大家好裆熙,歡迎來到小強(qiáng)流浪記端礼!
今天和大家聊聊瀏覽器的“重繪”和“回流”,為什么瀏覽器會(huì)產(chǎn)生重繪和回流呢弛车?一直在想如何引出這個(gè)話題齐媒。大家知道我們輸入一個(gè)網(wǎng)址到頁面展示整個(gè)過程嗎蒲每?
1纷跛、客戶端(瀏覽器)從DNS【域名系統(tǒng),它作為將域名和IP地址相互映射的一個(gè)分布式數(shù)據(jù)庫邀杏,能夠使人更方便地訪問互聯(lián)網(wǎng)】服務(wù)器得到域名的IP地址
2贫奠、拿到IP地址后,客戶端就向這個(gè)IP的地址發(fā)送http請(qǐng)求 (這里設(shè)涉及tcp的三次握手【建立連接】和四次揮手【關(guān)閉連接】)
3望蜡、服務(wù)器收到請(qǐng)求唤崭、處理并返回http請(qǐng)求
4、客戶端就得到返回的內(nèi)容
5脖律、客戶端得到內(nèi)容谢肾,就得解析和渲染頁面 ,下面是瀏覽器渲染頁面的過程
6小泉、根據(jù)HTML結(jié)構(gòu)生成DOM Tree
7芦疏、根據(jù)CSS生成CSSOM(CSS Object Model CSS對(duì)象模型)
8冕杠、然后 根據(jù)DOM樹和和CSSOM來整合形成Render Tree(渲染樹 此時(shí)就是帶有樣式的DOM Tree)[遇到<script>時(shí),執(zhí)行會(huì)阻塞渲染 因?yàn)镴S有權(quán)利改變DOM結(jié)構(gòu)]酸茴,有了Render Tree分预,瀏覽器已經(jīng)能知道網(wǎng)頁中有哪些節(jié)點(diǎn)、各個(gè)節(jié)點(diǎn)的CSS定義以及他們的從屬關(guān)系
9薪捍、然后就是Layout(譯):布局笼痹、布置、設(shè)計(jì)酪穿、安排)凳干,顧名思義就是計(jì)算出每個(gè)節(jié)點(diǎn)的幾何位置;
10被济、然后就是Paint(譯:繪制)纺座,即遍歷render樹,并使用瀏覽器UI后端層繪制每個(gè)可見節(jié)點(diǎn)溉潭。(此時(shí)就得引出性能優(yōu)化中的:"回流" 和 "重繪"兩個(gè)概念了)
11净响、最后一步Display: 將像素發(fā)送給GPU, 展示在頁面上喳瓣。
PS: 不可見節(jié)點(diǎn)包括:一些不會(huì)渲染輸出的節(jié)點(diǎn)坪稽,比如script、meta贸典、link等底循;一些通過css進(jìn)行隱藏的節(jié)點(diǎn)。比如display:none惠毁。注意犹芹,利用visibility和opacity隱藏的節(jié)點(diǎn),還是會(huì)顯示在渲染樹上的鞠绰。
回流:就是layout階段腰埂,計(jì)算每個(gè)節(jié)點(diǎn)的幾何位置,(計(jì)算規(guī)模尺寸蜈膨,布局等)這就稱為 “回流”【每個(gè)頁面至少需要一次回流屿笼,就是在頁面第一次加載的時(shí)候,這時(shí)候是一定會(huì)發(fā)生回流的翁巍,因?yàn)橐獦?gòu)建render tree】(個(gè)人理解)
重繪:然后就是Paint驴一,即 通過回流階段后 瀏覽器知道那些節(jié)點(diǎn)可繪制,并且知道其樣式灶壶,瀏覽器將渲染樹的每個(gè)可見節(jié)點(diǎn)通過GPU(圖形處理器)肝断,繪制在頁面上(個(gè)人理解)。
上面的理解可以得出:回流一定會(huì)觸發(fā)重繪,而重繪不一定會(huì)回流胸懈; 重繪的開銷較小鱼蝉,回流的代價(jià)較高(因?yàn)橐ビ?jì)算)。這就可以從瀏覽器渲染這方面進(jìn)行優(yōu)化性能:即優(yōu)化回流和重繪箫荡,下面是一些優(yōu)化方法魁亦,可以沖JS和CSS兩方面考慮,歡迎補(bǔ)充羔挡。
一: 從JS方面:
1洁奈、使用cssText,去修改html的style 或者修改class(這樣就可以做到一次性去修改);
2绞灼、避免頻繁操作DOM利术, 使用documentFragment
3、不要經(jīng)常訪問會(huì)引起瀏覽器緩存隊(duì)列的屬性(上述那些瀏覽器會(huì)立刻清空隊(duì)列的屬性)低矮。如果確實(shí)要訪問印叁, 利用緩存【因?yàn)楝F(xiàn)代瀏覽器會(huì)對(duì)頻繁的回流和重繪操作優(yōu)化,瀏覽器會(huì)維護(hù)一個(gè)隊(duì)列军掂,把所有引起回流和重繪的操作放入隊(duì)列中轮蜕,如果隊(duì)列中的任務(wù)數(shù)量或者時(shí)間間隔達(dá)到一個(gè)閾值的,瀏覽器就會(huì)將隊(duì)列清空蝗锥,進(jìn)行一次批處理跃洛,這樣可以把多次回流和重繪變成一次】,而頻繁訪問的話,瀏覽器會(huì)立即清空隊(duì)列终议。
4汇竭、對(duì)于復(fù)雜動(dòng)畫效果,使用絕對(duì)定位讓其脫離文檔流,否則會(huì)引起父元素以及后續(xù)元素頻繁的回流
二:從CSS方面:
1穴张、避免使用CSS表達(dá)式(例如calc())
2细燎、避免設(shè)置多層內(nèi)聯(lián)樣式
3、不要用table布局
4皂甘、將動(dòng)畫效果應(yīng)用到position屬性為absolute 或 fixed元素上玻驻。 【脫離文檔流】
5、display:none技術(shù)叮贩,也可以先為元素設(shè)置display: none击狮,操作結(jié)束后再把它顯示出來佛析。因?yàn)樵赿isplay屬性為none的元素上進(jìn)行的DOM操作不會(huì)引發(fā)回流和重繪益老。
參考:https://juejin.im/post/5c3c023b518825251077c679#heading-9