前言
在學(xué)習(xí)前端的過程中,大家都會(huì)對(duì)瀏覽器這個(gè)神秘的盒子感到好奇
從輸入一串url到頁面解析渲染完成,瀏覽器都干了些啥?
為了更好的理解這個(gè)過程,我們使用一個(gè)工具來幫助我們
Chrome自帶的開發(fā)工具中的performance(老版本和其他瀏覽器為timeline)
點(diǎn)擊錄制,然后在地址欄輸入我們的url
這里以百度為例,輸入www.baidu.com,回車
然后點(diǎn)擊錄制結(jié)束,就能看到這個(gè)東西
我們最先看到的是這個(gè)
字面意思就可以理解,瀏覽器在向服務(wù)器發(fā)送請(qǐng)求,并接收響應(yīng)頭和響應(yīng)體
不過實(shí)際上在這之前,瀏覽器還做了一些事
得先知道朝哪個(gè)服務(wù)器發(fā)送請(qǐng)求吧
根據(jù)url,先去本地DNS緩存列表里尋找對(duì)應(yīng)的服務(wù)器的ip地址和端口號(hào),若沒有找到,繼續(xù)尋找系統(tǒng)緩存和路由緩存,若找到則跳轉(zhuǎn)第三步
還沒找到的話則請(qǐng)求本地DNS服務(wù)器,沒有就將域名發(fā)送給其他服務(wù)器,遞歸尋找,從根域名服務(wù)器開始不斷向下遞歸,直到返回對(duì)應(yīng)的IP地址和端口號(hào),并將其緩存
根據(jù)ip地址和端口號(hào),與目標(biāo)服務(wù)器建立TCP連接(三次握手)
這三步并沒有被我們看見,然后接下來的事就被我們觀察到了
瀏覽器向服務(wù)器發(fā)送http請(qǐng)求,并接收返回的響應(yīng)頭和響應(yīng)體
繼續(xù)往下看
黃色部分都是瀏覽器的一些默認(rèn)行為,其中包括隱藏本來的標(biāo)簽頁內(nèi)容等等
以及下面的Recalculate Style(重新計(jì)算樣式),Layout(重排)是為清空本來的頁面,為新頁面做準(zhǔn)備
這些不用管它,不過在這中間我們又一次看到了Receive Data
那是因?yàn)榉?wù)器在發(fā)送數(shù)據(jù)的時(shí)候,可能會(huì)進(jìn)行拆包,分幾次發(fā)送
瀏覽器比較勤快,它并不會(huì)等html完全接收完才開始解析,而是接受一部分就開始解析一部分
HTML Parser的任務(wù)是將HTML標(biāo)記,解析成DOM Tree,這是一個(gè)深度遍歷的過程,只有Dom下的子節(jié)點(diǎn)都被遍歷完成,才遍歷下一個(gè)同級(jí)Dom節(jié)點(diǎn)
同時(shí),在解析的過程中,如果遇到了圖片,link標(biāo)簽,script標(biāo)簽,都會(huì)向服務(wù)器發(fā)送請(qǐng)求
例如我們上圖,遇到了百度的logo圖片,就請(qǐng)求下載
遇到js就立即解析下載執(zhí)行執(zhí)行
不管是內(nèi)聯(lián)的還是外部的,都會(huì)阻塞后續(xù)dom的解析和渲染
所以一般將標(biāo)簽放在后面
如果是外部的,還可以在標(biāo)簽上加上defer或async屬性
defer可以讓js的下載不影響html的后續(xù)解析,且在html解析完了再執(zhí)行js文件,且按照原來的下載順序
async也是讓js的下載不影響html的后續(xù)解析,但一旦下載完了就立即執(zhí)行,因此也無法保證按照下載順序執(zhí)行
遇到內(nèi)聯(lián)的css樣式就開始解析
外部的css文件,則在接收到了之后進(jìn)行解析
兩者都會(huì)不會(huì)阻塞Dom的解析,但會(huì)阻塞Dom的渲染
這也是為什么要把css的標(biāo)簽放進(jìn)中
當(dāng)css文件放在中時(shí),雖然css解析也會(huì)阻塞后續(xù)dom的渲染,但是在解析css的同時(shí)也在解析dom,所以等到css解析完畢就會(huì)逐步的渲染頁面了
把css語句解析成為CSSOM
渲染布局與繪制在有了Dom Tree和CSSOM之后
瀏覽器就會(huì)構(gòu)建Render Tree(渲染樹)
其實(shí)把DOM Tree和CSSOM進(jìn)行附加
所以Render Tree實(shí)際上就是一個(gè)計(jì)算好了樣式,同時(shí)不包含display:none之類,不占據(jù)空間的元素的的渲染樹。
然后瀏覽器就根據(jù)這個(gè)Render Tree進(jìn)行第一次的布局(Layout)以及繪制(Paint)
完成了第一次繪制之后,瀏覽器會(huì)繼續(xù)收到服務(wù)器發(fā)來的數(shù)據(jù)
圖片,css文件,js文件
其中可能會(huì)有導(dǎo)致頁面布局更改或樣式更改的內(nèi)容,都會(huì)添加到我們的Render Tree上去
引起重排(Layout)或重繪(Paint)
其中重排一定會(huì)連帶著引起重繪,反之則不然
重排(Reflow)引起重排的操作
頁面首次渲染
瀏覽器窗口大小發(fā)生改變
元素尺寸或位置發(fā)生改變
元素內(nèi)容變化(文字?jǐn)?shù)量或圖片大小等等)
元素字體大小變化
添加或者刪除可見的DOM元素
激活CSS偽類(例如::hover)
設(shè)置style屬性
那是遇到一次就重排一次嗎?也不是
瀏覽器會(huì)有一個(gè)渲染隊(duì)列來進(jìn)行優(yōu)化
積累了一定量或一定時(shí)間的更改內(nèi)容,才會(huì)進(jìn)行重排
不過當(dāng)訪問了特定屬性的時(shí)候
比如js文件里遇到一句console.log(body.clientWidth)
會(huì)強(qiáng)制刷新渲染隊(duì)列
以下屬性的訪問會(huì)立即刷新渲染隊(duì)列
widthheight | margin | padding | display | border |
position | overflow | clientWidth | clientHeight | clientTop |
clientLeft | offsetWidth | offsetHeight | offsetTop | offsetLeft |
scrollWidth | scrollHeight | scrollTop | scrollLeft | scrollIntoView() |
scrollTo() | getComputedStyle() | getBoundingClientRect() | scrollIntoViewIfNeeded() |
所以訪問這些屬性要謹(jǐn)慎,最好分離讀寫,以免過多的重排影響性能
重繪引起重繪的一般都是修改元素的屬性
color | border-style | visibility | background |
text-decoration | background-image | background-position | background-repeat |
outline-color | outline | outline-style | border-radius |
outline-width | box-shadow | background-size |
從性能優(yōu)化的角度,我們要盡量減少瀏覽器的重排和重繪,尤其是重排
盡量不要在布局信息改變時(shí)做查詢(會(huì)導(dǎo)致渲染隊(duì)列強(qiáng)制刷新)
減少DOM操作,同一個(gè)DOM的多個(gè)屬性改變可以寫在一起,在一個(gè)局部方法中需要多次訪問同一個(gè)Dom,則先暫存它的引用。批量添加DOM,可以先讓元素脫離文檔流,操作完后再帶入文檔流,這樣只會(huì)觸發(fā)一次重排(應(yīng)用fragment元素)
將需要多次重排的元素,position屬性設(shè)為absolute或fixed,例如有動(dòng)畫效果的元素
采用更優(yōu)的API替代消費(fèi)高的API,轉(zhuǎn)換優(yōu)化消費(fèi)高的集合,如用querySelectorAll()替代getElementByXX()。
開啟動(dòng)畫的GPU加速
少用HTML集合(類數(shù)組)來遍歷,因?yàn)榧媳闅v比真數(shù)組遍歷耗費(fèi)更高。
用事件委托來減少事件處理器的數(shù)量。
避免設(shè)置大量的style屬性,因?yàn)橥ㄟ^每一次設(shè)置都會(huì)觸發(fā)一次reflow,所以最好是使用class屬性
動(dòng)畫實(shí)現(xiàn)的速度太精細(xì)平滑,會(huì)導(dǎo)致reflow過于頻繁
不要使用table布局,因?yàn)?b>table中某個(gè)元素旦觸發(fā)了reflow,那么整個(gè)表格都會(huì)reflow??梢栽O(shè)置table-layout:auto;或者是table-layout:fixed這樣可以只reflow一行,
減少通過JavaScript代碼修改元素樣式,盡量使用修改class名方式操作樣式或動(dòng)畫;
隱藏在屏幕外,或在頁面滾動(dòng)時(shí),盡量停止動(dòng)畫;
最后大家可以自己去嘗試一下performance的使用,可以更直觀的理解瀏覽器的工作流程
參考文章https://segmentfault.com/a/11...
https://segmentfault.com/a/11...
https://sylvanassun.github.io...
https://www.imooc.com/article...
https://segmentfault.com/a/11...
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/114633.html
前言 在學(xué)習(xí)前端的過程中,大家都會(huì)對(duì)瀏覽器這個(gè)神秘的盒子感到好奇從輸入一串url到頁面解析渲染完成,瀏覽器都干了些啥? 直觀展示 為了更好的理解這個(gè)過程,我們使用一個(gè)工具來幫助我們Chrome自帶的開發(fā)工具中的performance(老版本和其他瀏覽器為timeline) showImg(https://segmentfault.com/img/bVbswbe?w=1338&h=920); 點(diǎn)擊錄...
前言 在學(xué)習(xí)前端的過程中,大家都會(huì)對(duì)瀏覽器這個(gè)神秘的盒子感到好奇從輸入一串url到頁面解析渲染完成,瀏覽器都干了些啥? 直觀展示 為了更好的理解這個(gè)過程,我們使用一個(gè)工具來幫助我們Chrome自帶的開發(fā)工具中的performance(老版本和其他瀏覽器為timeline) showImg(https://segmentfault.com/img/bVbswbe?w=1338&h=920); 點(diǎn)擊錄...
摘要:需要注意的一點(diǎn)是,面板下的功能,是對(duì)于細(xì)節(jié)中的細(xì)節(jié)進(jìn)行的優(yōu)化。我們可以很清晰明了得分析按照活動(dòng),目錄,域,子域,和進(jìn)行分組的前端性能。個(gè)人理解的話,前者類似事件冒泡,后者類似事件捕獲。同學(xué)在點(diǎn)我達(dá),他們正在籌劃改組成大前端團(tuán)隊(duì)。 對(duì)Chrome控制臺(tái)有一定的了解的朋友都在知道,Network面板會(huì)包括很多網(wǎng)絡(luò)請(qǐng)求方面的東西,包括Http相關(guān)的Request信息,Response信息...
摘要:但硬件加速是把雙刃劍,過渡的使用硬件加速會(huì)適得其反。所以,一定要牢記不要讓頁面的每個(gè)元素都使用硬件加速,當(dāng)且僅當(dāng)需要的時(shí)候才為元素創(chuàng)建渲染層。參考文檔無線性能優(yōu)化動(dòng)畫及硬件加速高性能動(dòng)畫與頁面渲染渲染優(yōu)化層模型 前言 談起瀏覽器的硬件加速,想必大家都知道的一個(gè)技巧就是在用CSS3做動(dòng)畫時(shí),給元素添加transform: translateZ(0)或者transform: transla...
摘要:但硬件加速是把雙刃劍,過渡的使用硬件加速會(huì)適得其反。所以,一定要牢記不要讓頁面的每個(gè)元素都使用硬件加速,當(dāng)且僅當(dāng)需要的時(shí)候才為元素創(chuàng)建渲染層。參考文檔無線性能優(yōu)化動(dòng)畫及硬件加速高性能動(dòng)畫與頁面渲染渲染優(yōu)化層模型 前言 談起瀏覽器的硬件加速,想必大家都知道的一個(gè)技巧就是在用CSS3做動(dòng)畫時(shí),給元素添加transform: translateZ(0)或者transform: transla...
閱讀 1352·2021-11-24 09:39
閱讀 2931·2021-09-30 09:47
閱讀 1415·2021-09-22 15:15
閱讀 2501·2021-09-10 10:51
閱讀 2035·2019-08-30 15:55
閱讀 3034·2019-08-30 11:06
閱讀 947·2019-08-30 10:53
閱讀 953·2019-08-29 17:26