第二次打開頁面時:
從上例中可以明顯看出,像chrome之類的高版本游覽器會對js文件進行緩存,作用是不言而喻,減少網絡請求。
其次,第二個問題,當一個javascript文件被加載時是否會阻塞其他javascript文件或者其他文件的加載。《高性能Javascript》一書中對這個問題做了較好的解答:各種游覽器的低版本的處理是當一個javascript文件在加載時,會同時阻塞頁面其他文件的加載(包括其他javascript文件),但IE8,Firfox3.5,Safari 4和Chrome 2都允許並行下載javascript文件,但遺憾的是,javascript下載過程仍然會組捨其他資源的下載,比如圖片。盡管javascript腳本的下載過程不會相互影響,但頁面仍然必須等待所有的javascript代碼下載並執行完成才能繼續。
這裡說句題外話:游覽器對同一域名下的並發鏈接數也是有限制的,其他一些參數如下:
二、技巧
1. 腳本位置
由於腳本會阻塞頁面其他資源的下載,因此推薦將所有的<script>標簽放到<body>標簽的底部,已盡量減少對整個頁面下載的影響。
2. 將能合並的js文件合並
3. 無阻塞腳本
現在比較常用的方法就是動態加載執行腳本。你的原理是通過DOM,你幾乎可以用Javascript動態創建HTML中的所有內容,其根本在於,<script>標簽與頁面中其他元素並無差異:都能通過DOM引用,都能在文檔中移動,刪除和創建。文件在改該<script>元素被添加到頁面時開始現在,它不會阻止其他文件下載,只在執行階段阻塞渲染。特別強調:《高性能javascript》一文中說“這種技術的重點在於:無論何時啟動下載,文件的下載和執行都不會阻塞頁面其他進程”,這並不是說它在執行不會阻塞其他javascript代碼,而是要強調不會阻塞其他資源的下載等其他任務。
具體的代碼如下:
復制代碼 代碼如下:
function loadScript(url){
var ga = document.createElement('script');
ga.type = 'text/javascript';
ga.async = true;
ga.src = url;
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(ga);
}
4. 神奇的setTimeout()
這裡我不過多的將setTimeout()的原理,有興趣的讀者可以具體去看《高性能javascript》的第六章。我重點強調下,setTimeout的第二個參數並不是一個精確的時間,二是必須在javascript線程空閒時才能運行。利用這個特性,如下代碼簡單可以實現等待其他js代碼執行完畢後再執行function裡面的代碼。
復制代碼 代碼如下:
setTimeout(function(){
// do some before other javascripe codes had processed
}, 25)
但在function裡面不要使用document.write()方法,因為執行setTimeout裡面函數時往往已經到了頁面onload之後,此時再執行 document.write 將導致當前頁面的內容被清空,因為它會自動觸發 document.open 方法。
《高性能Javascript》
HOW BROWSERS WORK: BEHIND THE SCENES OF MODERN WEB BROWSERS
Google Chrome源碼剖析【一】:多線程模型
javascript異步加載詳解