開篇 | 關於前端性能優化的探索

這是我參與8月更文挑戰的第2天,活動詳情查看:8月更文挑戰前端

前言

性能優化是每一個前端都繞不過去的課題。說到性能優化,網上一搜一大把《前端性能優化的N條建議》,諸如:git

1.減小 HTTP 的請求數;2. 使用 CDN;3. 添加 Expires 頭;4. 避免重定向;5. 將 CSS 樣式放在頁面的上方;6. 將腳本移動到底部;7. 減小 DOM 操做;8. 給圖片設置尺寸;9. 減小 DNS 查詢;10. 壓縮 JavaScript 和 CSS……github

噼裏啪啦一大堆,這對於記性不大好的我來講,這種瑣碎且毫無章法的1.2.3,太難了啊,能不能先概括一下?好比說:web

網絡層面的性能優化: 1.減小 HTTP 的請求數;2. 使用 CDN;3. 添加 Expires 頭;4. 避免重定向;9. 減小 DNS 查詢;10. 壓縮 JavaScript 和 CSS ……面試

渲染層面的性能優化: 5. 將 CSS 樣式放在頁面的上方;6. 將腳本移動到底部;7. 減小 DOM 操做;8. 給圖片設置尺寸;……瀏覽器

嗯,這樣好像好點兒,但能不能更清晰一些,這些道理都是誰說的,爲啥呀?哎,有沒有一條可循的線索,把這些零零散散的東西串起來?直到我拜讀《前端性能優化之關鍵路徑渲染優化》、《前端性能優化原理與實踐》,豁然開朗:只要循着網絡請求的過程瀏覽器渲染機制去探索,就知道爲何、以及怎麼作了。緩存

網絡請求的角度

網絡請求的過程

  1. DNS解析,獲取 URL 對應的 IP 地址
  2. 根據 IP,創建 TCP 鏈接(三次握手)
  3. HTTP 發起請求
  4. 服務器處理請求,HTTP 響應返回(瀏覽器渲染頁面,放在下一部分)
  5. 關閉 TCP 鏈接(四次揮手)

優化方向思考

  1. DNS 解析:可使用瀏覽器 DNS 緩存和 DNS prefetch 減小解析次數或者把解析前置
  2. TCP 鏈接:長鏈接、預鏈接、接入 SPDY 協議
  3. HTTP 請求:減小請求次數和減少請求體積方面,具體有利用瀏覽器緩存、本地存儲、資源的合併和壓縮、圖片優化等。

頁面渲染的角度

渲染機制

瀏覽器渲染的基本步驟

  1. 處理 HTML 標記並構建 DOM 樹
  2. 處理 CSS 標記並構建 CSSOM 樹
  3. 將 DOM 與 CSSOM 合併成一個 render tree
  4. 根據渲染樹來佈局,以計算每一個節點的幾何信息
  5. 將各個節點繪製到屏幕上

image.png

值得注意的是,Render Tree 依賴於 CSSOM Tree,若是頁面引用了外部樣式表,頁面須要等待樣式表加載完畢才能進行渲染。另外,JS 引擎和 UI 的渲染引擎是互斥的,因此當腳本在執行的時候瀏覽器要將控制權就給 JS 引擎,等到 JS 執行完畢再還給 UI 引擎(這與瀏覽器的進程管理有關)。性能優化

迴流與重繪

以上只是一個理論的渲染過程,但實際的頁面渲染並非那麼一路順風從上往下渲染就完了的。好比說,若是在渲染過程當中碰到的一個同步的 Script ,JS 改變了 DOM 結構,會發生什麼?這裏須要提到「迴流與重繪」的概念。服務器

優化方向思考

  1. 對於頁面首次渲染,減小阻塞因素
  2. 儘可能避免致使迴流與重繪的操做
  3. 利用懶加載實現首屏渲染優化
  4. 服務端渲染 ...

有了以上對網絡請求的流程 和 頁面渲染機制的認識,如今能夠理解爲何要把CSS文件放在頁面最上方、JS文件放在最下方、爲何要減小DOM操做等等。markdown

實際上還有不少細節的地方沒弄清楚,這裏咱先提個方向,更多的具體方案在後面的篇章再展開看看。

參考連接

前端性能優化之關鍵路徑渲染優化
從 8 道面試題看瀏覽器渲染過程與性能優化
前端性能優化原理與實踐
史上最全!圖解瀏覽器的工做原理

相關文章
相關標籤/搜索