web性能優化--高性能javascript

總結了一下《高性能javascript》書中比較核心的點,並補充了一些點。javascript

第一章 DOM標籤

  • 將全部 標籤放置在頁面的底部,緊靠 body 關閉標籤的上方。此法能夠保證頁面在腳本 運行以前完成解析。css

  • 將腳本成組打包。頁面的 標籤越少,頁面的加載速度就越快,響應也更加迅速。不論外部腳本 文件仍是內聯代碼都是如此。java

  • LazyLoad 還能夠下載多個 JavaScript 文件,並保證它們在全部瀏覽器上都可以按照正確的順序執行。ajax

  • 瞭解性能監控的API
    包括window.performance以及W3C Resourcing Timing正則表達式

第二章 Data Access 數據訪問

  • 做用域也關係到性能,可是要理 解速度與做用域的關係。算法

  • 全局變量老是 處於運行期上下文做用域鏈的最後一個位置,因此老是最遠才能觸及的,最慢。編程

  • 用局部變量存儲本地範圍以外的變量值,若是它們在函數中的使用多於一次。json

(function(d,$) {
        d.getElementById('test');
        ...
       $('.test').hide();
        ....
    }(document, jQuery))

做用域:數組

clipboard.png

深刻原形鏈越深,搜索的速度就會越慢。
屬性嵌套越深,訪問速度越慢。
將它的值存入一個局部變量,消除一次搜索過程。瀏覽器

  • 函數的節流與防反跳

參閱underscore庫的throttle函數(節流)與debounce函數(防反跳)。其中,throttle的含義是:每XX秒內只執行一次;debounce的含義是:當連續觸發函數調用時,在最後一次觸發的XX秒之後纔開始一次調用。
如何實現這一機制請看淺談 Underscore.js 中 _.throttle 和 _.debounce 的差別

第三章 DOM Scripting DOM 編程

  • 減小DOM 操做問題的量化

  • 將數組的 length 屬性緩存到一個變量中

  • 瀏覽器須要從新計算元素的幾何屬性,並且其餘元素的幾何屬性和位置也會所以改變 受到影響。 元素位置改變,尺寸, 內容, 瀏覽器窗口改變尺寸

  • 在反覆訪問的地方使用局部變量存放 DOM 引用.

  • 將全部改變合併在一塊兒執行,只修改 DOM 一次。可經過使用 cssText 屬性實現。

  • 從文檔流中摘除該元素; 隱藏元素,進行修改,而後再顯示它。 對其應用多重改變; 將元素帶回文檔中;

Example:
1.頁面頂部能夠「摺疊/展開」的元素稱做「動畫元素」,用絕對座標對它進行定位,當它的尺寸改變時,就 不會推移頁面中其餘元素的位置,而只是覆蓋其餘元素。
二、展開動做只在「動畫元素」上進行。這時其餘元素的座標並無改變,換句話說,其餘元素並無由於「動 畫元素」的擴大而隨之下移,而是任由動畫元素覆蓋。
三、「動畫元素」的動畫結束時,將其餘元素的位置下移到動畫元素下方,界面「跳」了一下。

  • 一個簡單而優雅的處理 DOM 事件的技術是事件託管。它基於這樣一個事實:事件逐層冒泡總能被父元
    素捕獲。採用事件託管技術以後,你只須要在一個包裝元素上掛接一個句柄,用於處理子元素髮生的全部 事件。

第四章 Algorithms and Flow Control 算法和流 程控制

  • 只有一種循環比其餘 循環明顯要慢:for-in 循環 最慢。 要搜索實例或原形。

  • 減小每次迭代中操做的總數能夠大幅度提升循環總體性能。 地將此值存入一 個局部變量中。 倒序循環。

使用遞減循環

for (var i=items.length; i--; ){ 
    process(items[i]);
 }

var values = [0,1,2,3,4];
var len = values.length;
for (var i = 0; i--) {
     循環...
}

超過1000次的循環,使用Duff's Device

var i = items.length % 8;
while(i) {
    process(items[i--]);
}

i = Math.floor(items.length / 8);

while(i) {
     process(items[i--]);
     process(items[i--]);
     process(items[i--]);
     process(items[i--]);
     process(items[i--]);
     process(items[i--]);
     process(items[i--]);
     process(items[i--]);
}

Conditionals 條件表達式

  • 若是條件較少時,if-else 容易閱讀,而條件較多時 switch 更容易閱讀。

  • 當你使用了太多的遞歸,超過最大調用棧尺寸時,瀏覽器會出錯並彈出error信息。

  • 任何能夠用遞歸實現的算法均可以用迭代實現。for循環代替遞歸( 運行的代碼總量越大,使用這些策略所帶來的性能提高就越明顯。)

第五章 Strings and Regular Expressions 字符串 和正則表達式

str += "two";
str = str + "one" + "two";
newStr = strs.join("");
  • 儘可能避免一個正則表達式作太多的工做

第六章 Responsive Interfaces 響應接口

  • 若是一個函數運行時間太長,那麼查看它是否能夠分解成一 系列可以短期完成的較小的函數。

  • 可經過原生的 Date 對象跟蹤代碼的運行時間。

  • 當多個重複的定時器被同時建立會產生性能問題。

  • 網頁工人線程

第七章 Ajax 異步 JavaScript 和 XML

  • 總的來講越輕量級的格式越好,最好是 JSON jsonp相對慢一點

  • 設置http頭設置緩存 expires etag if-none-match if-modified-since

第八章 Programming Practices 編程實踐

  1. Lazy Loading 延遲加載 按需加載(事件監聽 函數 js文件 css文件 )

  2. JavaScript 引擎提供的原生方法

  3. 原生的 querySelector()和 querySelectorAll()方法查詢dom

  4. 合併 JavaScript 文件

  5. 預處理 JavaScript 文件

  6. JavaScript 壓縮

  7. JavaScript 緊湊

  8. 開發過程當中的編譯(預處理)

  9. 緩存 的應用 JavaScript 文件

  10. cdn

  11. 性能分析工具

  12. 只直出首屏頁面可視內容,其餘在客戶端上延遲處理
    13.DNS prefeching

目前三種渲染頁面的方式:
1.ajax拉取數據
2.後臺直出數據和模版,js模版引擎去渲染(下降白屏)
3.後臺直出拼好的頁面 (下降白屏)

HTTP2.0性能加強的核心:二進制分幀

  • HTTP2.0 首部壓縮

clipboard.png

HTTP 2.0 在客戶端和服務器端使用「首部表」來跟蹤和存儲以前發送的鍵-值對,全部的HTTP2.0的請求都在一個TCP連接上.HTTP2.0全部通訊都是在一個TCP鏈接上完成。HTTP 2.0 把 HTTP 協議通訊的基本單位縮小爲一個一個的幀,這些幀對應 着邏輯流中的消息。並行地在同一個 TCP 鏈接上雙向交換消息。就比如,我請求一個頁面http://www.qq.com。頁面上全部的資源請求都是客戶端與服務器上的一條TCP上請求和響應的!

  • HTTP2.0的請求優先級

  • HTTP2.0的服務器推送
    除了對最初請求的響應外,服務器還能夠額外向客戶端推送資源,而無需客戶端明確地請求。

有了HTTP2.0的服務器推送,HTTP1.x時代的內嵌資源的優化手段也變得沒有意義了。