Node端性能
性能評估
-
經過性能測試工具評估: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
複製代碼
-
經過v8 profiling查看程序執行過程數據,與Webstorm聯合使用,能夠在Webstorm【Run/Debug Configurations】裏面配置,注意須要先安裝:v8-profilercss
常見優化方案
- 併發請求,例如:promise.all併發三方HTTP接口調用、RPC調用
- 若是用到mysql
- 使用數據庫鏈接池,重用鏈接
- 經常使用查詢創建索引
- 用程序避免聯合查詢
- 讀寫分離
- 加入緩存策略
前端性能
DNS查詢
TCP/HTTP
優化核心
- 消除和減小沒必要要的網絡延遲
- 把傳輸字節數降到最少
具體步驟
- 減小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):