快速定位網站效能問題,提前下班!
阿新 • • 發佈:2020-03-31
> 大家好,我是小雨小雨,致力於分享有趣的、實用的技術文章。
> 內容分為翻譯和原創,如果有問題,歡迎隨時評論或私信,希望和大家一起進步。
> 分享不易,希望能夠得到大家的支援和關注。
#### 檢視network時間
直接來一張大圖你怕不怕?哈哈
咱們先看看谷歌瀏覽器network中waterfall各欄位的含義哈。簡單看下就成,用到了再查不耽誤的。
![](https://user-gold-cdn.xitu.io/2020/3/31/171306b28561ddaa?w=860&h=762&f=png&s=91595)
- Queueing: 排隊時間,比如出現以下幾種情況的時候,將進入排隊
1. 當前請求前有優先順序更高的其他請求
1. HTTP的1.0和1.1版本中,如果對一個域傳送超過六個請求,那麼之後的請求需要等待之前請求處理完畢,這是瀏覽器對tcp連線數的限制。我們可以將資源託管到不同域下來緩解
1. 瀏覽器在進行其他操作,比如分配硬碟記憶體
- Stalled: 傳送請求之前等待的時間。它可能因為進入佇列的任意原因而被阻塞。這個時間包括代理協商的時間
- DNS Lookup: dns解析時間。線路為: 瀏覽器快取 => 作業系統快取 => 路由器快取 => 本地hosts檔案 => dns伺服器
- Waiting (TTFB): 瀏覽器從傳送請求到接收到伺服器第一個位元組的時間,全拼: Time To First Byte,包含這幾個操作: DNS解析 + TCP三次握手 + HTTP請求 + 第一位元組返回
- Content Download: 內容下載時間
##### 非 常用
- ssl: ssl握手時間
- Proxy negotiation: 代理協商時間
- Request sent: 傳送請求這一操作所花費的時間,一般情況下很短
- ServiceWorker Preparation: service worker啟動時間
- Request to ServiceWorker: 請求傳送到service worker的時間
- Receiving Push: 收到服務端傳送的資料的時間(http2.0支援)
- Reading Push: 讀取之前快取的伺服器推送的資料的時間(http2.0支援)
[Queueing&TTFB](https://developers.google.com/web/tools/chrome-devtools/network/issues#queued-or-stalled-requests)
#### 讓瀏覽器說話
常見的一個問題是:說說從輸入url到瀏覽器頁面展示這個流程,這次,只說瀏覽器接收到html後,瀏覽器做了什麼,並且是讓瀏覽器自己說,我們就看著。
下面例項程式碼:
```html
Document
上途中上方是network時間線,下面是主執行緒時間線
怎麼?你說影響defer和async影響到html解析了?沒有啊,他們那是佔了normal的光~
下載完之後,就各自為營,按部就班的執行啦。
![](https://user-gold-cdn.xitu.io/2020/3/31/171306b286589479?w=2510&h=268&f=png&s=109266)
看到沒,就算defer寫到async的上面,也不一定就在async前面執行,defer肯定得在DOMContentLoad之前執行,而async的話,啥時候完事啥時候執行。也就是說,只有defer不會影響html解析,所以啊,如果你們要想加快頁面顯示的話,就視情況多用defer吧。還有,這倆屬性只有script在head中才會生效嗷。
- 放到head標籤內,啥都不加的script
![](https://user-gold-cdn.xitu.io/2020/3/31/171306b286aca1ae?w=1133&h=248&f=png&s=6198)
- 放到body標籤內,啥都不加的script
![](https://user-gold-cdn.xitu.io/2020/3/31/171306b286d7b13e?w=1137&h=203&f=png&s=5150)
- 放到head標籤內,加defer的script
![](https://user-gold-cdn.xitu.io/2020/3/31/171306b2870c14b8?w=1133&h=251&f=png&s=5339)
- 放到head標籤內,加async的script
![](https://user-gold-cdn.xitu.io/2020/3/31/171306b881a3f817?w=1132&h=247&f=png&s=5941)
再往後就會執行頁面的佈局和渲染啦~
對了,再囑咐你們一點,匿名函式我只能用統一的命名顯示出來,所以你們除錯的時候,估計不會很愉快。要根據情況決定是否真的有必要使用匿名函式啊~
![](https://user-gold-cdn.xitu.io/2020/3/31/171306b304ae71f9?w=1132&h=324&f=png&s=64042)
> 我回來了~
所以說,我們首先可以合理載入執行script來減少html解析的阻塞,其實還有css的元素,因為css會阻塞css的執行,畢竟js有可能要操作css嘛。
還有什麼迴流、重繪什麼的,這裡就不再重複了。
有興趣的朋友可以用某些網站檢視一些performance,看看自己的掌握程度,有問題歡迎討論。
> 猜測,類似詞法解析和語法解析,詞法解析先獲取到要下載的內容,或者繫結在document上的事件,所以之後出發DOMContentLoad的時候會觸發之前繫結的事件,而且沒有在主執行緒中顯示
#### 總結
本文簡單的說了兩個點,一是network的timing欄,二是performance panel,只要掌握了這兩個功能的使用方法,就可以快速定位網站效能問題,進而進行優化,早點下班美滋滋~
常見優化方案
- 開啟壓縮
- 圖片使用webp
- cdn
- 提取關鍵幀資源,優先載入
- 程式碼分片,延遲載入
- 預載入,preload prefetch等
- script defer async
- 域名分片,減少請求數
- 服務端渲染
- 如果已經升級為https,可以考慮使用http2.0。兩個點:一個頭資訊壓縮,二是解決了隊頭阻塞問題,三是增加了服務端push。
- 資源預取,混合應用可以加離線寶
- 在mvvm類框架進行前端渲染,我們可以使用defer加在我們的內容,在配上骨架圖,保證使用者看到的不是空白的頁面。
- 當然少不了我們的業務程式碼,好的程式碼會讓網站更穩定的執行下去
- 分析network的timing,然後通過本文最開始提及的各欄位分析問題
> 如果你看過一些語言和框架,你會發現大同小異
------
不過,這些個優化只是在我們看來,還是不夠完善的,我們需要知道真實的使用者環境下是怎麼樣的,需要RUM(Real User Monitoring: 真實使用者資料監測),寫個指令碼來收集使用者的訪問情況,並可視化,作為我們的效能指標再好不過了。
這裡推薦採用三組資料:
- 平均值: 平均速度
- 中位值: 中間速度
- 第95百分位值: 弱勢網路、瀏覽器等資料,更全面
可以使用[performance](https://developer.mozilla.org/en-US/docs/Web/API/Performance)和[Resource Timing API](https://developer.mozilla.org/en-US/docs/Web/API/Resource_Timing_API/Using_the_Resource_Timing_API)來進行資料收集
想做更多的優化,還是應該瞭解一下chromium原始碼,錦上添花。
如果不想看原始碼,那就讓瀏覽器來告訴我們,它做了什麼吧~
最後,在網站優化方面,前端能做的不是很多,真正的大頭是在op和服務端,所以說,轉行吧~