當把js腳本經過script標籤放在head中的時候,早期瀏覽器在遇到script的時候會阻止瀏覽器加載和渲染html。直到javascript腳本被下載並執行完,且這些javascript是依次下載和執行,不能並行。以下面這個圖所示:javascript
現代瀏覽器如IE8,Firefox 3.5,Safari 4,Chrome 容許同時並行下載js文件。可是不幸的是js下載仍然會阻塞其餘資源的下載,如圖片。仍是會阻止瀏覽器去加載和渲染html。解決辦法就是將js body的最底端。html
限制script標籤的數量,由於每次遇到script都要阻塞瀏覽器加載和渲染html。這個對於內聯和外聯js都是同樣的。可是對於外聯js,每一個http請求都須要和服務器創建一次鏈接,時間上的開銷也不小。因此下載一個100KB的js文件比下載4個25KB的js文件速度要快。因此能夠將js文件進行文件的合併減小http請求的數量提升性能。java
非阻塞腳本在html加載完成後進行javascript源碼的下載。有幾種方法能夠作到:web
3.1 在script上添加defer屬性。defer屬性告訴瀏覽器該javascript代碼不會影響dom樹。因此瀏覽器能夠放心的將他延遲執行,即等dom加載完成後執行。defer屬性的script能夠防止瀏覽器的任何一個地方,當瀏覽器遇到這個script時候,開始下載可是並不當即執行,等到dom樹加載完成在onload事件觸發以前執行,且不會影響到其餘資源的下載。chrome
<html> <head> <title>Script Defer Example</title> </head> <body> <script defer> alert("defer"); </script> <script> alert("script"); </script> <script> window.onload = function(){ alert("load"); }; </script> </body> </html>
執行結果:
在不支持defer屬性的瀏覽器中結果爲:defer script load 在支持defer屬性的瀏覽器中的結果是script defer load編程
3.2 動態執行將javascript代碼插入文檔中。segmentfault
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 { //Others script.onload = function(){ callback(); }; } script.src = url; document.getElementsByTagName_r("head")[0].appendChild(script); }
3.3 經過XHR 從服務端獲取js 動態插入到文檔中。數組
每一個函數都會有個做用域鏈,用於標識符的查找也就是變量的查找。因此若是變量在原型鏈越後面的地方訪問所須要的時間就越長。因此全局對象的返回所須要的時間是最長的,應該用局部變量存起來減小做用域鏈的查詢次數。瀏覽器
with語句和try-catch 會改變執行函數的做用域鏈。會在做用域鏈前加上with或者catch本身的活躍對象AO。這就致使原本能夠本身訪問的局部變量須要在做用域鏈的後面一層被訪問到了。增長了變量訪問的時間。因此避免使用with語句。而try-catch仍是頗有用的。不該該避免,能夠經過在catch到錯誤後用一個錯誤處理函數來解決這種性能問題。服務器
在javascript中存儲數據的地方有四個。分別是直接量,變量,數組,對象。其中直訪問接量和變量是最快的,二者差異不大。可是對於數組和對象相對來講要慢些,特別是對象。由於訪問對象中的一些屬性和方法涉及到原型鏈的查找,這個和做用域鏈是一個道理。因此須要存儲這些須要遍歷原型鏈的方法或者屬性提供性能。
瀏覽器通常分爲渲染引擎和js引擎,如chrome 它的渲染引擎就是webkit 它的js引擎是v8。
訪問和修改dom是須要付出性能代價的。由於修改一個dom元素可能回去觸發瀏覽器去從新計算它的幾何屬性,從新排版。因此儘量少的去和dom元素打交道。
選用更快的DOM API 好比用nextSibling 代替childNodes 或者用children代替childNodes。