簡體   English   中英

推遲在asp.net MVC中加載javascript

[英]Defering the loading of javascript in asp.net MVC

我正在尋找優化在MVC項目中加載較大的javascript文件的方式。 我已經在使用捆綁和縮小功能,但是我真的只想在HTML和CSS加載后再加載其中的一些。 我正在研究這種方法:

https://varvy.com/pagespeed/defer-loading-javascript.html

通過這種方法,在加載正文之后,在load / onload事件中使用javascript將腳本標簽注入。 我的問題是,我想同時使用框架提供的捆綁和縮小功能,但我還沒有找到一種好的方法。

我只是想知道是否有人在MVC項目中成功使用了這種方法,以及是否可能已經有一個庫(在Nuget上或其他方式上)來簡化此過程。

編輯:這是我目前的解決方案,但我不確定我是否喜歡它。

由於捆綁框架可以根據您是否在調試中運行而返回單個腳本標簽或它們的列表,因此我們需要提取這些標簽的源值。 為此,我創建了一個靜態助手。

public static string ExtactFromScriptBundle(string aBundle)
    {
        List<string> returnValue = new List<string>();

        var jQueryString = Scripts.Render(aBundle).ToHtmlString();

        var reg = new Regex("\".*?\"");

        var matches = reg.Matches(jQueryString);
        foreach (var match in matches)
        {
            returnValue.Add(match.ToString().Replace("\"", ""));
        }

        return Json.Encode(returnValue);
    }

比起_layout.cshtml,您可以在標記之前插入一個類似於以下內容的代碼塊:

<script>
    function downloadJSAtOnload() {
     createScripElementsFromArray(@Html.Raw(ScriptHelper.ExtactFromScriptBundle("~/bundles/jquery")));
createScripElementsFromArray(@Html.Raw(ScriptHelper.ExtactFromScriptBundle("~/bundles/bootstrap")));
    }

    function createScripElementsFromArray(fileNameList) {
        var arrayLength = fileNameList.length;
        for (var i = 0; i < arrayLength; i++) {
            createScripElement(fileNameList[i]);
        }
    }

    function createScripElement(fileName) {
        var element = document.createElement("script");
        element.src = fileName;
        document.body.appendChild(element);
        console.log(fileName + " was loaded");
    }

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

在我看來,這是一個小技巧,因為我只是為了分析輸出而渲染捆綁包,但是我想我也可以緩存這些輸出以進一步優化頁面渲染。

通過Occam的Razor ,最好的解決方案是使用defer屬性...

<script src='myJavaScriptFile.js' defer></script>

它得到很好的支持

如果要在ASP.NET MVC中使用它,請執行以下操作:

創建一個新的Razor命令,如下所示:

public static class Scripts
{
    public static IHtmlString RenderDeferred(params string[] paths)
    {
        return Scripts.RenderFormat(@"<script src='{0}' defer></script>", paths);
    }
}

然后像這樣使用它:

@Scripts.RenderDeferred("~/myBundle/myJavaScriptBundle")

一種選擇是使用jquery加載外部腳本。 您最初會對jquery本身有依賴性,但是jquery的重量很輕。

然后,您將擁有:

$(document).ready(function(){

    //At this point, the HTML/CSS has already been loaded and rendered.

    //load external scripts
    $.getScript( "ajax/test.js", function( data, textStatus, jqxhr ) {
       console.log( data ); // Data returned
       console.log( textStatus ); // Success
       console.log( jqxhr.status ); // 200
       console.log( "Load was performed." );
    });

});

jQuery文檔: https : //api.jquery.com/jquery.getscript/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM