大前端性能總結

Node端性能

性能評估

  1. 經過性能測試工具評估:javascript

    • wrk:支持lua腳本,能夠輕鬆應對各類測試需求,如
    -- 帶隨機參數請求
    function request()
        wrk.headers["Connection"] = "keep-Alive"
        arg = math.random(1, 500)
        path = "/random?arg=" .. arg
        return wrk.format("GET", path)
    end
    複製代碼
  2. 經過v8 profiling查看程序執行過程數據,與Webstorm聯合使用,能夠在Webstorm【Run/Debug Configurations】裏面配置,注意須要先安裝:v8-profilercss

常見優化方案

  1. 併發請求,例如:promise.all併發三方HTTP接口調用、RPC調用
  2. 若是用到mysql
    • 使用數據庫鏈接池,重用鏈接
    • 經常使用查詢創建索引
    • 用程序避免聯合查詢
    • 讀寫分離
  3. 加入緩存策略

前端性能

DNS查詢

  • 減小DNS查詢次數

TCP/HTTP

優化核心

  1. 消除和減小沒必要要的網絡延遲
  2. 把傳輸字節數降到最少

具體步驟

  • 減小HTTP請求:對於HTTP1.0/1.1 減小請求資源數(打包、壓縮、合併等)
  • 使用CDN
  • 添加Expires首部並配置ETag標籤
  • GZip資源
  • 避免HTTP重定向
  • 持久化鏈接:避免TCP的三次握手,HTTP1.1默認開啓,HTTP1.0可使用:Connection: Keep-Alive
  • HTTP1 不支持多路複用,能夠爲一臺主機並行打開多個TCP會話(通常爲6個)
  • 消除沒必要要的請求字節(HTTP1 請求、響應頭不會被壓縮)
  • 嵌入資源,如:Base64嵌入資源(針對小的靜態圖片資源)

客戶端渲染

關鍵渲染路徑:DOM -> CSSDOM / JS -> RenderTree -> Layout -> Paint html

瀏覽器渲染過程

構建DOM

  • 構建過程:character -> token -> node -> DOM
  • 增量構建

構建CSSOM(CSS Object Model)

  • 構建過程:character、token、node、CSSOM
  • 選擇器越複雜,匹配用的時間約多

構建RenderTree

  • RenderTree包含全部須要呈如今頁面上的節點信息
  • display: none的元素不會被添加到RenderTree中,由於它不須要被渲染,visibility: hidden的元素會被添加到RenderTree中

Layout

  • 計算須要渲染的節點的大小和位置
  • 節點位置和大小是基於將viewport計算的
  • 在移動端一般將viewport設置爲瀏覽器推薦的理想視口,以保證字體顯示大小易於閱讀
  • 旋轉屏幕、修改瀏覽器窗口大小,修改位置大小相關的CSS屬性,均可能觸發Layout

Paint

  • 根據background、border、box-shadow等樣式,將Layout生成的區域填充爲最終將顯示在屏幕上的像素

資源優化

CSS性能優化(防止資源阻塞初次渲染)

  • media query(link裏面加上media)
    • 此時樣式表仍然會加載,當瀏覽器環境不匹配媒體查詢條件時,該樣式表不會阻塞渲染
    • 針對不一樣媒體環境拆分CSS文件,避免爲了加載非關鍵CSS資源,而阻塞初次渲染
  • 使用DOM API添加link不會阻塞初次渲染
var style = document.createElement('lin');
style.rel = 'stylesheet';
style.href = 'index.css';
document.head.appendChild(style);
複製代碼
  • preload & prefetch & prerender(不止能夠用於CSS)
    • rel="preload",不是stylesheet不會阻塞渲染
    • preload是resource hint規範中定義的一個功能,resource hint告知瀏覽器提早創建鏈接或加載資源,以提升資源加載的速度:
      • preload:https://www.w3.org/TR/preload/
      • prefetch & prerender:https://w3c.github.io/resource-hints/#prefetch
    • 瀏覽器遇到標記爲preload的link時,會開始加載它
    • 當onload事件發生時,將rel改成stylesheet,便可應用此樣式
    • 能夠經過 loadCSS.js 使用preload (CSS preload polyfill):原理其實就是使用DOM API
<link rel="preload" type="text/css" href="./style.css" as="style" onload="this.rel='stylesheet'"/>
複製代碼

JS性能優化

  • JS會阻塞HTML Parse(HTML解析器,增量),於是會阻塞出如今腳本後面的HTML標記的渲染
  • 緣由:JS能夠經過document.write修改HTML文檔流,所以在執行JS時,瀏覽器會暫停解析DOM的工做
  • CSS會阻塞JS
  • 瀏覽器資源加載策略(preload,與前面CSS preload不同,詳見:https://juejin.im/post/5a4ed917f265da3e317df515)
    • 當HTML Parser被腳本阻塞時,Parser雖然會中止構建DOM,但仍會識別該腳本後面的資源,並提早加載
  • 性能優化(防止阻塞)
    • 將資源放到body底部
    • 使用defer延遲腳本執行:使用defer,該腳本會被推遲到整個HTML文檔解析完後,再開始執行。被defer的腳本,在執行時會嚴格按照在HTML文檔中出現的順序執行。使用defer方法,能夠提前腳本資源加載
    • 使用async異步加載腳本:該腳本不會阻塞HTML parser,也不會被CSS阻塞,腳本加載完就開始執行。async適用於無依賴的獨立資源(好比百度統計代碼)

圖片

  • 使用blob異步加載
  • 使用img-2代替img標籤(原理與上面同樣),對於圖片多的網站輕鬆提高五倍以上訪問速度

字體

  • 瀏覽器爲了不FOUT(Flash Of Unstyled Text),會盡可能等待字體加載完成後,再顯示應用了該字體的內容。帶來了FOIT(Flash Of Invisible Text 問題),致使空白
  • 設置多字體,降級方法:使用默認字體
  • 異步加載字體文件:經過異步加載CSS,便可避免字體阻塞渲染,仍是會空白

其它

優化關鍵渲染路徑

優化目標

  • 關鍵資源數
  • 關鍵資源體積
  • 關鍵資源網絡來回數

勿盲目內聯資源

  • 若啓用HTTP2,則無需內聯資源
  • 若資源被多個頁面共享,則沒法充分利用緩存,致使重複得下載

內聯與緩存結合

  • 首次訪問,使用內聯,並經過異步(如:rel="prefetch")請求緩存資源,緩存成功經過cookie標記,下次訪問時,則只返回外部資源標記

其它

經常使用工具

性能測試工具

相關資料

補充

TTFB(Time To First Byte):

  • 從客戶端發出請求到接收到第一個響應字節所花費時間(Transfer-Encoding: chunked)

HTTP2.0主要設計:

  • 解決HTTP中「隊首阻塞」;
  • 二進制分幀機制,無需創建多個TCP鏈接,從而改進TCP利用率
  • 保持HTTP1.1語義

隊首阻塞:

  • HTTP應用層隊首阻塞:按照優先級發送請求
  • TCP傳輸層隊首阻塞:TCP要求分組嚴格按照順序交付

React性能優化Time Slicing(附Suspence):

相關文章
相關標籤/搜索