javaScript 在瀏覽器中的運行性能,在web2.0時代顯得尤其重要,成千上萬行javaScript代碼無疑會成爲性能殺手,javascript
在較低版本的瀏覽器執行JavaScript代碼的時候,因爲瀏覽器只使用單一進程來處理ui界面刷新和JavaScript腳本執行,css
這意味着在加載javascript文件的時候不能同時作任何其餘的事情。 在加載的同時形成了用戶交互阻塞;html
理論上來講,把樣式與行爲有關的腳本放在一塊兒率先加載,這樣有利於確保正確的用戶體驗,例以下面的代碼:html5
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>javascript</title> <script src="file.js" type="text/javascript" charset="utf-8"></script> <script src="file1.js" type="text/javascript" charset="utf-8"></script> <link rel="stylesheet" type="text/css" href="file.css"/> <link rel="stylesheet" type="text/css" href="file1.css"/> <link rel="stylesheet" type="text/css" href="file2.css"/> </head> <body> </body> </html>
這種看似合理的代碼其實有着很嚴重的性能問題:在javascript文件加載並執行完成以前會阻止頁面進行渲染,咱們的web頁面會出現一片空白java
沒法與之正常交互,這稱之爲腳本阻塞web
因爲腳本會阻塞頁面其餘資源的加載 咱們能夠把全部的script標籤放在</body>以前 在頁面加載的最後來加載javascript文件ajax
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>javascript</title> <link rel="stylesheet" type="text/css" href="file.css"/> <link rel="stylesheet" type="text/css" href="file1.css"/> <link rel="stylesheet" type="text/css" href="file2.css"/> </head> <body> <!--推薦全部的js文件位置--> <script src="file.js" type="text/javascript" charset="utf-8"></script> <script src="file1.js" type="text/javascript" charset="utf-8"></script> </body> </html>
-----------優化javascript的首要任務,將js文件放置在頁面底部;chrome
那如何建立一個無阻塞的腳本呢?瀏覽器
無阻塞腳本的祕訣在於,在頁面加載完成以後纔開始加載javascript代碼。 咱們要在window對象的load時間觸發後再下載並執行腳本,app
已知有不少種方式能夠實現這一效果,這裏簡單例舉一二:
1.HTML5新特性
html5爲script標籤提供了兩個新的屬性 一個是defer 另外一個是async 它們採用的都是並行下載的方式; 在下載過程當中並不會形成頁面阻塞
它們的區別在於 defer表示等待頁面加載完成纔會執行,async則是它自己加載完成後就自動執行;
defer目前已被各大主流瀏覽器所兼容;
2.建立動態腳本元素;這很容易使頁面渲染完成以後再進行腳本加載;
例如:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>javascript</title> </head> <body> <script type="text/javascript"> var script = document.createElement("script"); script.src = "ztf.js"; document.getElementsByTagName("head")[0].appendChild(script); </script> </body> </html>
咱們使用標準的dom方法document.createElement來動態的建立一個script元素並指定它的src;這行成了一個動態的腳本模式;在任意時刻插入任意的javascript代碼都會被瀏覽器執行;(建立的script最好不要插入到body裏面;這樣可能會引發ie拋出一個‘操做已終止’的錯誤信息;)
ff,opera,chrome和safari3以上版本的script標籤會在加載完成觸發onload事件。
而在老版本ie下(ie6-10) 它會觸發一個readystatechange事件。<script>元素會提供一個readyState屬性,它的值在scr加載不一樣過程產生不一樣的變化;咱們一般會使用到 "loaded" 和 "complete"。
經過「客戶端能力檢測」 (http://www.jxbh.cn/newshow.asp?id=1434&tag=2) 咱們能夠建立一個通用的動態加載javascript的函數:
function loadScript(url,callback){ var script = document.createElement("script"); script.type="text/javascript"; if(script.readyState){ //客戶端能力檢測 若是支持readyState則返回的是字符串 反之返回undefined script.onreadystatechange = function(){ //onreadystatechange事件 if(script.readyState=="loaden"||script.readyState=="complete"){ script.onreadystatechange=null; callback(); } } }else{ script.onload = function(){ callback(); } } script.src = url; document.getElementsByTagName("head")[0].appendChild(script); }
這個函數接受兩個參數;javascript文件的url和完成加載後的回調函數。loadScript()函數的用法以下
loadScript("ztf.js",function(){ alert("loadend") });
若是須要的話,你能夠儘量多的加載javascript文件到頁面上,但必定要考慮清楚文件的加載順序,能夠不斷的使用callback回調函數加載多個javascript腳本;
另外還有一種,ajax動態請求加載腳本 在這裏筆者就不一 一說明 ,你們查閱有關文檔;
部份內容摘自《高性能javascript》