##一.避免行內腳本阻塞渲染
-
把行內腳本移至底部(
body結束標籤前) -
使用非同步回調啟動 JavaScript 的執行
-
使用 script 的 defer 屬性
###把行內腳本移至底部
把行內腳本放在 body 的結束標籤前
優點:簡單易用,頁面內的圖片等資源和位於底部的行內腳本並行下載
缺點:仍然會阻塞頁面渲染,如果行內腳本執行時間很長(大於 300ms),就不應該用這種簡單方法了
###非同步啟動執行腳本
透過 setTimeout(doStuff, 0) 來非同步執行腳本,在 Firefox 中需要延遲 250ms(250 是 Nglayout.initialpaint.delay )
優點:可以實現逐步渲染,在行內腳本開始執行之前,瀏覽器會先渲染 DOM 內容(多半是文字)
缺點:會阻塞圖片的渲染,如果圖片回應傳回時正在 doStuff,圖片將等到 doStuff 結束才會顯示。此時應該放棄 setTimeout,改用 window.onload 啟動腳本執行。當然,如果行內腳本執行時間很短(小於 300ms),用 setTimeout 是沒問題的
P.S. 對於執行時間很長的行內腳本,最理想的方案是每隔 300ms 分塊執行, setTimeout(doChunk, 300) ,但需要大規模重構程式碼,把大塊邏輯分成一些小片段(300ms 內能夠完成的)
###使用 script 的 defer 屬性
defer 屬性也適用於行內腳本,允許瀏覽器繼續解析和渲染頁面的同時延遲執行行內腳本
優點:資源並行下載
缺點:阻塞渲染,只適用於執行時間較短的行內腳本,很長的腳本仍然需要 setTimeout
##二.樣式表也會阻塞行內腳本
除了按引入順序執行 JS,瀏覽器還會保證按引入順序解析 CSS(因為不同的解析順序會導致不同的樣式結果,比如同優先級樣式覆蓋規則)
鮮為人知的:瀏覽器還會保持 CSS 和 JS 的解析順序,如果把行內腳本放在樣式表之後,會明顯地延遲資源的下載(結果是樣式表下載完成並且行內腳本執行完畢時,後續資源才能開始下載)
這是因為行內腳本可能含有依賴於樣式表中樣式的程式碼,比如 document.getElementsByClassName()
結論:在樣式表後面的行內腳本會阻塞所有後續資源的下載(或者說,如果樣式表後面沒有行內腳本的話,樣式表將與其他資源並行下載。當然,無論行內腳本前面有沒有樣式表,行內腳本都會阻塞後續資源的下載)
##三.總結
行內腳本可能會導致 CSS 變成阻塞的,保證只引用外部腳本就可以避免這個問題
###參考資料
- 《高效能網站建設進階指南》
暫無評論,快來發表你的看法吧