在准備面試,然后復習到了計網的知識點,緊接着又扯到了url從輸入到瀏覽器渲染的那個問題,這里來順便完善補充一下,本文的重點在渲染
上面的圖就是瀏覽器從服務器請求來頁面后渲染的全過程
這里我們分開來看:分為了四大步
-
解析DOM樹和CSSOM
1.HTML標簽進行Dom樹解析:
在Dom樹解析的過程中,遇到link會去進行請求資源,這個過程不會阻塞Dom的解析;
遇到script標簽,則會將解析停下來,去執行js代碼,因此script標簽通常建議放在</body>之前,能優化用戶體驗,減少白屏時間,還可以使用js動態加載生產script標簽(PS:這個jsonp跨域請求有在使用)
這里需要注意img標簽是不會阻塞Dom的解析的,雖然他也有src標簽去請求外部資源
下面是大佬思否上的原話:
解析遇到link、script、img標簽時,瀏覽器會向服務器發送請求資源。
script的加載或者執行都會阻塞html解析、其他下載線程以及渲染線程。
link加載完css后會解析為CSSOM(層疊樣式表對象模型,一棵僅含有樣式信息的樹)。css的加載和解析不會阻塞html的解析,但會阻塞渲染。
img的加載不會阻塞html的解析,但img加載后並不渲染,它需要等待Render Tree生成完后才和Render Tree一起渲染出來。未下載完的圖片需等下載完后才渲染。
2.CSS語法進行CSS樹解析
CSS解釋器將CSS進行解釋然后解析
划重點!!!Dom樹和CSSOM兩者不是解析完再渲染的,而是邊解析邊進行渲染的!
-
DOM樹和CSSOM渲染完成后合並生成Render樹
-
布局(reflow重排發生在這個階段)
這個階段是通過遞歸調用進行布局的,引擎計算各元素的尺寸大小,進行布局樹繪制
觸發重排:
- 頁面首次渲染
- 瀏覽器窗口大小變化
- 元素尺寸、位置、內容、字體大小發生變化
- 添加或刪除可見的元素
- 激活偽類時
- 繪制(repainting重繪發生在這個階段)
觸發重繪:改變元素顏色、背景、visibility、outline等屬性
!!!划重點 ,重排一定會觸發重繪,重繪不一定會觸發重排
阻塞問題總結
阻塞發生的情況:
- 遇到script標簽加載js的時候會加載js並且執行完畢才開始渲染
- 遇到alert會阻塞
- css也會阻塞
- css是由單獨的下載線程異步下載的。
總結:
1.css加載不會阻塞DOM樹的解析
2.css加載會阻塞DOM樹(render樹)的渲染
3.css加載會阻塞后面js語句的執行
為了避免讓用戶看到長時間的白屏時間,我們應該盡可能的提高css加載速度,比如可以使用以下幾種方法:
- 使用CDN(因為CDN會根據你的網絡狀況,替你挑選最近的一個具有緩存內容的節點為你提供資源,因此可以減少加載時間)
- 對css進行壓縮(可以用很多打包工具,比如webpack,gulp等,也可以通過開啟gzip壓縮)
- 合理的使用緩存(設置cache-control,expires,以及E-tag都是不錯的,不過要注意一個問題,就是文件更新后,你要避免緩存而帶來的影響。其中一個解決防范是在文件名字后面加一個版本號)
- 減少http請求數,將多個css文件合並,或者是干脆直接寫成內聯樣式(內聯樣式的一個缺點就是不能緩存)