亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

加載和執(zhí)行JS的正確姿勢(shì)

zhichangterry / 2656人閱讀

摘要:在這些文件的下載執(zhí)行過(guò)程中,用戶看到的則是一片空白。頁(yè)面仍然必須等到所有代碼下載并執(zhí)行完畢才能繼續(xù)渲染。

前言

kyrieliuの《高性能JavaScript》讀書(shū)筆記。

script標(biāo)簽是一個(gè)很“霸道”的狠角色,它的每次出現(xiàn)都讓頁(yè)面等待腳本的解析和執(zhí)行。也就是說(shuō),不管當(dāng)前的javascript代碼是內(nèi)嵌還是包含在外鏈文件中,頁(yè)面的下載和渲染都必須停下來(lái)等待腳本執(zhí)行完成。
其實(shí),script標(biāo)簽的“霸道”是必須的,因?yàn)轫?yè)面的生存周期中,腳本的執(zhí)行可能會(huì)修改頁(yè)面的內(nèi)容。
總之,在解析和執(zhí)行js的這個(gè)過(guò)程中,頁(yè)面渲染和用戶交互完全被阻塞了。

腳本位置

說(shuō)起腳本的位置,腦海里不禁想起來(lái)那兩句真言:

css放在

js放在

至于why呢,舉個(gè)栗砸:


    
        一個(gè)栗子
        
        
        
        
    
    
    
        

hello from kyrieliu.

這一段看似正常的代碼實(shí)際上有著肥腸嚴(yán)重的性能問(wèn)題:在head中加載了三個(gè)js文件。
前面我有說(shuō)到,js文件會(huì)阻塞頁(yè)面渲染,知道它們?nèi)肯螺d并執(zhí)行完畢后,頁(yè)面渲染才能繼續(xù)(無(wú)情無(wú)恥無(wú)理取鬧)。
縱觀一份html文檔,用戶真正看得見(jiàn)的內(nèi)容基本上都寫(xiě)在body標(biāo)簽里,也就是說(shuō),瀏覽器在解析到body標(biāo)簽之前,不會(huì)渲染頁(yè)面的任何部分。現(xiàn)在又寫(xiě)了三個(gè)腳本到head標(biāo)簽里面,好嘞,這下子渲染的延遲更明顯了,用戶在打開(kāi)這樣的一個(gè)頁(yè)面時(shí),看到了what?白屏!用戶不能瀏覽頁(yè)面的內(nèi)容,更無(wú)法與頁(yè)面進(jìn)行交互。

場(chǎng)景還原

第一個(gè)js文件開(kāi)始下載,與此同時(shí)阻塞了頁(yè)面其他文件的下載。等呀等,ok,第一個(gè)js文件終于下載完了,第二個(gè)js按捺不住自己喜悅的心情,正要開(kāi)始下載,突然,第一個(gè)js文件說(shuō):“且慢,老子還沒(méi)有完事呢”,第二個(gè)js文件嚇了一跳,站在原地不動(dòng)。第一個(gè)js文件開(kāi)始執(zhí)行,等到執(zhí)行完畢,第二個(gè)js文件才得以開(kāi)始下載。
總之,每個(gè)文件必須等到前一個(gè)文件下載并執(zhí)行完成才會(huì)開(kāi)始下載
在這些文件"one by one"的下載執(zhí)行過(guò)程中,用戶看到的則是一片空白。

不是那么好的好消息

IE8/Firefox3.5/Safari 4/Chrome 2都允許并行下載js文件,也就是說(shuō),script標(biāo)簽在下載外部資源時(shí),不會(huì)阻塞其他的script標(biāo)簽。
遺憾的是:

js文件的下載過(guò)程仍然會(huì)阻塞其他資源的下載,比如圖片。

頁(yè)面仍然必須等到所有js代碼下載并執(zhí)行完畢才能繼續(xù)渲染。

因此,盡管瀏覽器通過(guò)允許并行下載提高了性能,但腳本阻塞仍然是一個(gè)問(wèn)題。
綜上,推薦將所有的script標(biāo)簽盡可能的放在body標(biāo)簽的底部,以盡量減少對(duì)整個(gè)頁(yè)面渲染的影響。

組織腳本

既然每個(gè)script標(biāo)簽初始下載時(shí)都會(huì)阻塞頁(yè)面渲染,那么我們可以通過(guò)減少頁(yè)面上script標(biāo)簽的數(shù)量來(lái)改善這一情況。不光是外鏈的腳本,內(nèi)嵌腳本的數(shù)量同樣也要限制(畢竟執(zhí)行js代碼也會(huì)阻塞頁(yè)面的渲染)。
多于外鏈的腳本,這里的情況有一點(diǎn)需要額外注意的地方:考慮HTTP請(qǐng)求會(huì)帶來(lái)額外的性能開(kāi)銷,所以下載單個(gè)100kb的文件要比下載四個(gè)25kb的文件更快。從這個(gè)角度出發(fā),更能說(shuō)明減少外鏈腳本文件的數(shù)量將會(huì)改善性能。
What u should do?合并腳本!

無(wú)阻塞的腳本

隨著web應(yīng)用的功能越豐富,所需要的js代碼就越多,所以精簡(jiǎn)源代碼也并不總是可行。盡管下載單個(gè)較大的js文件只產(chǎn)生一次HTTP請(qǐng)求,但這樣做卻會(huì)鎖死瀏覽器一大段時(shí)間。
為了避免這種情況,需要向頁(yè)面中逐步加載js文件,這樣做,在某種程度上來(lái)說(shuō)不會(huì)阻塞瀏覽器。

延遲的腳本

HTML4為script標(biāo)簽定義了一個(gè)擴(kuò)展屬性:defer。Defer表明本元素所含的腳本不會(huì)修改DOM,因此代碼能安全的延遲執(zhí)行。
帶有defer屬性的script標(biāo)簽可以放在文檔的任何位置(不會(huì)阻塞瀏覽器的其他進(jìn)程,此類文件可以與頁(yè)面中的其他資源并行下載),對(duì)應(yīng)的js代碼將在頁(yè)面解析到script標(biāo)簽時(shí)開(kāi)始下載,但并不會(huì)執(zhí)行,(onload事件被出發(fā)前)才會(huì)執(zhí)行。
PS:截至這本書(shū)的第一版(2010年11月),這個(gè)屬性對(duì)IE和Firefox的支持性比較好(我的天居然有IE),如果真要投入到實(shí)際的項(xiàng)目中,不妨先去檢查一下瀏覽器的兼容性先~

動(dòng)態(tài)腳本元素
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "js_file.js";
document.getElementsByTagName("body")[0].appendChild(script);

Firefox/Opera/Chrome和Safari 3+會(huì)在script元素接收完成時(shí)出發(fā)一個(gè)load事件,所以你可以通過(guò)監(jiān)聽(tīng)這個(gè)事件來(lái)獲得腳本加載完成時(shí)的狀態(tài):

script.onload = function(){
    console.log("script loaded.");
}

一向特立獨(dú)行的IE自然有他的另一套:觸發(fā)一個(gè)readystatechange事件。script元素提供一個(gè)readyState屬性,有以下五種取值:

"uninitialized"

"loading"

"loaded"

"interactive" 數(shù)據(jù)完成下載但尚不可用

"complete"

所以,

script.onreadystatechange = function(){
    if (script.readyState == "loaded" || script.readyState == "complete"){
        script.onreadystatechange = null;
        console.log("script loaded.");
    }
}

至此,我們得到了一個(gè)可以應(yīng)用于廣泛瀏覽器的動(dòng)態(tài)加載腳本用的函數(shù):

function loadScript(url, callback){
    var script = document.createElement("script");
    script.type = "text/javascript";
    
    if (script.readyState){//IE
        script.onreadystatechange = function(){
            if (script.readyState == "loaded" || script.readyState == "complete"){
                script.onreadystatechange = null;
                callback();
            }
        }
    }else{
        script.onload = function(){
            callback();
        }
    }
}

可以這么用:

loadScript("file.js",function(){
    console.log("script loaded.");
});

也可以這么用:

loadScript("file_1.js",function(){
    loadScript("file_2.js",function(){
        loadScript("file_3.js",function(){
            console.log("all files are loaded.");
        });
    });
});
XMLHttpRequest腳本注入

標(biāo)題看起來(lái)很高大上的樣子,其實(shí)就是Ajax。

