瀏覽器渲染流程及其性能優(yōu)化分析

渲染流程

一個(gè)頁面呈現(xiàn)通過瀏覽器呈現(xiàn)到出來女坑,會(huì)經(jīng)過以下步驟

webkitflow.png
  1. 解析頁面內(nèi)容
  2. 構(gòu)建DOM樹
  3. 構(gòu)建CSSOM樹
  4. 合并DOM樹和CSSOM樹填具,生成Render-Tree(渲染樹)
  5. 基于當(dāng)前的viewport計(jì)算出每個(gè)元素的位置和尺寸等幾何信息(Layout)
  6. 將元素信息轉(zhuǎn)換成屏幕上的像素(Painting)
  7. 顯示(Display)

構(gòu)建DOM樹

DOM樹是對html文檔結(jié)構(gòu)的描述,它存儲(chǔ)了html文檔標(biāo)簽的屬性和關(guān)系匆骗,每一個(gè)html標(biāo)簽都會(huì)存在一個(gè)對應(yīng)的DOM元素劳景,元素的嵌套層級(jí)決定了他們的上下層關(guān)系,最終所有DOM元素會(huì)構(gòu)成一顆DOM樹碉就。

以下是一個(gè)簡單的html頁面:

<!DOCTYPE html>
<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òu)造過程如下:

full-process.png
  1. 編碼:瀏覽器處理接收到的HTML原始字節(jié)數(shù)據(jù)盟广,根據(jù)指定的編碼將字節(jié)轉(zhuǎn)換成字符(Bytes —> Characters)。
  2. 提取標(biāo)簽:瀏覽器根據(jù)W3C HTML5 標(biāo)準(zhǔn)從第一步中得到的字符串中提取出各種html標(biāo)簽瓮钥,例如筋量,“<html>”、“<body>”碉熄,以及其他尖括號(hào)內(nèi)的字符串桨武。每個(gè)令牌都具有特殊含義和一組規(guī)則(Characters —> Tokens)。
  3. 詞法分析: 根據(jù)第二部中得到的標(biāo)簽锈津,根據(jù)html元素的語言玻募、規(guī)則、屬性一姿,將其轉(zhuǎn)換成一個(gè)個(gè)元素對象七咧。
  4. DOM構(gòu)建: 步驟三中創(chuàng)建的每一個(gè)對象都會(huì)鏈接在一個(gè)數(shù)據(jù)結(jié)構(gòu)內(nèi),該結(jié)構(gòu)會(huì)捕獲原始標(biāo)記中定義的父項(xiàng)-子項(xiàng)關(guān)系叮叹,如:HTML 對象是 body 對象的父項(xiàng)艾栋,bodyparagraph 對象的父項(xiàng),依此類推蛉顽。利用鏈接結(jié)構(gòu)蝗砾,構(gòu)建出DOM樹

CSSOM樹

CSS定義了html文檔可以應(yīng)用的樣式表,CSSOM樹存儲(chǔ)了CSS的對象模型結(jié)構(gòu)携冤。在瀏覽器為頁面的html元素計(jì)算樣式時(shí)悼粮,可以通過遍歷CSSOM來查找匹配的樣式表。

以以下CSS為例:

body { font-size: 16px }
p { font-weight: bold }
span { color: red }
p span { display: none }
img { float: right }

CSSOM樹產(chǎn)生的過程與DOM樹的構(gòu)建過程類似曾棕,具體如下:

cssom-construction.png

瀏覽器會(huì)根據(jù)CSS的語法標(biāo)準(zhǔn)扣猫,解析CSS文件,并生成相應(yīng)的對象翘地,最后構(gòu)成CSSOM樹申尤,上面的CSS最終構(gòu)成的CSSOM樹如下:

cssom-tree.png

body是所有顯示元素的根節(jié)點(diǎn),它定義了font-size:16px衙耕,由于所有的元素都是body的子項(xiàng)昧穿,所以他們會(huì)繼承body的樣式(CSS的級(jí)聯(lián)規(guī)則)。

注意:

以上樹并非完整的 CSSOM 樹橙喘,它只顯示了我們決定在樣式表中替換的樣式时鸵。每個(gè)瀏覽器都提供一組默認(rèn)樣式(也稱為“User Agent 樣式”),即我們不提供任何自定義樣式時(shí)所看到的樣式厅瞎,我們的樣式只是替換這些默認(rèn)樣式(例如默認(rèn) IE 樣式)饰潜。

構(gòu)建渲染樹

