《高效能JavaScript》讀書筆記①載入和執行
JavaScript的載入和執行(Loading and Execution)
JavaScript的阻塞特性
當瀏覽器遇到JavaScript程式碼段時(不管是內嵌還是外鏈),由於不確定其是否會進行DOM操作,所以都會等待指令碼的解析和執行完成後,再往下執行。此時頁面渲染和使用者互動都是被阻塞的,這就是 JavaScript的阻塞特性 。
JavaScript阻塞特性的思考
雅虎效能小組對JS程式碼最佳化的首要規則就是,透過改變
指令碼的位置來減少對頁面載入的影響。也就是說將
元素放到
標籤底部,這樣頁面的CSS和圖片等資原始檔載入時,就不需要等待JS程式碼的解析和執行了。
除此之外,減少
標籤的數量也能改善阻塞的情況
我們可以合併
程式碼段,因為瀏覽器在解析HTML頁面時,每遇到一個
標籤,都會因為執行指令碼而導致一定的延時。
我們還需要儘可能的合併外鏈的JavaScript檔案。測試發現,下載一個100KB的JS檔案比下載四個25KB的JS檔案要快,是因為每次HTTP請求相當於重新進行一次Socket連線,會產生效能損耗。
實現Noblocking Scripts(無阻塞的指令碼)的幾種方式
-
Deferred Scripts (指令碼延遲)
針對JavaScript的阻塞特性,很多人首先想到的辦法可能是:能不能先下載JS檔案,等頁面載入完成後,再去解析和執行引入的JavaScript程式碼呢?
針對此種設想,HTML4標準為標籤提供了
defer
屬性。意味著可以先下載JS檔案(同時允許並行下載),等到DOM載入完成(即事件被觸發前),才會執行其中的程式碼段。注意:該屬性只對宣告瞭
src
屬性的標籤生效,另外HTML5規範中引入了async屬性,和defer屬性一樣,也是用於非同步載入指令碼的
-
Dynamic Script Elements (動態指令碼元素)
我們知道DOM(文件物件模型)機制使得我們可以動態的建立、編輯、移動和刪除HTML元素,這裡面當然也包含元素。也就是說,其實我們是可以透過JavaScript程式碼來動態構建
標籤的。
//建立script元素var script = document.creatElement("script"); //指定元素的type屬性script.type = "text/javascript"; //指定URLscript.src = "file1.js"; //將新的script標籤加入到文件頭部document.getElementByTagName("head")[0].appendChild(script);
注意,當新的
元素被加入到
時,會立即開始下載
file1.js
檔案,並執行其中的JS指令碼。這種方式的優勢就在於,能夠把指令碼放在頁面
區域,避免影頁面其他部分的載入。
如果需要監聽指令碼的下載狀態,可以透過()方法監聽指令碼載入完成的狀態:var script = document.creatElement("script"); script.type = "text/javascript";//js下載完畢後的監聽(IE中不可用)script. = function(){ alert("script loaded!"); }; script.src = "file1.js";document.getElementByTagName("head")[0].appendChild(script);
但是()方法僅在Firefox、Chrome、Opera和Safari3+ 瀏覽器中支援,如果想在IE瀏覽器要監聽js指令碼的下載狀態,則可以透過監聽
元素的readyState狀態屬性來實現。
readyState有五種取值,但是微軟的相關文件表明,在整個元素生命週期中,並非readyState的每個值都會用到。最終表明
元素載入完畢的是"loaded"和"complete"兩個狀態,所以我們要檢查這兩個狀態。
var script = document.creatElement("script"); script.type = "text/javascript";//js下載完畢後的監聽(IE)script.onreadystatechange = function(){ if(script.readyState == "loaded" || script.readyState == "complete"){ alert("script loaded!"); } }
由此可見透過
動態指令碼元素
的方式解決JavaScript的阻塞問題時,如果需監聽下載狀態,還需要針對不同瀏覽器做封裝處理。//定義公共的js載入方法(有沒有覺得這種callback的方式和$.Ajax很類似?)function loadScript(url,callback){ var script = document.creatElement("script"); script.type = "text/javascript"; //判斷如果能獲取readyState屬性,則表明是IE瀏覽器 if(script.readyState){ script.onreadystatechange = function(){ if(script.readyState == "loaded" || script.readyState == "complete"){ script.onreadysatechange = null; callback(); } } //其他瀏覽器 }else{ script. = function(){ callback(); } } script.src = url; document.getElementByTagName("head")[0].appendChild(script); }//呼叫loadScript("file1.js",function(){ alert("script loaded!"); });
-
XMLHttpRequest Script Injection (XMLHttpRequest指令碼注入)
另一種無阻賽載入指令碼的方式,是使用XMLHttpRequest(XHR)物件載入JS指令碼
由於XMLHttpRequest指令碼注入的方式,由JS指令碼的載入以及元素的建立兩部分組成,我們就可更加靈活的控制JavaScript指令碼,比如先載入,等到需要時候再執行。
//建立XMLHttpRequest物件
var xhr = new XMLHttpRequest();
//透過GET請求載入file1.js
xhr.open("get","file1.js",true);
//透過XHR物件的onreadystatechange()方法監聽readState屬性的變化
xhr.onreadystatechange = function(){
//readyState屬性表示XHR物件請求的就緒狀態:0-請求未初始化;1-請求已建立;2-請求已傳送;3-請求處理中;4-響應已完成
if(xhr.readyState == 4){
//status屬性表示HTTP請求的狀態碼:200-(OK)請求成功;304-(Not Modified)從快取中讀取;狀態碼小於300都表示請求成功
if(xhr.status >= 200 && (xhr.status //建立script元素
var script = document.creatElement("script");
//指定元素的type屬性
script.type = "text/javascript";
//將response響應內容填充到script元素中
script.text = xhr.responseText;
//當把script元素新增到body時,js程式碼會被立即執行
document.body.appendChild(script);
}
}
}
```
作者:梁同學de自言自語
連結:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/755/viewspace-2813618/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 《高效能JavaScript》讀書筆記JavaScript筆記
- 類載入讀書筆記筆記
- 高效能JavaScript 重排與重繪 讀書筆記JavaScript筆記
- 【前端效能優化】高效能JavaScript讀書筆記前端優化JavaScript筆記
- 《高效能javascript》讀書筆記-第二章 資料存取JavaScript筆記
- 【讀書筆記】Postgresql連線方法及執行器筆記SQL
- 《JavaScript 物件導向精要》 讀書筆記JavaScript物件筆記
- 執行緒間協作-《thinking in java》讀書筆記(一)執行緒ThinkingJava筆記
- 《JavaScript程式設計精解》--讀書筆記JavaScript程式設計筆記
- Javascript的裝載和執行JavaScript
- 讀書筆記筆記
- 《你不知道的JavaScript》 (下) 讀書筆記JavaScript筆記
- 《你不知道的JavaScript》 (上) 讀書筆記JavaScript筆記
- 《你不知道的JavaScript》 (中) 讀書筆記JavaScript筆記
- 讀書筆記 – 你不知道的 JavaScript(上)筆記JavaScript
- 《讀書與做人》讀書筆記筆記
- 《CLR Via C#》讀書筆記:26.執行緒基礎C#筆記執行緒
- 《Kafka入門與實踐》讀書筆記Kafka筆記
- 《JavaScript Dom程式設計藝術》讀書筆記(一)JavaScript程式設計筆記
- 《你不知道的 JavaScript》全卷讀書筆記JavaScript筆記
- 《CLR Via C#》讀書筆記:24.執行時序列化C#筆記
- webpackDemo讀書筆記Web筆記
- Vue讀書筆記Vue筆記
- 散文讀書筆記筆記
- Cucumber讀書筆記筆記
- HTTP 讀書筆記HTTP筆記
- postgres 讀書筆記筆記
- 讀書筆記2筆記
- 讀書筆記3筆記
- 高效能javascript程式設計筆記JavaScript程式設計筆記
- JavaScript 紅寶書筆記JavaScript筆記
- javascript紅寶書筆記JavaScript筆記
- [讀書筆記] Ruby 中的 Block 和 Iterator筆記BloC
- 《JavaScript 模式》讀書筆記(6)— 程式碼複用模式3JavaScript模式筆記
- 《JavaScript 模式》讀書筆記(6)— 程式碼複用模式2JavaScript模式筆記
- js高程讀書筆記JS筆記
- 《論語》讀書筆記筆記
- 《重構》讀書筆記筆記