跳到主要內容
黯羽輕揚每天積累一點點

佈置行內腳本

免費2015-11-27#JS#Solution#JavaScript行内脚本#css阻塞渲染#逐步渲染

如果行內腳本放置的位置不對,CSS 也可能會阻塞頁面渲染

##一.避免行內腳本阻塞渲染

  • 把行內腳本移至底部(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 變成阻塞的,保證只引用外部腳本就可以避免這個問題

###參考資料

  • 《高效能網站建設進階指南》

評論

暫無評論,快來發表你的看法吧

提交評論