渲染樹通過合并DOM和CSSOM得到,它只包含渲染網(wǎng)頁所需的(需要顯示的)節(jié)點(diǎn)磁奖,以上面的DOM樹和CSSOM樹為例囊拜,他們合并后如下:

render-tree-construction.png

具體步驟如下:

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

    • 某些節(jié)點(diǎn)不可見(例如腳本標(biāo)記比搭、元標(biāo)記等)冠跷,因?yàn)樗鼈儾粫?huì)體現(xiàn)在渲染輸出中,所以會(huì)被忽略身诺。
  2. 對于每個(gè)可見節(jié)點(diǎn)蜜托,為其找到適配的 CSSOM 規(guī)則并應(yīng)用它們。

    • 如果一個(gè)DOM節(jié)點(diǎn)通過 CSS進(jìn)行了隱藏霉赡,那么它在渲染樹中也會(huì)被忽略橄务,例如,上例中的p標(biāo)簽下的span 節(jié)點(diǎn)就不會(huì)出現(xiàn)在渲染樹中穴亏,因?yàn)橛幸粋€(gè)顯式規(guī)則在該節(jié)點(diǎn)上設(shè)置了“display: none”屬性(visible屬性不會(huì))

    Note: visibility: hiddendisplay: none 是不一樣的蜂挪。前者隱藏元素重挑,但元素仍占據(jù)著布局空間(即將其渲染成一個(gè)空框),而后者 (display: none) 將元素從渲染樹中完全移除棠涮,元素既不可見谬哀,也不是布局的組成部分。

  3. 生成渲染樹严肪,得到最終要顯示的所有元素和它的樣式史煎。

注意:

只有同時(shí)具有 DOM 和 CSSOM 才能開始構(gòu)建渲染樹

布局

布局階段會(huì)根據(jù)渲染樹中得到的元素及其樣式信息去計(jì)算元素在當(dāng)前設(shè)備上的具體的大小、位置驳糯,所有相對測量值都轉(zhuǎn)換為屏幕上的絕對像素篇梭。

以下面的代碼為例:

<!DOCTYPE html>
<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>

head中的meta標(biāo)簽聲明了當(dāng)前頁面的寬度應(yīng)該與設(shè)備寬度相等width=device-width,不進(jìn)行縮放initial-scal=1. Body 下的第一個(gè)div采用默認(rèn)布局酝枢,它的寬度為其父容器的50%恬偷,它下面的div同樣采用默認(rèn)布局,寬度又為它父親節(jié)點(diǎn)的50%隧枫。

假如當(dāng)前設(shè)備的寬度為320px喉磁,則第一個(gè)div的寬度就是160px,第二個(gè)div的寬度就是80px官脓,最終效果如下

layout-viewport.png

繪制

在這個(gè)階段协怒,瀏覽器會(huì)根據(jù)在Layout階段計(jì)算出的所有節(jié)點(diǎn)的幾何信息(大小、位置)卑笨,將其繪制到屏幕孕暇。

至此,頁面已經(jīng)可以在屏幕顯示出來赤兴。

DOM & CSSOM & JS

  • 瀏覽器將不會(huì)渲染任何已處理的內(nèi)容妖滔,直至 CSSOM 構(gòu)建完畢

  • 同時(shí)具有 DOM 和 CSSOM 才能構(gòu)建渲染樹

  • 當(dāng)瀏覽器遇到一個(gè) script 標(biāo)記時(shí),DOM 構(gòu)建將暫停桶良,直至腳本完成執(zhí)行

  • 如果瀏覽器尚未完成 CSSOM 的下載和構(gòu)建座舍,此時(shí)有Javscript腳本需要運(yùn)行,瀏覽器將延遲腳本執(zhí)行和 DOM 構(gòu)建陨帆,直至其完成 CSSOM 的下載和構(gòu)建

  • 圖像不會(huì)阻止頁面的首次渲染

下面是一個(gè)具體的例子:

1# <!DOCTYPE html>
2# <html>
3#   <head>
4#     <meta name="viewport" content="width=device-width,initial-scale=1">
5#     <link href="style.css" rel="stylesheet">
6#     <title>Critical Path: Script External</title>
7#   </head>
8#   <body>
9#     <p>Hello <span>web performance</span> students!</p>
10#    <div><img src="awesome-photo.jpg"></div>
11#    <script src="app.js"></script>
12#   </body>
13# </html>

