简体   繁体   中英

Moving Ajax toolkit scripts to the bottom of the page

I'm currently working on improving one of our sites PageSpeed insights score, at the moment we're hovering around 90 , we'd like to break into the mid 90's if possible.

One of the sticking points we have is that the Ajax toolkit script manager is generating its script at the top of the page, google flags this as a " should fix " issue and is complaining that the script is render blocking and should be moved to the bottom of the page or loaded asychronously or via the defer attribute.

I'm using the following to combine our scripts into one .js file to minimize requests:

<ajaxToolkit:ToolkitScriptManager ID="manScript" LoadScriptsBeforeUI="false" runat="server" EnableViewState="false" ScriptMode="Release">

    <CompositeScript ScriptMode="Release" Path="/CMSGlobalFiles/Js/combinedajax.min.js">
        <Scripts>
            <asp:ScriptReference Name="WebForms.js" Path="/CMSGlobalFiles/Js/aspnet/WebForms.js" Assembly="System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
            <asp:ScriptReference Name="MicrosoftAjax.js" Path="/CMSGlobalFiles/Js/aspnet/MicrosoftAjax.js"  />
            <asp:ScriptReference Name="MicrosoftAjaxWebForms.js" Path="/CMSGlobalFiles/Js/aspnet/MicrosoftAjaxWebForms.js" />
        </Scripts>
    </CompositeScript>

</ajaxToolkit:ToolkitScriptManager>

Is there a way to set either defer or async on the CompositeScript tag that gets output? Or any other way of moving this to the bottom of the page?

I've tried the following:

protected override void Render(HtmlTextWriter writer)
{
    StringWriter output = new StringWriter();
    base.Render(new HtmlTextWriter(output));

    string outputAsString = output.ToString();

    if(outputAsString.Contains("<script src=\"/CMSGlobalFiles/Js/combinedajax.min.js\" type=\"text/javascript\"></script>"))
    {
        outputAsString = outputAsString.Replace("<script src=\"/CMSGlobalFiles/Js/combinedajax.min.js\" type=\"text/javascript\"></script>", string.Empty);
    }

    writer.Write(outputAsString);
}

And then manually including a reference to the script at the bottom of the page:

<script type="text/javascript">
    function downloadJSAtOnload() {
        createScript("/CMSGlobalFiles/Js/combinedajax.min.js?v=1");
        createScript("//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js");
        createScript("/cmsglobalfiles/js/vendor/modernizr.js");
        createScript("/cmsglobalfiles/js/main.min.js");
        createScript("/cmsglobalfiles/js/vendor/wow.min.js");
    }

    function createScript(path) {
        var element = document.createElement("script");
        element.src = path;
        document.body.appendChild(element);
    }

    if (window.addEventListener)
        window.addEventListener("load", downloadJSAtOnload, false);
    else if (window.attachEvent)
        window.attachEvent("onload", downloadJSAtOnload);
    else window.onload = downloadJSAtOnload;
</script>

This removes the generated composite script and creates a new one before the closing body tag, this brings our score up to 95 but I think this is loaded too late as we're getting a lot of console errors:

ReferenceError: Sys is not defined

WebForm_InitCallback is not defined

Which indicates the script manager is broken, is there a way to achieve this at all?

我使用ajax控件工具包版本15.1.4.0 ,你使用ScriptManager而不是ToolkitScriptManager但你可以设置LoadScriptsBeforeUI="False"并在</form>之前渲染。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM