天天看點

《高性能javascript》學習筆記一

補充:因《高性能javascript》一書成書較早,書中介紹的許多知識已過期或者有新的标準,我盡量結合自己的了解以及書中的觀點進行總結和闡述。如有錯誤之處還請指出。

一、腳本的加載和執行

1、為什麼腳本會阻塞頁面

大多數浏覽器是單線程(js線程和ui線程共享同一個線程),是以,在執行js代碼時,ui層無法做出響應。是以,在下載下傳或者執行js過程中,頁面渲染和互動是阻塞的。

2、防止頁面阻塞的方法

(1)将script标簽置于頁面底部。因為js引擎是從上往下解析,先讀取css和html,頁面出來之後,再讀取js檔案并執行,就不會造成頁面的阻塞。(其實也會,不過下載下傳./執行js代碼時使用者能看到頁面,隻要js下載下傳執行不需要很久,使用者察覺不到。)

(2)合并js檔案。同樣大小的js,合并成一個會比分成多個更節約性能。因為每次請求都會額外消耗性能,如果隻有一次請求,無疑是最好的。

(3)async和defer屬性。給script标簽添加async或者defer屬性,浏覽器将會異步加載這個script标簽的資源(即目前浏覽器線程閑置時下載下傳執行)。如果有多個script标簽有async屬性,則先下載下傳完的先執行。多個defer屬性的script标簽,則按照頁面上的順序從上往下執行。

兩者差別:async屬性是下載下傳完對應js檔案立即執行。defer屬性是下載下傳完之後,等到頁面的load事件之前執行該js檔案。

(4)動态引入js檔案。可以在js代碼中建立script标簽,設定src屬性放在頁面上。動态script标簽在放在頁面上時會立刻異步執行,下載下傳完js檔案後會自動執行。(異步執行的原因,其實是因為在将script标簽放入頁面上時,對應的請求任務才會加入到事件隊列,是以要等到之前的事件處理完才會下載下傳并執行這個js檔案。)

《高性能javascript》學習筆記一
《高性能javascript》學習筆記一

結果是:

《高性能javascript》學習筆記一

在執行完setTimeout之後,然後會立即将console.log(2222)這個事件放入事件隊列。。然後下載下傳外部的9-25.js檔案,然後輸出2222,然後輸出外部檔案的1111.

如果延遲回調的時間設定為100(比下載下傳9-25.js時間小就行),那麼結果是

《高性能javascript》學習筆記一
《高性能javascript》學習筆記一

setTimeout的時間,是将對應的時間放入事件隊列的時間,而不是具體執行的時間。是以在下載下傳9-25.js檔案完成後,如果時間還沒到,那麼會先執行外部的js檔案(因為這時會把外部的js檔案執行放入事件隊列),然後執行回調函數的代碼。

推薦方式:動态注入或者async