在這個(gè)例子中曲秉,整個(gè)頁面的加載流程如下:

  1. 瀏覽器解析html文檔(編碼—>提取標(biāo)簽—>詞法分析)
  2. 然后開始構(gòu)建DOM
  3. 第5行,發(fā)現(xiàn)link標(biāo)簽疲牵,開始加載CSS文件并創(chuàng)建CSSOM
  4. 第11行承二,發(fā)現(xiàn)script標(biāo)簽,開始加載外部腳本纲爸,阻塞DOM的構(gòu)建
  5. 腳本加載完畢亥鸠,開始執(zhí)行腳本,此時(shí)如果
    1. CSSOM已經(jīng)構(gòu)建完畢识啦,則直接執(zhí)行腳本
    2. CSSOM并沒有構(gòu)建完畢负蚊,則等待CSSOM構(gòu)建完畢神妹,然后執(zhí)行腳本
  6. 腳本執(zhí)行完畢,繼續(xù)DOM構(gòu)建
  7. 利用構(gòu)建好的DOM+CSSOM盖桥,穿件渲染樹
  8. 繪制并顯示

渲染過程性能優(yōu)化

優(yōu)化關(guān)鍵渲染路徑

關(guān)鍵渲染路徑指的是 HTML 標(biāo)記灾螃、CSS 和 JavaScript,圖像不會(huì)阻止頁面的首次渲染揩徊。通過優(yōu)化關(guān)鍵渲染路徑,可以縮短首次渲染頁面的時(shí)間嵌赠。

可以通過以下維度進(jìn)行優(yōu)化:

  1. 減少資源數(shù)量塑荒、字節(jié)大小。

    如通過壓縮css和js文件來減小他們的字節(jié)數(shù)姜挺,通過合并文件來減少http請求的數(shù)量齿税,以此來提高資源加載的速度

  2. 盡早加載CSS資源

    由于CSSOM會(huì)阻塞渲染,只有DOM和CSSOM加載完畢后渲染才開始執(zhí)行炊豪,因此應(yīng)該盡量早的加載CSS資源

  3. 利用media屬性聲明CSS的使用場景

    <link href="style.css" rel="stylesheet" media="orientation:landscape">
    

    上面的例子中凌箕,聲明了media的值為orientation:portrait,則這個(gè)style.css文件只有在橫屏狀況下才會(huì)使用,其他狀況都不會(huì)阻塞渲染词渤。

    關(guān)于media的更多資料牵舱,可以查看這里

  4. 將腳本標(biāo)記為異步

    默認(rèn)情況下,所有 JavaScript 都會(huì)阻止解析器缺虐,向 script 標(biāo)記添加異步關(guān)鍵字可以指示瀏覽器在等待腳本加載期間不阻止 DOM 構(gòu)建芜壁,如下

    <script src="app.js" async></script>
    

提升交互性能

交互或者動(dòng)畫都會(huì)出發(fā)頁面的重繪,他會(huì)影響用戶的操作流暢性體驗(yàn)高氮。當(dāng)前主流的設(shè)備的幀率都是60fps慧妄,因此網(wǎng)頁應(yīng)用渲染完一幀的速率就應(yīng)該低于16ms這樣才不會(huì)掉幀。在這16ms中剪芍,瀏覽器需要完成以下工作:

frame-full.jpg

執(zhí)行JavaScript腳本(增刪改dom或style) -> 計(jì)算節(jié)點(diǎn)樣式 -> 計(jì)算節(jié)點(diǎn)的集合信息(位置塞淹、大小) -> 像素填充 -> 圖層合并?

Javascript和CSS是由開發(fā)者提供的,其他步驟都完全由瀏覽器控制罪裹,因此饱普,我們的腳本的處理時(shí)間應(yīng)該低于16ms才能保證頁面的重繪在16ms內(nèi)完成,一般來說坊谁,留給JavaScript執(zhí)行的時(shí)間大概在10ms左右费彼。

使用 requestAnimationFrame 來實(shí)現(xiàn)視覺變化

JavaScript執(zhí)行的最佳時(shí)機(jī)是在屏幕開始繪制新一幀的開頭。 requestAnimationFrame接受一個(gè)函數(shù)口芍,并保證該函數(shù)在新的一幀的開頭被調(diào)用箍铲,我們可以使用這個(gè)方法來處理動(dòng)畫。下面是一個(gè)小的示例:

var start = null;
var element = document.getElementById('SomeElementYouWantToAnimate');
element.style.position = 'absolute';

function move(timestamp) {
  if (!start) start = timestamp;
  var progress = timestamp - start;
  element.style.left = Math.min(progress / 10, 200) + 'px';
  if (progress < 2000) {
    window.requestAnimationFrame(move);
  }
}

window.requestAnimationFrame(move);

