前端性能優化成神之路—前端頁面渲染流程

瀏覽器渲染的工做流程javascript

瀏覽器的工做原理。以Webkit引擎的工做流程爲例,瀏覽器加載一個HTML頁面後進行以下操做   java

解析HTML【遇到<img>標籤加載圖片】 —> 構建DOM樹瀏覽器

加載樣式 —> 解析樣式【遇到背景圖片連接不加載】 —> 構建樣式規則樹  緩存

加載javascript —> 執行javascript代碼佈局

把DOM樹和樣式規則樹匹配構建渲染樹【加載渲染樹上的背景圖片】url

計算元素位置進行佈局spa

繪製【開始渲染圖片】code

 

 

圖片加載與渲染規則對象

頁面中不是全部的<img>標籤圖片和樣式表背景圖片都會加載。設置了display:none屬性的元素,圖片不會渲染出來,但會加載。blog

<style>

.img-purple {

    background-image: url(../image/purple.png);

}

</style>

<img src="../image/pink.png" style="display:none">

<div class="img-purple" style="display:none"></div>

 

圖片資源請求以下

 

原理是把DOM樹和樣式規則樹匹配構建渲染樹時,會把可渲染元素上的全部屬性(如display:none屬性和background-image屬性)結合一塊兒產出到渲染樹。

當解析渲染樹時會加載<img>標籤元素上的圖片,發現元素上有background-image屬性時會加載背景圖片。

當繪製時發現元素上有display:none屬性,則不計算該元素位置,也不會繪製該元素。

<style>

.img-yellow {

    background-image: url(../image/yellow.png);

}

</style>

<div style="display:none">

    <img src="../image/red.png">

    <div class="img-yellow"></div>

</div>

 

圖片資源請求以下:

 

設置了display:none屬性元素的子元素,樣式表中的背景圖片不會渲染出來,也不會加載;而<img>標籤的圖片不會渲染出來,但會加載。

原理

正如上面所說的,構建渲染樹時,只會把可渲染元素產出到渲染樹,這就意味有不可渲染元素,當匹配DOM樹和樣式規則樹時,若發現一個元素的屬性上有display:none,瀏覽器會認爲該元素的子元素是不可渲染的,所以不會把該元素的子元素產出到渲染樹上。

當解析渲染樹時渲染樹上沒有設置了display:none屬性元素的子元素,所以不會加載該元素中子元素的背景圖片。

當繪製時也由於渲染樹上沒有設置了display:none屬性元素的子元素,所以該元素中子元素的背景圖片不會渲染出來。

重複圖片

 

 

.img-blue {

    background-imageurl(../image/blue.png);

}

<div class="img-blue"></div>

<img src="../image/blue.png">

<img src="../image/blue.png">

 

圖片資源請求以下:

 

 

 

頁面中多個<img>標籤或樣式表中的背景圖片圖片路徑是同一個,圖片只加載一次。

原理

瀏覽器請求資源時,都會先判斷是否有緩存,如有緩存且未過時則會從緩存中讀取,不會再次請求。先加載的圖片會存儲到瀏覽器緩存中,後面再次請求同路徑圖片時會直接讀取緩存中的圖片。

不存在元素的背景圖片

.img-blue {

    background-imageurl(../image/blue.png);

}

.img-orange{

    background-imageurl(../image/orange.png);

}

 

圖片資源請求以下:

 

 

不存在元素的背景圖片不會加載。

原理

不存在的元素不會產出到DOM樹上,所以渲染樹上也不會有不存在的元素,當解析渲染樹時沒法解析不存在的元素,不存在的元素上的圖片天然不會加載也不會渲染。

僞類的背景圖片

.img-green {

    background-imageurl(../image/green.png);

}

.img-green:hover{

    background-imageurl(../image/red.png);

}

 

觸發hover前的圖片資源請求以下:

 

觸發hover後的圖片資源請求以下:

 

當觸發僞類的時候,僞類樣式上的背景圖片纔會加載。

原理

觸發hover前,DOM樹與樣式規則樹匹配的是無hover狀態選擇器.img-green的樣式,所以渲染樹上background-image屬性的值是url(../image/green.png),解析渲染樹時加載的是green.png,繪製時渲染的也是green.png

觸發hover後,由於.img-green:hover的優先級比較高,所以DOM樹與樣式規則樹匹配的是有hover狀態選擇器.img-green:hover的樣式,渲染樹上background-image屬性的值是url(../image/red.png),解析渲染樹時加載的是red.png,繪製時渲染的也是red.png

應用

佔位圖

當使用樣式表中的背景圖片做爲佔位符時,要把背景圖片轉爲base64格式。這是由於背景圖片加載的順序在標籤後面,背景圖片可能會在<img>標籤圖片加載完成後纔開始加載,達不到想要的效果。

預加載

不少場景裏圖片是在改變或觸發狀態後才顯示出來的,例如點擊一個Tab後,一個設置display:none隱藏的父元素變爲顯示,這個父元素裏的子元素圖片會在父元素顯示後纔開始加載;又如當鼠標hover到圖標後,改變圖標圖片,圖片會在hover上去後纔開始加載,致使出現閃一下這種不友好的體驗。

在這種場景下,咱們就須要把圖片預加載,預加載有不少種方式:

  1. 如果小圖標,能夠合併成雪碧圖,在改變狀態前就把全部圖標都一塊兒加載了。

  2. 使用上文講到的,設置了display:none屬性的元素,圖片不會渲染出來,但會加載。把要預加載的圖片加到設置了display:none的元素背景圖或標籤裏。

  3. 在javascript建立img對象,把圖片url設置到img對象的src屬性裏。

相關文章
相關標籤/搜索