關於前端頁面的性能優化是個老生常談的話題,各類技術博客已經也已經羅列出了各類方案,可是要優化,就得找出問題,像盲人摸象同樣瞎優化其實並不會有特別明顯的效果。css
chrome-dev-tools應該是作爲FE最熟悉的工具,開發時必備的調試神器。其餘先不說,今天咱們只看network.html
主要功能你們應該都會用,我只說幾個比較重要的點(指標)。前端
1. Network 面板突出顯示兩種事件:DOMContentLoaded
和 load
web
圖片底部信息欄中的藍色部分爲DOMContentLoaded事件觸發的時間,時間軸中的藍色線也表明它在整個時間軸中的位置,看起來更直觀。chrome
那麼DOMContentLoaded表明什麼呢?其實就是頁面dom文檔加載完成,翻譯成表明的話就是數據庫
document.ready = function () { ... } //or $(document).ready({...}); //or $(function(){..});
因此,這個時間應該越小越好,那麼怎麼來優化使這個時間更小呢?瀏覽器
首先,咱們應該知道在這個時間段內發生了什麼,從上圖能夠看到首先第一個加載的是document,即爲咱們發送請求後,server端通過一系列的處理返回的html文檔,能夠看出這個耗時仍是比較長的,鼠標懸停到 Timeline 圖表內的資源上時,能夠看到更詳細的信息。緩存
這幾個字段都是什麼意思呢?看一下官方的文檔性能優化
Queuing若是某個請求正在排隊,則指示:服務器
Stalled/Blocking請求等待發送所用的時間。 能夠是等待 Queueing 中介紹的任何一個緣由。 此外,此時間包含代理協商所用的任什麼時候間。
Proxy Negotiation與代理服務器鏈接協商所用的時間。
DNS Lookup執行 DNS 查詢所用的時間。 頁面上的每個新域都須要完整的往返才能執行 DNS 查詢。
Initial Connection / Connecting創建鏈接所用的時間,包括 TCP 握手/重試和協商 SSL 的時間。
SSL完成 SSL 握手所用的時間。
Request Sent / Sending發出網絡請求所用的時間。 一般不到一毫秒。
Waiting (TTFB)等待初始響應所用的時間,也稱爲至第一字節的時間。 此時間將捕捉到服務器往返的延遲時間,以及等待服務器傳送響應所用的時間。
Content Download / Downloading接收響應數據所用的時間。
能夠看出上圖中中TTFB的時間比較長,而官方的建議是將此值控制在 200 毫秒如下。而致使這個耗時較長的緣由有兩個:
解決辦法是首先儘量縮減網絡。理想的狀況是將應用託管在本地,而後查看 TTFB 是否仍然很長。若是仍然很長,則須要優化應用的響應速度。有不少潛在因素均可能會延緩服務器響應,例如應用邏輯緩慢、數據庫查詢緩慢、路由緩慢、框架、庫、資源CPU不足或內存不足等。因此須要server端的學生優化一下了,能夠是優化數據庫查詢、爲特定部分的內容實現緩存,或者修改網絡服務器配置。
因此當你看到timeline上有大片綠色時,別猶豫,把優化的艱鉅任務讓給server吧,他們的工做應該又飽合了一些。
參考:
https://developers.google.com/web/tools/chrome-devtools/network-performance/understanding-resource-timing?hl=zh-cn
當TTFB優化好之後,那該fe上場了。接下來咱們能作什麼呢?
1. 合併資源,減小請求
當DOM加載完成後便開始解析,其餘的資源也開始加入請求隊列,這時就會有個問題,若是是http1協議的話併發的http請求數是有限制的,chorme是6個。其餘瀏覽器稍有差別,不過大概也是在這個數量。如下爲瀏覽器具體的限制:
IE 6 and 7: 2 IE 8: 6 IE 9: 6 IE 10: 8 IE 11: 8 Firefox 2: 2 Firefox 3: 6 Firefox 4 to 46: 6 Opera 9.63: 4 Opera 10: 8 Opera 11 and 12: 6 Chrome 1 and 2: 6 Chrome 3: 4 Chrome 4 to 23: 6 Safari 3 and 4: 4
因此爲了儘量減小限制,更多的加載資源就要把該合併的合併,該壓縮的壓縮。
2. 靜態資源上傳CDN
上邊說到的http限制是有一個條件就是同一主機下才有的,因此解決限制的辦法還有一個就是域分片。也就是在應用上設置多個子域,以便提供資源。而後,在子域之間平均分配正在提供的資源。而CDN原本就是用來最近的訪問資源,因此CDN是必定要用的。
3. 加載順序
加載順序這個你們知道,由於js會阻塞DOM的解析,因此js文件儘可能放到文檔底部,而css必需要放在文檔頭部,由於會根據css文件生成cssDOM,而後由DOM和cssDOM合併才能產生渲染樹,有了渲染樹纔會去接下來的佈局和解析。
4. aync和defer
defter
當 HTML 文檔被解析時若是碰見 defer 腳本,則在後臺加載腳本,文檔解析過程不中斷,而等文檔解析結束以後,defer 腳本執行。另外,defer 腳本的執行順序與定義時的位置有關。過程以下圖:
async
當 HTML 文檔被解析時若是碰見 async 腳本,則在後臺加載腳本,文檔解析過程不中斷。腳本加載完成後,文檔中止解析,腳本執行,執行結束後文檔繼續解析。過程以下圖:
若是 script 標籤中包含 defer,那麼這一塊腳本將不會影響 HTML 文檔的解析,而是等到 HTML 解析完成後纔會執行。而 DOMContentLoaded 只有在 defer 腳本執行結束後纔會被觸發。 因此這意味着什麼呢?HTML 文檔解析不受影響,等 DOM 構建完成以後 defer 腳本執行,但腳本執行以前須要等待 CSSOM 構建完成。在 DOM、CSSOM 構建完畢,defer 腳本執行完成以後,DOMContentLoaded 事件觸發。 若是 script 標籤中包含 async,則 HTML 文檔構建不受影響,解析完畢後,DOMContentLoaded 觸發,而不須要等待 async 腳本執行、樣式表加載等等。 須要注意的是用async時,在文件加載完成後就會當即執行不會等文檔加載完,因此頗有可能不是按照本來的順序來執行的。若是js先後有依賴性,用async,就頗有可能出錯。