不推薦使用 setTimeoutsetInterval 來執(zhí)行動(dòng)畫之類的視覺變化的原因在于鬓椭,回調(diào)將在幀中的某個(gè)時(shí)點(diǎn)運(yùn)行颠猴,可能剛好在末尾关划,而這可能經(jīng)常會(huì)使我們丟失幀,導(dǎo)致卡頓翘瓮。

settimeout.png

減少/避免布局操作

當(dāng)元素的“l(fā)ayout”屬性發(fā)生了改變贮折,也就是改變了元素的幾何屬性(例如寬度、高度资盅、左側(cè)或頂部位置等)调榄,那么瀏覽器將必須檢查所有其他元素,然后“自動(dòng)重排”頁面呵扛。任何受影響的部分都需要重新繪制每庆,而且最終繪制的元素需進(jìn)行合成。

常見的幾何屬性有:

bottom, direction,display,float,font-size,font-weight,height,left,margin,padding,position,right,top,width...

可以通過https://csstriggers.com/查看更多信息今穿。

避免強(qiáng)制同步布局

正常的頁面更新流程是JavaScript 運(yùn)行 -> 計(jì)算樣式 -> 布局, 但是在以下場景缤灵,JavaScript會(huì)強(qiáng)制瀏覽器提前進(jìn)行布局:

var box = document.getElementById("example-dom");
box.classList.add('fiori');         //修改樣式
console.log(box.offsetHeight);      //讀取高度

在給box節(jié)點(diǎn)添加新的樣式ful-screen之前,自上一幀的所有舊布局值是已知的蓝晒,瀏覽器為了優(yōu)化性能腮出,會(huì)將更新操作暫緩到隊(duì)列批量處理;但是芝薇,程序立馬請求查看節(jié)點(diǎn)的高度box.offsetHeight胚嘲,為了獲取準(zhǔn)確的數(shù)據(jù),瀏覽器必須立刻應(yīng)用樣式更改剩燥,然后運(yùn)行布局慢逾,這是不必要的,如果有大量的這種操作(處理動(dòng)畫時(shí)灭红,往往會(huì)不停的修改樣式侣滩,應(yīng)該避免寫與讀操作相間觸發(fā)),將會(huì)帶來巨大的開銷变擒。

正確的做法是應(yīng)該先獲取高度君珠,然后再進(jìn)行樣式的更改

var box = document.getElementById("example-dom");
console.log(box.offsetHeight);      //讀取高度
box.classList.add('fiori');         //修改樣式

反例:

for(var i=0;i<p.length;i++){
  p[i].style.width = d.offsetWidth + 'px'; //獲取d的寬度并賦值給p[i]
}

正例:

var w = d.offsetWidth; // 提前獲取好d的寬度
for(var i=0;i<p.length;i++){
  p[i].style.width = w + 'px'; //通過變量w給p[i]賦值,循環(huán)中只有寫操作娇斑,不會(huì)強(qiáng)制同步布局
}

后臺(tái)運(yùn)行復(fù)雜/耗時(shí)邏輯

JavaScript 在瀏覽器的主線程上運(yùn)行策添,恰好與樣式計(jì)算、布局以及許多情況下的繪制一起運(yùn)行毫缆。如果 JavaScript 運(yùn)行時(shí)間過長唯竹,就會(huì)阻塞這些其他工作,可能導(dǎo)致幀丟失苦丁。對于一些計(jì)算密集的操作浸颓,建議使用web worker進(jìn)行處理,不要占用瀏覽器的主進(jìn)程

減少繪制區(qū)域

繪制并非總是繪制到內(nèi)存中的單個(gè)圖像。事實(shí)上产上,在必要時(shí)瀏覽器可以繪制到多個(gè)圖像或合成器層棵磷,類似于Photoshop圖層的概念,我們可以創(chuàng)建不同的圖層繪制圖像晋涣,最后將他們合并仪媒。

利用這個(gè)特性,可以將經(jīng)常需要重繪的部分單獨(dú)放在一個(gè)圖層谢鹊,避免整個(gè)頁面收到影響算吩。

使用 will-change CSS 屬性可以為元素創(chuàng)建一個(gè)新的圖層, will-change 為web開發(fā)者提供了一種告知瀏覽器該元素會(huì)有哪些變化的方法撇贺,這樣瀏覽器可以在元素屬性真正發(fā)生變化之前提前做好對應(yīng)的優(yōu)化準(zhǔn)備工作赌莺。

.moving-element {
  will-change: transform;
}

注意:

不要?jiǎng)?chuàng)建太多圖層,因?yàn)槊繉佣夹枰獌?nèi)存和管理開銷松嘶。

