亚洲视频二区_亚洲欧洲日本天天堂在线观看_日韩一区二区在线观看_中文字幕不卡一区

公告:魔扣目錄網(wǎng)為廣大站長提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.430618.com 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

前言

First paint 直譯過來的意思就是瀏覽器第一次渲染(paint),在First paint之前是白屏,在這個(gè)時(shí)間點(diǎn)之后用戶就能看到(部分)頁面內(nèi)容。

所以研究這個(gè)First Paint的觸發(fā)時(shí)機(jī)對于優(yōu)化瀏覽器頁面的首屏渲染時(shí)間有很重要的作用。

在正題開始之前,先說下瀏覽器的頁面的加載流程(大體過程是這樣,并不精確,只是為了幫助理解后面內(nèi)容):

  1. 瀏覽器輸入url,瀏覽器發(fā)送請求到服務(wù)器,服務(wù)器將請求的html返回給瀏覽器。
  2. 瀏覽器下載完成HTML(Finish Loading HTML)之后,便開始從上到下解析。
  3. 解析的過程中碰到css和js外鏈(其實(shí)HTML的下載也是這個(gè)流程)都會(huì)執(zhí)行以下過程:
  4. Send Request:表示給這個(gè)外鏈對應(yīng)的服務(wù)器發(fā)送請求
  5. Receive Response: 表示接收響應(yīng),這里是表示告訴瀏覽器可以開始從網(wǎng)絡(luò)接收數(shù)據(jù)了
  6. Receive Data:表示開始接收數(shù)據(jù)
  7. Finish Loading: 表示已經(jīng)完成下載數(shù)據(jù)。
  8. Parse Stylesheet/Evaluate(默認(rèn)情況下js下載完成之后執(zhí)行Evaluate,css下載完成后會(huì)進(jìn)行Parse Stylesheet)
  9. 所有的css下載完成后Parse Stylesheet然后開始構(gòu)建CSSOM
  10. DOM(文檔對象模型)和 CSSOM(CSS對象模型)會(huì)合并生成一個(gè)渲染樹(Render Tree)
  11. 根據(jù)渲染樹的內(nèi)容計(jì)算處各個(gè)節(jié)點(diǎn)在網(wǎng)頁中的大小和位置(Layout,可以理解為“刻章”)
  12. 根據(jù)Layout繪制內(nèi)容在瀏覽器上(Paint,可以理解為“蓋章”)。
Chrome的First Paint

 

正題開始

在最新版的Chrome的perfomance中是能直接看到First Paint這個(gè)時(shí)間點(diǎn)的,為了方便大家測試,我就直接拿谷歌這個(gè)示例頁面來做演示:

測試頁面

用chrome打開上面鏈接,最好是隱身模式,防止插件亂入影響判斷,按F12或者右鍵檢查元素打開控制臺(tái)先切換到Network選項(xiàng),勾選禁用緩存(緩存也會(huì)影響到判斷):

Chrome的First Paint

 

切換到Perfomance,勾選Screenshots并點(diǎn)擊紅框進(jìn)行頁面分析(會(huì)自動(dòng)停止的,不用點(diǎn)stop):

Chrome的First Paint

 

分析完后可以看到如下結(jié)果:

Chrome的First Paint

 

上圖中的綠色的線就是當(dāng)前頁面第一次出現(xiàn)內(nèi)容的時(shí)間點(diǎn),可以將鼠標(biāo)放到Main上面的Network中綠色的線附近可以看到在他之前頁面空白,在他之后就有內(nèi)容。 除了綠色的線還有藍(lán)色以及紅色的線,這里也解釋一下:

Chrome的First Paint

 

簡單講一下DOMContentLoaded、load的區(qū)別:

  1. DOMContentLoaded是HTML文檔(包括CSS、JS)被加載以及解析完成之后觸發(fā)(即 HTML->DOM的過程完成 )
  2. load則是在頁面的其他資源如圖片、字體、音頻、視頻加載完成之后觸發(fā)
  3. load事件一般在DOMContentLoaded之后才觸發(fā)(也有可能在它之前哦)

這個(gè)時(shí)候發(fā)現(xiàn)綠色虛線之前有一個(gè)淺綠色方塊,相應(yīng)的解釋如下:

