瀏覽器DOM渲染及阻塞問題
在準備面試,然后復習到了計網的知識點移盆,緊接著又扯到了url從輸入到瀏覽器渲染的那個問題币喧,這里來順便完善補充一下轨域,本文的重點在渲染
上面的圖就是瀏覽器從服務器請求來頁面后渲染的全過程
這里我們分開來看:分為了四大步
-
解析DOM樹和CSSOM
1.HTML標簽進行Dom樹解析:
在Dom樹解析的過程中,遇到link會去進行請求資源杀餐,這個過程不會阻塞Dom的解析干发;
遇到script標簽,則會將解析停下來史翘,去執(zhí)行js代碼枉长,因此script標簽通常建議放在</body>之前,能優(yōu)化用戶體驗琼讽,減少白屏時間必峰,還可以使用js動態(tài)加載生產script標簽(PS:這個jsonp跨域請求有在使用)
這里需要**注意**img標簽是不會阻塞Dom的解析的,雖然他也有src標簽去請求外部資源
下面是大佬思否上的原話:
解析遇到link钻蹬、script吼蚁、img標簽時,瀏覽器會向服務器發(fā)送請求資源问欠。
script的加載或者執(zhí)行都會阻塞html解析肝匆、其他下載線程以及渲染線程。
link加載完css后會解析為CSSOM(層疊樣式表對象模型,一棵僅含有樣式信息的樹)顺献。css的加載和解析不會阻塞html的解析旗国,但會阻塞渲染。
img的加載不會阻塞html的解析注整,但img加載后并不渲染能曾,它需要等待Render Tree生成完后才和Render Tree一起渲染出來嫁怀。未下載完的圖片需等下載完后才渲染。
2.CSS語法進行CSS樹解析
CSS解釋器將CSS進行解釋然后解析
** 劃重點=枳恰L潦纭!Dom樹和CSSOM兩者不是解析完再渲染的蚂斤,而是邊解析邊進行渲染的存捺!**
-
DOM樹和CSSOM渲染完成后合并生成Render樹
-
布局(reflow重排發(fā)生在這個階段)
這個階段是通過遞歸調用進行布局的,引擎計算各元素的尺寸大小曙蒸,進行布局樹繪制
觸發(fā)重排:
- 頁面首次渲染
- 瀏覽器窗口大小變化
- 元素尺寸捌治、位置、內容纽窟、字體大小發(fā)生變化
- 添加或刪除可見的元素
- 激活偽類時
- 繪制(repainting重繪發(fā)生在這個階段)
觸發(fā)重繪:改變元素顏色肖油、背景、visibility臂港、outline等屬性
I埂!审孽!劃重點 县袱,重排一定會觸發(fā)重繪,重繪不一定會觸發(fā)重排
阻塞問題總結
阻塞發(fā)生的情況:
- 遇到script標簽加載js的時候會加載js并且執(zhí)行完畢才開始渲染
- 遇到alert會阻塞
- css也會阻塞
- css是由單獨的下載線程異步下載的佑力。
總結:
1.css加載不會阻塞DOM樹的解析
2.css加載會阻塞DOM樹(render樹)的渲染
3.css加載會阻塞后面js語句的執(zhí)行
為了避免讓用戶看到長時間的白屏時間式散,我們應該盡可能的提高css加載速度,比如可以使用以下幾種方法:
- 使用CDN(因為CDN會根據你的網絡狀況打颤,替你挑選最近的一個具有緩存內容的節(jié)點為你提供資源暴拄,因此可以減少加載時間)
- 對css進行壓縮(可以用很多打包工具,比如webpack,gulp等编饺,也可以通過開啟gzip壓縮)
- 合理的使用緩存(設置cache-control,expires,以及E-tag都是不錯的乖篷,不過要注意一個問題,就是文件更新后反肋,你要避免緩存而帶來的影響那伐。其中一個解決防范是在文件名字后面加一個版本號)
- 減少http請求數,將多個css文件合并石蔗,或者是干脆直接寫成內聯樣式(內聯樣式的一個缺點就是不能緩存)