其他

  • 不要使用過于復(fù)雜的css選擇器
  • 精簡DOM節(jié)點(diǎn)數(shù)量

工具

性能監(jiān)控工具

  • Chrome DevTool(強(qiáng)力推薦,以后有機(jī)會(huì)會(huì)單獨(dú)介紹)
  • Lighthouse

參考文獻(xiàn)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末挎扰,一起剝皮案震驚了整個(gè)濱河市翠订,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌遵倦,老刑警劉巖尽超,帶你破解...
    沈念sama閱讀 218,640評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異梧躺,居然都是意外死亡似谁,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,254評論 3 395
  • 文/潘曉璐 我一進(jìn)店門掠哥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來巩踏,“玉大人,你說我怎么就攤上這事续搀∪恚” “怎么了?”我有些...
    開封第一講書人閱讀 165,011評論 0 355
  • 文/不壞的土叔 我叫張陵禁舷,是天一觀的道長彪杉。 經(jīng)常有香客問我,道長牵咙,這世上最難降的妖魔是什么派近? 我笑而不...
    開封第一講書人閱讀 58,755評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮洁桌,結(jié)果婚禮上渴丸,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好曙强,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,774評論 6 392
  • 文/花漫 我一把揭開白布残拐。 她就那樣靜靜地躺著,像睡著了一般碟嘴。 火紅的嫁衣襯著肌膚如雪溪食。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,610評論 1 305
  • 那天娜扇,我揣著相機(jī)與錄音错沃,去河邊找鬼。 笑死雀瓢,一個(gè)胖子當(dāng)著我的面吹牛枢析,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播刃麸,決...
    沈念sama閱讀 40,352評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼醒叁,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了泊业?” 一聲冷哼從身側(cè)響起把沼,我...
    開封第一講書人閱讀 39,257評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎吁伺,沒想到半個(gè)月后饮睬,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,717評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡篮奄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,894評論 3 336
  • 正文 我和宋清朗相戀三年捆愁,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片窟却。...
    茶點(diǎn)故事閱讀 40,021評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡昼丑,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出间校,到底是詐尸還是另有隱情矾克,我是刑警寧澤,帶...
    沈念sama閱讀 35,735評論 5 346
  • 正文 年R本政府宣布憔足,位于F島的核電站胁附,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏滓彰。R本人自食惡果不足惜控妻,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,354評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望揭绑。 院中可真熱鬧弓候,春花似錦郎哭、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,936評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至依鸥,卻和暖如春亥至,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背贱迟。 一陣腳步聲響...
    開封第一講書人閱讀 33,054評論 1 270
  • 我被黑心中介騙來泰國打工姐扮, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人衣吠。 一個(gè)月前我還...
    沈念sama閱讀 48,224評論 3 371
  • 正文 我出身青樓茶敏,卻偏偏與公主長得像,于是被迫代替她去往敵國和親缚俏。 傳聞我的和親對象是個(gè)殘疾皇子惊搏,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,974評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 大家都知道萬維網(wǎng)的應(yīng)用層使用了HTTP協(xié)議,并且用瀏覽器作為入口訪問網(wǎng)絡(luò)上的資源忧换。用戶在使用瀏覽器訪問一個(gè)網(wǎng)站時(shí)需...
    SylvanasSun閱讀 2,149評論 1 12
  • 發(fā)送 & 接收信息 數(shù)據(jù)是以“數(shù)據(jù)包”的形式通過互聯(lián)網(wǎng)發(fā)送胀屿,而數(shù)據(jù)包以字節(jié)為單位。當(dāng)你編寫一些 HTML包雀、CSS ...
    mongofeng閱讀 917評論 0 0
  • 發(fā)送 & 接收信息 數(shù)據(jù)是以“數(shù)據(jù)包”的形式通過互聯(lián)網(wǎng)發(fā)送,而數(shù)據(jù)包以字節(jié)為單位亲铡。當(dāng)你編寫一些 HTML才写、CSS ...
    IT界中小PQ閱讀 406評論 0 0
  • 用戶在使用瀏覽器訪問一個(gè)網(wǎng)站時(shí)需要先通過HTTP協(xié)議向服務(wù)器發(fā)送請求,之后服務(wù)器返回HTML文件與響應(yīng)信息奖蔓。這時(shí)赞草,...
    dosher_多舍閱讀 852評論 0 1
  • 背景(做前端永遠(yuǎn)也跨不過去了就是性能優(yōu)化) 公司目前有大量前后端耦合項(xiàng)目,瀏覽器的首屏加載速度非常的慢吆鹤,在不段優(yōu)化...
    天一呀閱讀 1,156評論 0 4