日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

网站性能优化--CRP

發(fā)布時(shí)間:2023/12/10 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 网站性能优化--CRP 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

網(wǎng)站性能優(yōu)化–CRP

為了把HTML、CSS和JavaScript轉(zhuǎn)化成活靈活現(xiàn)、絢麗多彩的網(wǎng)頁(yè),瀏覽器需要處理一系列的中間過(guò)程,優(yōu)化性能其實(shí)就是了解這個(gè)過(guò)程中發(fā)生了什么-即CRP(Critical Rendering Path,關(guān)鍵渲染路徑)。首先,我們從頭開始快速學(xué)習(xí)一下瀏覽器是如何顯示一個(gè)簡(jiǎn)單網(wǎng)頁(yè)的。

瀏覽器渲染一個(gè)網(wǎng)頁(yè)的過(guò)程


構(gòu)建對(duì)象模型

文檔對(duì)象模型(DOM)

<html><head><meta name="viewport" content="width=device-width,initial-scale=1"><link href="style.css" rel="stylesheet"><title>Critical Path</title></head><body><p>Hello <span>web performance</span> students!</p><div><img src="awesome-photo.jpg"></div></body> </html>

一個(gè)普通的頁(yè)面,里面包含一些文本和一張圖片,瀏覽器是如何處理這個(gè)頁(yè)面的呢?

  • 轉(zhuǎn)換:瀏覽器從磁盤或網(wǎng)絡(luò)讀取HTML的原始字節(jié),然后根據(jù)指定的文件編碼格式(例如 UTF-8)將其轉(zhuǎn)換為相應(yīng)字符
  • 令牌化:瀏覽器把字符轉(zhuǎn)化成W3C HTML5 標(biāo)準(zhǔn)指定的各種確切的令牌,比如””、””以及其他在尖括號(hào)內(nèi)的字符串。每個(gè)令牌都有特殊的含義以及它自己的一套規(guī)則
  • 詞法分析:生成的令牌轉(zhuǎn)化為對(duì)象,這個(gè)對(duì)象定義了它們的屬性及規(guī)則
  • DOM構(gòu)建:最后,由于HTML標(biāo)記定義了不同標(biāo)簽之間的關(guān)系(某些標(biāo)簽嵌套在其他標(biāo)簽中),創(chuàng)建的對(duì)象在樹狀的數(shù)據(jù)結(jié)構(gòu)中互相鏈接,樹狀數(shù)據(jù)結(jié)構(gòu)也捕獲了原始標(biāo)簽定義的父子關(guān)系:HTML對(duì)象是body對(duì)象的父對(duì)象,body是p對(duì)象的父對(duì)象等等

    上述整個(gè)流程的最終輸出是文檔對(duì)象模型,即這個(gè)簡(jiǎn)單網(wǎng)頁(yè)的 “DOM”,瀏覽器完成頁(yè)面的所有后續(xù)處理都是建立在這個(gè)DOM基礎(chǔ)上的。
    打開Chrome DevTools > Timeline,錄制時(shí)間軸,上述過(guò)程對(duì)應(yīng)Loading事件中的Parse HTML事件,可以查看到執(zhí)行這一過(guò)程所需要的時(shí)間。
    DOM樹捕獲了文檔標(biāo)記的屬性及關(guān)系,但它沒(méi)有告訴我們?cè)卦阡秩緯r(shí)是什么樣子的。這是CSSOM要干的活,也就是接下來(lái)要講的。
  • CSS對(duì)象模型(CSSOM)

    當(dāng)瀏覽器構(gòu)建上述網(wǎng)頁(yè)DOM的時(shí)候,在head里面碰到一個(gè)link標(biāo)簽,這個(gè)標(biāo)簽引用了一個(gè)外部的CSS樣式表:style.css。瀏覽器預(yù)測(cè)會(huì)需要這個(gè)資源來(lái)渲染頁(yè)面,因此會(huì)立即發(fā)出一個(gè)該資源的請(qǐng)求,該請(qǐng)求返回以下內(nèi)容:
    與HTML一樣,我們需要將收到的 CSS 規(guī)則轉(zhuǎn)換為瀏覽器可以理解、能夠處理的東西。因此,我們重復(fù)與處理 HTML 非常相似的過(guò)程:

    最終輸出的是CSS對(duì)象模型,即CSSOM。

    想要查看CSS處理過(guò)程所花費(fèi)的時(shí)間,可以在錄制的時(shí)間軸中查看Rendering事件中的Recalculate Style事件:與DOM解析不同,timeline不顯示單獨(dú)的“Parse CSS”條目,而是在Recalculate Style事件下一同捕獲CSS解析、CSSOM構(gòu)建以及computed styles的遞歸計(jì)算。

    構(gòu)建渲染樹、布局及繪制

    前面介紹了我們根據(jù)輸入的HTML及CSS構(gòu)建了DOM樹和CSSOM樹,但二者是獨(dú)立的對(duì)象:DOM描述的是文檔內(nèi)容,CSSOM描述的是應(yīng)用于文檔的樣式規(guī)則。瀏覽器會(huì)把DOM和CSSOM組合起來(lái)構(gòu)建一個(gè)渲染樹(Render-tree),渲染樹會(huì)捕獲頁(yè)面上所有可見(jiàn)的DOM內(nèi)容以及應(yīng)用在每個(gè)節(jié)點(diǎn)上的CSSOM樣式。

    構(gòu)建渲染樹的過(guò)程大致如下:

    1.從DOM樹的根節(jié)點(diǎn)開始,遍歷每個(gè)可見(jiàn)的節(jié)點(diǎn)

    • 某些節(jié)點(diǎn)不可見(jiàn)(例如 script 標(biāo)簽、meta 標(biāo)簽等),因?yàn)樗鼈儾粫?huì)體現(xiàn)在渲染結(jié)果中,所以會(huì)被忽略
    • 某些通過(guò) CSS 隱藏的節(jié)點(diǎn)在渲染樹中也會(huì)被忽略,比如應(yīng)用了 display:none 規(guī)則的節(jié)點(diǎn)

    2.為每一個(gè)可見(jiàn)的節(jié)點(diǎn)匹配并應(yīng)用對(duì)應(yīng)的CSSOM規(guī)則
    3.生成有內(nèi)容和計(jì)算樣式的可見(jiàn)節(jié)點(diǎn)

    注意:小提示:注意visibility: hidden和display: none二者的區(qū)別。visibility: hidden只是讓元素在視覺(jué)上不可見(jiàn),但是元素在頁(yè)面布局中仍然占據(jù)空間。而display: none則是從渲染樹中刪除某一個(gè)元素,不僅視覺(jué)上不可見(jiàn),渲染樹上也沒(méi)有,更不會(huì)影響到頁(yè)面的布局。
    最終輸出的就是一個(gè)包含了所有可見(jiàn)節(jié)點(diǎn)的內(nèi)容及樣式信息的渲染樹。

    到目前為止,我們已經(jīng)計(jì)算出了哪些節(jié)點(diǎn)是可見(jiàn)的以及它們的計(jì)算樣式,但是我們還沒(méi)有計(jì)算它們?cè)谠O(shè)備視口(viewport)中的準(zhǔn)確位置及尺寸大小——這就是布局(Layout)階段要做的工作,也就是常說(shuō)的重排(reflow)。

    為了計(jì)算出頁(yè)面中每個(gè)對(duì)象的準(zhǔn)確大小和位置,瀏覽器從渲染樹的根節(jié)點(diǎn)開始遍歷,計(jì)算頁(yè)面上每個(gè)對(duì)象的幾何信息。舉例如下:

    <html><head><meta name="viewport" content="width=device-width,initial-scale=1"><title>Critial Path: Hello world!</title></head><body><div style="width: 50%"><div style="width: 50%">Hello world!</div></div></body> </html>

    上面頁(yè)面的 body 包含兩個(gè)嵌套 div:第一個(gè) div(父元素)將節(jié)點(diǎn)尺寸大小設(shè)置為視口寬度的 50%,第二個(gè) div 的寬度為父元素的 50%,即視口寬度的 25%!

    布局過(guò)程的輸出是一個(gè)“盒子模型”,它精確地捕獲了每個(gè)元素在視口中的準(zhǔn)確位置及尺寸大小:所有相對(duì)度量單位都被轉(zhuǎn)換為屏幕上的絕對(duì)像素。

    自此,我們已經(jīng)知道了哪些節(jié)點(diǎn)是可見(jiàn)的以及它們的計(jì)算樣式和幾何信息,然后我們就可以把這些信息傳送到最后一個(gè)階段,即把渲染樹中的每一個(gè)節(jié)點(diǎn)都轉(zhuǎn)化到屏幕上實(shí)際的像素點(diǎn)。這個(gè)步驟通常被稱為繪制(painting)或者柵格化(rasterizing)。

    構(gòu)建渲染樹、布局與繪制所消耗的時(shí)間也可以通過(guò)timeline來(lái)查看:

    • “Layout” 事件捕獲渲染樹的構(gòu)建及位置、尺寸的計(jì)算
    • 布局完成時(shí),瀏覽器會(huì)觸發(fā) ‘Paint’ 事件:將渲染樹轉(zhuǎn)化為屏幕上的實(shí)際像素

    終于,我們的頁(yè)面在設(shè)備視口中可見(jiàn)了。

    現(xiàn)在回顧一下瀏覽器執(zhí)行的幾個(gè)步驟:

    • 處理 HTML 標(biāo)記,構(gòu)建 DOM 樹
    • 處理 CSS 標(biāo)記,構(gòu)建 CSSOM 樹
    • 將 DOM 樹和 CSSOM 樹融合成渲染樹
    • 根據(jù)渲染樹進(jìn)行布局,計(jì)算每個(gè)節(jié)點(diǎn)的幾何信息
    • 在屏幕上繪制各個(gè)節(jié)點(diǎn)

    優(yōu)化CRP

    阻塞渲染的CSS

    在構(gòu)建渲染樹部分我們已了解到:CRP要求DOM和CSSOM兩者融合在一起才能構(gòu)建渲染樹。這就導(dǎo)致了一個(gè)性能問(wèn)題:HTML和CSS都是阻塞渲染的資源。HTML很顯然,沒(méi)有DOM就沒(méi)有內(nèi)容去渲染。CSS沒(méi)有那么明顯,但確實(shí)是阻塞渲染的資源。我們知道一個(gè)正常的網(wǎng)頁(yè)如果沒(méi)有引入專用的css,頁(yè)面有多丑陋。當(dāng)我們的網(wǎng)頁(yè)引入了專用的css,頁(yè)面一加載出來(lái)的時(shí)候就是絢麗多彩的,如果css不阻塞渲染,我們看到的很可能是這樣的一個(gè)畫面:頁(yè)面剛加載出來(lái)的時(shí)候其丑無(wú)比,過(guò)了一會(huì),頁(yè)面又變漂亮了……

    既然CSS是阻塞渲染的資源,這就意味著在CSSOM構(gòu)建完成之前,瀏覽器不會(huì)去渲染任何已處理的內(nèi)容。要盡早、盡快地把CSS下載到客戶端以優(yōu)化首次渲染的時(shí)間。

    使用CSS“媒體類型”和“媒體查詢”優(yōu)化阻塞渲染的CSS:

    <link href="style.css" rel="stylesheet"> <link href="print.css" rel="stylesheet" media="print"> <link href="other.css" rel="stylesheet" media="(min-width: 40em)">
    • 第一條聲明阻塞渲染,匹配所有情況
    • 第二條聲明只適用于打印(媒體類型),因此,頁(yè)面在瀏覽器中首次加載時(shí),不會(huì)阻塞渲染
    • 第三條聲明提供了媒體查詢,由瀏覽器判斷:如果條件符合,則在該樣式表下載并處理完以前,瀏覽器會(huì)阻塞渲染

    小提示:「阻塞渲染」僅是指該資源是否會(huì)阻塞瀏覽器的首次頁(yè)面渲染。無(wú)論 CSS 是否阻塞渲染,CSS 資源都會(huì)被下載,只是說(shuō)非阻塞性資源的優(yōu)先級(jí)比較低而已。

    阻塞解析的JavaScript

    js可以修改頁(yè)面的內(nèi)容、樣式以及響應(yīng)用戶的交互,JS在DOM、CSSOM和JS執(zhí)行之間引入了很多新的依賴關(guān)系,導(dǎo)致瀏覽器在處理和渲染頁(yè)面上出現(xiàn)大幅延遲:

    • 當(dāng)瀏覽器遇到<script>標(biāo)簽時(shí),DOM構(gòu)建會(huì)暫停,直到腳本執(zhí)行完畢
    • JavaScript 執(zhí)行會(huì)暫停,直到CSSOM準(zhǔn)備就緒

    解析器阻塞 vs. 異步 JavaScript

    默認(rèn)情況下,JavaScript 執(zhí)行會(huì)阻塞解析器:當(dāng)瀏覽器在文檔中遇到<script>標(biāo)簽時(shí),DOM構(gòu)建必須暫停,瀏覽器把控制權(quán)移交給JS引擎,JS引擎編譯并執(zhí)行腳本,腳本執(zhí)行完畢后再繼續(xù)構(gòu)建DOM。

    事實(shí)上,內(nèi)聯(lián)腳本始終會(huì)阻塞解析器,除非你編寫額外的代碼來(lái)延遲它們的執(zhí)行。那通過(guò)<script>引入的外聯(lián)腳本呢?結(jié)果是一樣的,瀏覽器都會(huì)暫停,然后執(zhí)行腳本,腳本執(zhí)行完畢之后再去處理文檔的剩余部分。盡管如此,通過(guò)<script>引入外聯(lián)腳本還是有一個(gè)很大的好處。

    默認(rèn)情況下,所有 JS 均會(huì)阻塞解析器,因?yàn)闉g覽器不知道腳本想在頁(yè)面上做什么,因此它必須假定最糟的情況并阻塞解析器。但是,如果我們能夠有個(gè)信號(hào)告知瀏覽器,說(shuō)腳本無(wú)需在文檔中引用它的確切位置被執(zhí)行呢?這樣一來(lái),瀏覽器就會(huì)繼續(xù)構(gòu)建DOM,并在腳本準(zhǔn)備就緒后執(zhí)行腳本。

    這個(gè)信號(hào)就是async——在script標(biāo)簽里面添加async關(guān)鍵字,其有兩個(gè)特性:

    • 告訴瀏覽器當(dāng)它碰到<script>標(biāo)簽時(shí)不用阻塞DOM構(gòu)建,因此瀏覽器會(huì)忽略腳本請(qǐng)求,繼續(xù)解析DOM
    • JS執(zhí)行不依賴CSSOM:如果在CSSOM就緒之前腳本已經(jīng)就緒,腳本可以立即執(zhí)行
      很顯然,這將會(huì)顯著提升性能!

    分析CRP性能

    先定義三個(gè)用于描述CRP的詞匯:

    • 關(guān)鍵資源:能夠阻止網(wǎng)頁(yè)首次渲染的資源
    • 關(guān)鍵路徑長(zhǎng)度:往返過(guò)程的數(shù)量,或者獲取所有關(guān)鍵資源所需的總時(shí)間
    • 關(guān)鍵字節(jié):網(wǎng)頁(yè)首次渲染所需的總字節(jié)數(shù),是所有關(guān)鍵資源的傳輸文件大小總和

    demo1:

    <html><head><meta name="viewport" content="width=device-width,initial-scale=1"><title>Critical Path: No Style</title></head><body><p>Hello <span>web performance</span> students!</p><div><img src="awesome-photo.jpg"></div></body> </html>

    最簡(jiǎn)單的可用網(wǎng)頁(yè)僅由 HTML 標(biāo)記組成:無(wú) CSS、javascript 或其他類型的資源。要呈現(xiàn)此網(wǎng)頁(yè),瀏覽器必須初始化請(qǐng)求、等待 HTML 文檔準(zhǔn)備就緒、對(duì)其進(jìn)行解析、構(gòu)建 DOM,最后使其呈現(xiàn)在屏幕上。

    • 1個(gè)關(guān)鍵資源
    • 1個(gè)關(guān)鍵路徑長(zhǎng)度(假設(shè)文件很小)
    • 5KB關(guān)鍵字節(jié)
      T0 和 T1 之間的時(shí)間用于捕獲網(wǎng)絡(luò)傳輸和服務(wù)器處理時(shí)間。 在最理想的情況(HTML 文件較小)下,我們僅需一個(gè)網(wǎng)絡(luò)往返過(guò)程即可提取整個(gè)文檔(由于 TCP 傳輸協(xié)議的工作方式,較大的文件可能需要多個(gè)往返過(guò)程)。

    demo2:

    <html><head><meta name="viewport" content="width=device-width,initial-scale=1"><link href="style.css" rel="stylesheet"></head><body><p>Hello <span>web performance</span> students!</p><div><img src="awesome-photo.jpg"></div></body> </html>

    • 2個(gè)關(guān)鍵資源
    • 2個(gè)或更多個(gè)關(guān)鍵路徑長(zhǎng)度
    • 9KB關(guān)鍵字節(jié)

      我們必須同時(shí)使用 HTML 和 CSS 來(lái)構(gòu)建渲染樹,因此 HTML 和 CSS 均為關(guān)鍵資源;瀏覽器需要一個(gè)網(wǎng)絡(luò)往返過(guò)程來(lái)提取 HTML 文檔,然后檢索到的標(biāo)記告知我們還需要 CSS 文件,這意味著,瀏覽器必須返回服務(wù)器并獲取 CSS,然后才能在屏幕上呈現(xiàn)網(wǎng)頁(yè),因此,該網(wǎng)頁(yè)最少需要兩個(gè)往返過(guò)程才能顯示(CSS 文件可能需要多個(gè)往返過(guò)程,重點(diǎn)在’最少’);兩種資源加起來(lái)的關(guān)鍵字節(jié)總量最多為 9 KB。

    demo3:

    <html><head><meta name="viewport" content="width=device-width,initial-scale=1"><link href="style.css" rel="stylesheet"></head><body><p>Hello <span>web performance</span> students!</p><div><img src="awesome-photo.jpg"></div><script src="app.js"></script></body> </html>

    • 3個(gè)關(guān)鍵資源
    • 2個(gè)或更多個(gè)關(guān)鍵路徑長(zhǎng)度
    • 11KB關(guān)鍵字節(jié)

      我們有三個(gè)關(guān)鍵資源,關(guān)鍵字節(jié)總量最多為 11 KB,但是關(guān)鍵路徑長(zhǎng)度仍然是兩個(gè)往返過(guò)程,因?yàn)槲覀兛梢圆⑿袀鬏?CSS 和 JavaScript!

    demo4: 如果app.js中的內(nèi)容不涉及到操作DOM和CSSOM,只是一些分析類型的代碼和其他不需要阻塞頁(yè)面渲染的代碼,則可以在<script>中加入“async”屬性:

    <html><head><meta name="viewport" content="width=device-width,initial-scale=1"><link href="style.css" rel="stylesheet"></head><body><p>Hello <span>web performance</span> students!</p><div><img src="awesome-photo.jpg"></div><script src="app.js" async></script></body> </html>

    異步執(zhí)行腳本有以下幾項(xiàng)優(yōu)勢(shì):

    • 腳本再也不會(huì)阻止解析器,所以也不再是CRP的組成部分
    • 因?yàn)闆](méi)有其他關(guān)鍵腳本,CSS 也不需要阻止DomContentLoaded事件
    • DomContentLoaded事件觸發(fā)得越早,其他應(yīng)用邏輯執(zhí)行的時(shí)間就越早

    因此,經(jīng)過(guò)優(yōu)化的網(wǎng)頁(yè)恢復(fù)到了具有兩個(gè)關(guān)鍵資源(HTML 和 CSS)、具有兩個(gè)往返過(guò)程的最短關(guān)鍵路徑長(zhǎng)度和 9 KB 的關(guān)鍵字節(jié)總量。

    demo5:

    如果CSS樣式表僅適用于打印:

    <html><head><meta name="viewport" content="width=device-width,initial-scale=1"><link href="style.css" rel="stylesheet" media="print"></head><body><p>Hello <span>web performance</span> students!</p><div><img src="awesome-photo.jpg"></div><script src="app.js" async></script></body> </html>

    因?yàn)?style.css 資源僅用于打印,所以只要DOM構(gòu)建完成,瀏覽器就具有了渲染網(wǎng)頁(yè)的足夠信息! 所以,該網(wǎng)頁(yè)僅具有一個(gè)關(guān)鍵資源(HTML),最小關(guān)鍵呈現(xiàn)路徑長(zhǎng)度為一個(gè)往返過(guò)程和5KB的關(guān)鍵字節(jié)。

    優(yōu)化CRP

    常規(guī)步驟:

  • 分析、描述關(guān)鍵路徑:關(guān)鍵資源數(shù)量、字節(jié)數(shù)、關(guān)鍵路徑長(zhǎng)度
  • 最小化關(guān)鍵資源數(shù)量:刪除相應(yīng)資源、延遲下載、標(biāo)記為異步資源等
  • 減少關(guān)鍵字節(jié)數(shù),以減少資源下載時(shí)間(往返次數(shù))
  • 優(yōu)化剩余關(guān)鍵資源的加載順序:盡可能早的下載所有關(guān)鍵資源,以縮短關(guān)鍵路徑長(zhǎng)度
  • 文章轉(zhuǎn)載自https://segmentfault.com/a/1190000008550336

    總結(jié)

    以上是生活随笔為你收集整理的网站性能优化--CRP的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。