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