Chrome的First Paint

 


Chrome的First Paint

 

由圖可以得出“淺綠色”代表的是根據(jù)CSSOM計(jì)算樣式并進(jìn)行布局繪制的過程,這段時(shí)間內(nèi)瀏覽器做了一下事情:

  1. Recalculate Style:重新計(jì)算樣式,確定DOM元素的樣式規(guī)則(定規(guī)則)
  2. Layout:根據(jù)計(jì)算結(jié)果進(jìn)行布局,確定元素的大小和位置(刻章)
  3. Update Layer Tree: 更新渲染層樹
  4. Paint: 繪制,根據(jù)前面的Layer Tree繪制頁面(位置、大小、顏色、邊框、陰影等)(蓋章)
  5. Composite Layers: 形成層,瀏覽器按照合理的順序合并成一個(gè)圖層然后輸出到屏幕(給別人看)
Chrome的First Paint

 

那什么時(shí)候開始First paint呢?在淺綠色方塊最前面的虛線往前看,發(fā)現(xiàn)在灰色虛線之前都會(huì)有一個(gè)步驟:就是Parse Stylesheet(調(diào)研了很多頁面都是如此)

Chrome的First Paint

 

所以,F(xiàn)irst Paint的加載流程應(yīng)該是這樣:

  1. 所有的CSS加載完成
  2. Parse Stylesheet:構(gòu)建出CSSOM
  3. Recalculate Style:重新計(jì)算樣式,確定DOM元素的樣式規(guī)則(定規(guī)則)
  4. Layout:根據(jù)計(jì)算結(jié)果進(jìn)行布局,確定元素的大小和位置(刻章)
  5. Update Layer Tree:更新渲染層樹
  6. Paint:繪制,根據(jù)前面的Layer Tree繪制頁面(位置、大小、顏色、邊框、陰影等)(蓋章)
  7. Composite Layers:形成層,瀏覽器按照合理的順序合并成一個(gè)圖層然后輸出到屏幕(給別人看)

但是現(xiàn)在還只是確定了First Paint的加載流程,也確定了他是在所有CSS執(zhí)行完P(guān)arse Stylesheet之后才會(huì)觸發(fā),但是這還是不夠準(zhǔn)確啊,所以我找了一些CSS和JS的外鏈來測試,模板如下:

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <title>Document</title>
 <link href="https://cdn.bootcss.com/bootstrap/4.0.0/css/bootstrap.css" rel="stylesheet">
 <link href="https://cdn.bootcss.com/jqueryui/1.12.1/jquery-ui.css" rel="stylesheet">
 <script src="https://cdn.bootcss.com/vue/2.5.13/vue.js"></script>
 <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
 <script src="https://cdn.bootcss.com/react/16.4.0-alpha.0911da3/cjs/react.development.js"></script>
 <script src="https://cdn.bootcss.com/angular.js/2.0.0-beta.17/angular2.js"></script>
</head>
<body>
 <div id='root1'>
 1
 </div>
 <div id='root2'>
 2
 </div>
 <div id='root3'>
 3
 </div>
</body>
</html>

我們通過改變上面模板里的外鏈順序來探究:

第一種情況:

Chrome的First Paint

 


Chrome的First Paint

 

發(fā)現(xiàn)FP發(fā)生在最后(實(shí)心的藍(lán)色線是按shift出來的,不是DOMContentLoaded),現(xiàn)在還發(fā)現(xiàn)不了什么。

第二種情況:

調(diào)換head中CSS和JS外鏈位置

Chrome的First Paint

 


Chrome的First Paint

 

仍然發(fā)現(xiàn)不了什么

第三種情況

把CSS放head,JS放</body>前

Chrome的First Paint

 


Chrome的First Paint

 

發(fā)現(xiàn)FP竟然在藍(lán)色和紅色虛線前面出現(xiàn),通過這點(diǎn)可以確定,F(xiàn)P還跟JS外鏈的位置有關(guān),繼續(xù):

第四種情況:

JS外鏈放head,CSS放</body>前

Chrome的First Paint

 


Chrome的First Paint

 

發(fā)現(xiàn)又跟第一二種情況一樣了,所以這種用法是不可取的。

第五種情況:

CSS和JS都放</body>前,且CSS緊貼在div后面,JS在CSS后面:

Chrome的First Paint

 


Chrome的First Paint

 

可以發(fā)現(xiàn)FP居然更快觸發(fā),但是我鼠標(biāo)hover到綠色虛線后,仍然是白屏,只有等到CSS加載完成執(zhí)行Parse Stylesheet之后才顯示出內(nèi)容(說明這種用法也不可取),難道body中的CSS也會(huì)影響?

第六種情況:

掉換一下上面CSS和JS的位置:

Chrome的First Paint

 


Chrome的First Paint

 

發(fā)現(xiàn)這次FP觸發(fā)而且立馬有內(nèi)容,而等到CSS加載完成之后還會(huì)再重新渲染一次,嗯,看來body中的第一個(gè)JS腳本有貓膩,接下來的情況對他特殊照顧。

第七種情況:

CSS放head中,JS放在div節(jié)點(diǎn)中間:

Chrome的First Paint

 


Chrome的First Paint

 

哈哈,居然只渲染了12倆字,說明瀏覽器會(huì)渲染body中腳本之前的內(nèi)容,那會(huì)是哪個(gè)腳本之前的內(nèi)容呢?

第八種情況:

在div之間都插入腳本

Chrome的First Paint

 


Chrome的First Paint

 

看來瀏覽器會(huì)提前渲染body中第一個(gè)腳本前的內(nèi)容(我們就把body中的第一個(gè)外鏈腳本叫做【第一腳本】吧),并且第一腳本還會(huì)在FP之后才執(zhí)行。所以結(jié)合之前得出的結(jié)論,在CSSOM準(zhǔn)備就緒之后,瀏覽器會(huì)提前渲染第一腳本前的內(nèi)容,我們可以用第九種情況來驗(yàn)證:

第九種情況:

這種情況和上種沒什么區(qū)別,只是增加了一個(gè)CSS,這個(gè)CSS中還會(huì)發(fā)出一個(gè)請求去加載其他CSS(通過@import url()的方式),所以CSS的加載時(shí)間很長。

Chrome的First Paint

 


Chrome的First Paint

 

通過結(jié)果可以看出,123在CSS下載完成之后才渲染,而不是單獨(dú)渲染一個(gè)1,所以FP必須得等到CSSOM準(zhǔn)備就緒之后才會(huì)觸發(fā),否則即使有第一腳本在也沒用。 所以到這里,我們總算可以下結(jié)論了:

FP發(fā)生在body中第一個(gè)script腳本之前的CSS解析和JS執(zhí)行完成之后。換句話說就是第一腳本之前的DOM和CSSOM準(zhǔn)備就緒之后,便會(huì)著手渲染第一腳本前的內(nèi)容。

但是...你以為到這里就結(jié)束了?其實(shí)沒有。

第十種情況:

這種情況中,head中既有JS也有CSS,body中也有第一腳本存在:

Chrome的First Paint

 


Chrome的First Paint

 

注意上圖中的vue.js是在head中的,而后面的JS文件都在body中,而且,vue.js加載完成之后,body中的JS還沒下載完成,這個(gè)時(shí)候我們調(diào)換一下vue.js和angular2.js的位置:

Chrome的First Paint

 


Chrome的First Paint

 

看,這個(gè)時(shí)候又沒有提前渲染了,123等到所有JS文件都執(zhí)行完之后才渲染,這種情況除了驗(yàn)證了第九點(diǎn)的結(jié)論,還能補(bǔ)充我們的結(jié)論:

如果第一腳本前的JS和CSS加載完了,body中的腳本還未下載完成,那么瀏覽器就會(huì)利用構(gòu)建好的局部CSSOM和DOM提前渲染第一腳本前的內(nèi)容(觸發(fā)FP);如果第一腳本前的JS和CSS都還沒下載完成,body中的腳本就已經(jīng)下載完了,那么瀏覽器就會(huì)在所有JS腳本都執(zhí)行完之后才觸發(fā)FP。

到這里本次探究就結(jié)束了,其實(shí)還有很多種情況,感興趣的可以自己去試試。

建議:

  • CSS放在head中,JS放在</body>前(如果在head必須放JS,也盡量減少他的大小,把大JS文件放</body>前)。
  • 減小head中CSS和JS大小(gzip了解一下?),
  • 優(yōu)化head中的JS和CSS外鏈的網(wǎng)絡(luò)情況,減少Stalled、TTFB和Content Download的時(shí)間。
  • 在第一腳本前使用骨架圖,可以減少用戶的白屏感知時(shí)間(對于使用JS插入模板來渲染的框架,建議將骨架圖的路由生成邏輯單獨(dú)提出來)

科普一下

  • Chrome會(huì)渲染局部CSSOM和DOM
  • First Paint和DOMContentLoaded、load事件的觸發(fā)沒有絕對的關(guān)系,F(xiàn)P可能在他們之前,也可能在他們之后,這取決于影響他們觸發(fā)的因素的各自時(shí)間(FP:第一腳本前CSSOM和DOM的構(gòu)建速度;DOMContentLoaded:HTML文檔自身以及HTML文檔中所有JS、CSS的加載速度;load:圖片、音頻、視頻、字體的加載速度)。
  • DOMContentLoaded和load事件也沒有強(qiáng)制的先后順序,DOMContentLoaded一般在load事件之前觸發(fā),但也可能在load事件之后觸發(fā)。
  • 第一腳本前的CSS如果還會(huì)去加載字體文件,那么即使CSSOM和DOM構(gòu)建完成觸發(fā)FP,頁面內(nèi)容也會(huì)是空白,只有等到字體文件下載完成才會(huì)出現(xiàn)內(nèi)容(這也是我們在打開一個(gè)加載了谷歌字體的網(wǎng)站會(huì)白屏很長時(shí)間的原因)。
  • 默認(rèn)情況下,CSS外鏈之間是誰先加載完成誰先解析,但是JS外鏈之間即使先加載完成,也得按順序執(zhí)行。
  • link外鏈后面緊跟script外鏈,須先等link parse完成之后,script才會(huì)執(zhí)行,即使script先下載完成。script后面緊跟link,也是一樣,會(huì)等script執(zhí)行完之后,link才會(huì)parse。
  • 如果script之后緊跟幾個(gè)link且script比這幾個(gè)link的下載時(shí)間都長,那script執(zhí)行完成之后link是按順序執(zhí)行。
  • RRDL:
  • R:send Request,發(fā)送資源請求
  • R:receive Response,接收到服務(wù)端響應(yīng)
  • D:receive Data,開始接受服務(wù)端數(shù)據(jù)(一個(gè)資源可能執(zhí)行多次)
  • L:finish Loading,完成資源下載
  • 瀏覽器在RRDL的時(shí)候,在D(Receive data)這個(gè)步驟可能執(zhí)行多次。
  • TTFB:Time To First Byte,第一個(gè)字節(jié)返回的時(shí)間,這個(gè)是對應(yīng)send Request到receive Response這段時(shí)間。
  • 瀏覽器會(huì)給HTML中的資源文件進(jìn)行等級分類(Hightest/High/Meduim/Low/Lowest),一般HTML文檔自身、head中的CSS都是Hightest,head中JS一般是High,而圖片一般是Low,而設(shè)置了async/defer的腳本一般是Low,gif圖片一般是Lowest。
  • 下圖中的資源文件淺色和深色和第二個(gè)圖畫紅框的位置是對應(yīng)的(不信自己計(jì)算一下對應(yīng)的時(shí)間)
Chrome的First Paint

 


Chrome的First Paint

 

希望本文能幫助到您!

點(diǎn)贊+轉(zhuǎn)發(fā),讓更多的人也能看到這篇內(nèi)容(收藏不點(diǎn)贊,都是耍流氓-_-)

關(guān)注 {我},享受文章首發(fā)體驗(yàn)!

每周重點(diǎn)攻克一個(gè)前端技術(shù)難點(diǎn)。更多精彩前端內(nèi)容私信 我 回復(fù)“教程”

原文鏈接:http://eux.baidu.com/blog/fe/Chrome%E7%9A%84First%20Paint

作者:洪閏輝

分享到:
標(biāo)簽:Chrome Paint
用戶無頭像

網(wǎng)友整理

注冊時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定