var xhr = new XMLHttpRequest();
xhr.open("get","file.js",true);
xhr.onreadystatechange = function(){
    if (xhr.readyState == 4){
        if (xhr.status >= 200 && xhr.status < 300 || xhr.status == 304){
            var script = document.createElement("script");
            script.type = "text/javascript";
            script.text = xhr.responseText;
            document.body.appendChild(script);
        }
    }
};
xhr.send(null);

局限:跨域問(wèn)題。

小結(jié)

body閉合標(biāo)簽之前,將所有的script標(biāo)簽放到頁(yè)面底部。這樣能確保在腳本執(zhí)行前頁(yè)面已經(jīng)完成了渲染。

合并腳本。頁(yè)面中的script標(biāo)簽越少,加載也就越快,響應(yīng)也更迅速。

無(wú)阻塞下載js:

script標(biāo)簽的defer屬性

動(dòng)態(tài)創(chuàng)建script元素來(lái)下載并執(zhí)行代碼

使用XHR對(duì)象下載js代碼并注入頁(yè)面中。

分享一個(gè)還算有趣的前端er:——微信公眾號(hào):劉凱里(kkkyrieliu)

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/81751.html

相關(guān)文章

  • 頁(yè)面我做主——瀏覽器去廣告正確姿勢(shì)

    摘要:簡(jiǎn)單高效的自定義方式對(duì)于這些情況我們可以使用一個(gè)強(qiáng)大的瀏覽器插件,簡(jiǎn)稱,中文俗稱為油猴,支持和瀏覽器。簡(jiǎn)單幾行代碼,就可以去除大部分頁(yè)面廣告。聲明需要使用的函數(shù)。 會(huì)CSS就會(huì)去廣告~ 傳統(tǒng)去廣告方法的弊端 我們?yōu)g覽網(wǎng)頁(yè)的時(shí)候經(jīng)常不免會(huì)看到各種不想看到的廣告內(nèi)容,最簡(jiǎn)單的方案就是通過(guò)瀏覽器插件來(lái)解決,比如大名鼎鼎的AdBlock插件以及國(guó)內(nèi)的各種廣告攔截助手。 但這些插件的攔截能力可...

    iamyoung001 評(píng)論0 收藏0
  • 頁(yè)面我做主——瀏覽器去廣告正確姿勢(shì)

    摘要:簡(jiǎn)單高效的自定義方式對(duì)于這些情況我們可以使用一個(gè)強(qiáng)大的瀏覽器插件,簡(jiǎn)稱,中文俗稱為油猴,支持和瀏覽器。簡(jiǎn)單幾行代碼,就可以去除大部分頁(yè)面廣告。聲明需要使用的函數(shù)。 會(huì)CSS就會(huì)去廣告~ 傳統(tǒng)去廣告方法的弊端 我們?yōu)g覽網(wǎng)頁(yè)的時(shí)候經(jīng)常不免會(huì)看到各種不想看到的廣告內(nèi)容,最簡(jiǎn)單的方案就是通過(guò)瀏覽器插件來(lái)解決,比如大名鼎鼎的AdBlock插件以及國(guó)內(nèi)的各種廣告攔截助手。 但這些插件的攔截能力可...

    20171112 評(píng)論0 收藏0
  • 有了 TensorFlow.js,瀏覽器中就能進(jìn)行實(shí)時(shí)人體姿勢(shì)判斷

    摘要:反饋檢測(cè)到的每個(gè)人的置信度值以及檢測(cè)到的每個(gè)姿勢(shì)關(guān)鍵點(diǎn)。姿勢(shì)置信度這決定了姿勢(shì)判斷的整體置信度。在較高級(jí)別,這將控制回饋的姿勢(shì)較低置信度分?jǐn)?shù)。只有在調(diào)整姿勢(shì)置信度得分不夠好的情況下,為了過(guò)濾掉不太準(zhǔn)確的姿勢(shì),該數(shù)值應(yīng)該增加或減少。 文 / Dan Oved,Google Creative Lab 的自由創(chuàng)意技術(shù)專家,紐約大學(xué) ITP 的研究生。編輯和插圖 / 創(chuàng)意技術(shù)專家 Irene Alv...

    KaltZK 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<