效能優化詳解

jasminecjc發表於2016-07-27

幾個月前面試的時候問我效能優化我可能會開始背誦雅虎軍規,加點webp,程式碼層面稍稍講點,現在系統的梳理下效能優化的方方面面

本文涉及方面有:

  1. 程式碼優化

  2. 網路請求過程角度入手

    • DNS解析

    • TCP建立連結

    • 網路往返時延(RTT)

    • 資料傳輸

  3. 網路問題角度入手

    • 請求數量

    • 流量

  4. 效能優化測試工具

程式碼優化

css程式碼優化

避免類正則的屬性選擇器

CSS3新增了複雜的屬性選擇器,可以通過類正規表示式的方式對元素的屬性值進行匹配。當然這些型別的選擇器定是會影響效能的,正規表示式匹配會比基於類別的匹配會慢很多。大部分情況下我們應儘量避免使用 *=, |=, ^=, $=, 和 ~=語法的屬性選擇器。

合寫CSS

除了壓縮的方式,我們還可以通過少寫CSS屬性來達到減少CSS位元組的目的

利用繼承CSS

css的繼承機制也可以幫我們再一定程度上縮減位元組數,我們知道CSS有很多屬性是可以繼承的即在父容器設定了默寫屬性,子容器會預設也使用這些屬性,因此如果我們希望全文字型尺寸是14px,大可不必為每個容器設定,只需要在body上設定就可以了。應用這個技巧,把CSS屬性在可能的情況下提到父容器是可以幫我們節省CSS位元組的,順便說一下哪些屬性可以繼承

  • 所有元素可繼承:visibilitycursor

  • 內聯元素和塊元素可繼承:letter-spacing、word-spacing、white-space、line-height、color、font、 font-family、font-size、font-style、font-variant、font-weight、text- decoration、text-transform、direction

  • 塊狀元素可繼承:text-indenttext-align

  • 列表元素可繼承:list-style、list-style-type、list-style-position、list-style-image

  • 表格元素可繼承:border-collapse

  • 不可繼承的:display、margin、border、padding、background、height、min-height、max- height、width、min-width、max-width、overflow、position、left、right、top、 bottom、z-index、float、clear、table-layout、vertical-align、page-break-after、 page-bread-before

不用CSS表示式

不亂用CSS reset或屬性設定

避免適用萬用字元或隱式萬用字元

javascript程式碼優化

儘量使用原生方法

javaScript是解釋性語言,相比編譯性語言執行速度要慢。瀏覽器已經實現的方法,就不要再去實現一遍了。另外,瀏覽器已經實現的方法在演算法方面已經做了很多優化

不要型別轉換

JavaScript是動態型別,但如果你想提高速度不要使用該功能。儘量保持變數的型別一致。這也適用於陣列,儘管主要是由瀏覽器都進行了優化,但儘量不要混用不同型別的陣列

避免使用不支援的語法

優化編譯器不支援一些特定的語句, 使用這些語法會使包含它的函式無法得到優化.
有一點請注意, 即使這些語句無法到達或者不會被執行, 它們也會使相關函式無法被優化
目前不會被優化的有:

  • generator 函式

  • 包含 for...of 語句的函式

  • 包含 try...catch 的函式

  • 包含 try...finally 的函式

  • 包含複合 let 賦值語句的函式 (原文為 compound let assignment)

  • 包含複合 const 賦值語句的函式 (原文為 compound const assignment)

  • 包含含有 __proto__ 或者 get/set 宣告的物件字面量的函式

可能永遠不會被優化的有:

  • 包含 debugger 語句的函式

  • 包含字面呼叫 eval() 的函式

  • 包含 with 語句的函式

處理方法

之前提到過的一些語句在生產環境中是無法避免的, 比如 try...finallytry...catch. 為了是代價最小, 它們必須被隔離到一個最小化的函式, 以保證主要的程式碼不受影響.

使用微類庫

通常開發者都會使用JavaScript類庫,如jQuery、Mootools、YUI、Dojo等,但是開發者往往只是使用JavaScript類庫中的部分功能。為了更大的提升效能,應儘量避免使用這類大而全的類庫,而是按需使用微類庫來輔助開發

用做標記的變數儘可能使用布林型別

直接用true和false做標記,不要使用數字或者字串的1和0來做標記。

jquery最佳實踐

jquery最佳實踐筆記

網路請求角度入手

正常的一次網路請求會經歷4個過程,分別是:DNS解析 -> TCP建立連結 -> 網路往返時延(RTT) -> 資料傳輸,面臨的挑戰可以總結為時延較高、頻寬有限、流量有成本,具體各過程面臨的挑戰和優化措施如下。

  1. DNS解析

    • 主要挑戰:解析耗時長

    • 優化措施

      1. 減少域名

      2. 首屏在3個域名內

      3. 減少DNS查詢,避免重定向。瀏覽器DNS快取 、計算機DNS快取、 伺服器DNS快取、使用Keep-Alive特性 來減少DNS查詢。

    參考資料: DNS解析

  2. TCP連線

    • 主要挑戰:除了TCP握手會多一次網路往返,另外在移動端網路建立TCP連結前,還需要進行信令的互動,在2G環境下影響最為明顯

    • 優化措施(複用)

      1. HTTP2.0多路複用
        HTTP/2 可以很容易的去實現多流並行而不用依賴建立多個 TCP 連線,HTTP/2 把 HTTP 協議通訊的基本單位縮小為一個一個的幀,這些幀對應著邏輯流中的訊息。並行地在同一個 TCP 連線上雙向交換訊息。

           單連線多資源的方式,減少服務端的連結壓力,記憶體佔用更少,連線吞吐量更大
           由於 TCP 連線的減少而使網路擁塞狀況得以改善,同時慢啟動時間的減少,使擁塞和丟包恢復速度更快
        
      2. HTTP1.1持久連線

    參考資料:知乎HTTP2.0

  3. 網路往返時延(RTT)

    • 主要挑戰:耗時長

    • 優化措施(複用、合併、就近接入)

      1. 就近接入

        • 靜態資源:接入CDN

        • 動態資料
          接入移動運營商和小運營商反向代理進行加速

      2. 合併請求,減少請求數量

        • 首屏禁止301、302跳轉

        • 合併樣式和指令碼

        • 使用css圖片精靈

        • 首屏必須小圖片使用base64格式內嵌入HTML

        • 初始首屏之外的圖片資源按需載入,靜態資源延遲載入

        • 合併外聯程式碼

      3. 快取

        • 抽出公共程式碼複用快取

        • 使用LocalStorage等快取資料

        • 圖片/外鏈程式碼開啟快取

    參考資料:知乎合併 HTTP 請求是否真的有意義?

  4. 資料傳輸

    • 主要挑戰:頻寬有限、流量有成本

    • 優化措施(複用、壓縮、分包)

      1. 壓縮

        • 圖片優化

          不需要背景透明的採用jpg代替png
          使用webp
          使用合適尺寸的圖片,而不是對圖片進行拉伸
        • 開啟GZIP

        • 壓縮程式碼

        • 靜態資源使用不帶cookie的域名

      2. 複用
        HTTP 304

網路問題角度入手

頁面在網路上遇到的問題可以總結為一個或多個網路請求以及每個請求的流量問題,在請求數量以及每個請求的流量固定的情況下,可以通過優化請求順序以及合理劃分流量來提升使用者體驗,請求順序和流量劃分通常遇到的問題和優化措施如下。

  1. 請求

    • 主要挑戰:
      沒有充分利用有限的併發數量,序列載入資料
      可以預先載入的操作沒有預先載入
      無用請求搶佔併發數量

    • 優化

      1. DNS的預解析
        可以通過用meta資訊來告知瀏覽器, 我這頁面要做DNS預解析

        <meta http-equiv="x-dns-prefetch-control" content="on" />
        可以使用link標籤來強制對DNS做預解析:
        <link rel="dns-prefetch" href="http://ke.qq.com/" />
      2. HTTP管線化
        HTTP管線化可以克服同域並行請求限制帶來的阻塞,它是建立在持久連線之上,是把所有請求一併發給伺服器,但是伺服器需要按照順序一個一個響應,而不是等到一個響應回來才能發下一個請求,這樣就節省了很多請求到伺服器的時間。不過,HTTP管線化仍舊有阻塞的問題,若上一響應遲遲不回,後面的響應都會被阻塞到。

      3. 刪除無用請求

    1. 流量

      • 主要挑戰:各種流量混在一起載入,流量之間沒有優先順序

      • 優化措施(延遲載入)

        1. 延遲載入非首屏程式碼(拆分首屏css,首屏js)

        2. 延遲載入非首屏資料
          懶載入,螢幕滾動到才載入

        3. 延遲載入非首屏圖片
          輪播圖片等第一張圖片載入後再載入後面其他圖片

網站效能工具

YSLOW
會按照雅虎軍規分析網站
Page Speed Online
Google Page Speed 是當下很流行的線上測試網站效能工具,基於Google的一套最佳的前端效能的規則,你可以很方便得到大量的效能資訊,甚至還提供了移動裝置的最佳實踐報告。
Show Slow
它能從三個流行的測試工具YSlow,Page Speed和DynaTrace定期獲取測試資料進行總結對比,免費,但需要註冊。

相關文章