瀏覽器如何渲染頁(yè)面刹缝?

1.背景介紹

瀏覽器渲染頁(yè)面的大致過(guò)程:

從瀏覽器地址欄的請(qǐng)求鏈接開(kāi)始,瀏覽器通過(guò)DNS解析查到域名映射的IP地址抱虐,成功之后瀏覽器端向此IP地址取得連接昌阿,成功連接之后,瀏覽器端將請(qǐng)求頭信息 通過(guò)HTTP協(xié)議向此IP地址所在服務(wù)器發(fā)起請(qǐng)求恳邀,服務(wù)器接受到請(qǐng)求之后等待處理懦冰,最后向?yàn)g覽器端發(fā)回響應(yīng),此時(shí)在HTTP協(xié)議下谣沸,瀏覽器從服務(wù)器接收到 text/html類型的代碼刷钢,瀏覽器開(kāi)始顯示此html,并獲取其中內(nèi)嵌資源地址乳附,然后瀏覽器再發(fā)起請(qǐng)求來(lái)獲取這些資源内地,并在瀏覽器的html中顯示

2.知識(shí)剖析

瀏覽器解析的大概的工作流程可以歸納為以下幾個(gè)步驟

1. 用戶輸入網(wǎng)址(假設(shè)是個(gè) HTML 頁(yè)面,第一次訪問(wèn)赋除,無(wú)緩存情況)阱缓,瀏覽器向服務(wù)器發(fā)出HTTP請(qǐng)求,服務(wù)器返回 HTML 文件举农; (善用緩存荆针,減少HTTP請(qǐng)求,減輕服務(wù)器壓力)

2. 瀏覽器載入 HTML 代碼颁糟,發(fā)現(xiàn) head 內(nèi)有一個(gè) link 引用外部 CSS 文件,則瀏覽器立即發(fā)送CSS文件請(qǐng)求航背,獲取瀏覽器返回的CSS文件;? (CSS文件合并棱貌,減少HTTP請(qǐng)求)

3. 瀏覽器繼續(xù)載入 HTML 中 body 部分的代碼玖媚,并且 CSS 文件已經(jīng)拿到手了,可以開(kāi)始渲染頁(yè)面了键畴;CSS文件需要放置最上面最盅,避免網(wǎng)頁(yè)重新渲染。

4. 瀏覽器在代碼中發(fā)現(xiàn)一個(gè) img 標(biāo)簽引用了一張圖片起惕,向服務(wù)器發(fā)出請(qǐng)求涡贱。此時(shí)瀏覽器不會(huì)等到圖片下載完,而是繼續(xù)渲染后面的代碼惹想;(圖片文件合并问词,減少HTTP請(qǐng)求)

5. 服務(wù)器返回圖片文件,由于圖片占用了一定面積嘀粱,影響了后面段落的排布激挪,因此瀏覽器需要回過(guò)頭來(lái)重新渲染這部分代碼;? (最好圖片都設(shè)置尺寸锋叨,避免重新渲染)

6. 瀏覽器發(fā)現(xiàn)了一個(gè)包含一行 JavaScript 代碼的 script? 標(biāo)簽垄分,會(huì)立即運(yùn)行該js代碼;(script最好放置頁(yè)面最下面)

7.js腳本執(zhí)行了語(yǔ)句娃磺,它令瀏覽器隱藏掉代碼中的某個(gè) div,突然就少了一個(gè)元素薄湿,瀏覽器不得不重新渲染這部分代碼;? (頁(yè)面初始化樣式不要使用js控制)

8.終于等到了 /html 的到來(lái)偷卧,瀏覽器淚流滿面……

9. 當(dāng)用戶點(diǎn)了一下界面中的“換膚”按鈕豺瘤,JavaScript 讓瀏覽器換了一下 link 標(biāo)簽的 CSS 路徑;

10. 瀏覽器召集了在座的各位 div span ul li 們听诸,“大伙兒收拾收拾行李坐求,咱得重新來(lái)過(guò)……”,瀏覽器向服務(wù)器請(qǐng)求了新的CSS文件晌梨,重新渲染頁(yè)面桥嗤。

瀏覽器每天就這么來(lái)來(lái)回回跑著,要知道不同的人寫(xiě)出來(lái)的 HTML 和 CSS 代碼質(zhì)量參差不齊仔蝌,說(shuō)不定哪天跑著跑著就掛掉了砸逊。

好在這個(gè)世界還有這么一群人——頁(yè)面重構(gòu)工程師,平時(shí)挺不起眼掌逛,也就幫視覺(jué)設(shè)計(jì)師們切切圖啊改改字师逸,其實(shí)背地里還是干了不少實(shí)事的。

3.常見(jiàn)問(wèn)題

什么是repain(重繪)和reflow(回流)豆混?

4.解決方案

說(shuō)到頁(yè)面為什么會(huì)慢篓像?那是因?yàn)闉g覽器要花時(shí)間、花精力去渲染皿伺,尤其是當(dāng)它發(fā)現(xiàn)某個(gè)部分發(fā)生了點(diǎn)變化影響了布局员辩,需要倒回去重新渲染, 該過(guò)程稱為reflow(回流)鸵鸥。

reflow 幾乎是無(wú)法避免的〉旎現(xiàn)在界面上流行的一些效果丹皱,比如樹(shù)狀目錄的折疊、展開(kāi)(實(shí)質(zhì)上是元素的顯 示與隱藏)等宋税,都將引起瀏覽器的 reflow摊崭。鼠標(biāo)滑過(guò)、點(diǎn)擊……只要這些行為引起了頁(yè)面上某些元素的占位面積杰赛、定位方式呢簸、邊距等屬性的變化,都會(huì)引起它內(nèi)部乏屯、周圍甚至整個(gè)頁(yè)面的重新渲 染根时。通常我們都無(wú)法預(yù)估瀏覽器到底會(huì) reflow 哪一部分的代碼,它們都彼此相互影響著辰晕。

如果只是改變某個(gè)元素的背景色蛤迎、文 字顏色、邊框顏色等等不影響它周圍或內(nèi)部布局的屬性含友,將只會(huì)引起瀏覽器 repaint(重繪)忘苛。

repaint 的速度明顯快于 reflow(在IE下需要換一下說(shuō)法,reflow 要比 repaint 更緩慢)唱较。

為什么reflow 要比 repaint 更緩慢扎唾?

repaint(重繪) ,repaint發(fā)生更改時(shí)南缓,元素的外觀被改變胸遇,且在沒(méi)有改變布局的情況下發(fā)生,如改變outline,visibility,background color汉形,不會(huì)影響到dom結(jié)構(gòu)渲染纸镊。

reflow(回流),與repaint區(qū)別就是他會(huì)影響到dom的結(jié)構(gòu)渲染概疆,同時(shí)他會(huì)觸發(fā)repaint逗威,他會(huì)改變他本身與所有父輩元素(祖先),這種開(kāi)銷是非常昂貴的岔冀,導(dǎo)致性能下降是必然的凯旭,頁(yè)面元素越多效果越明顯。

注意:回流必將引起重繪使套,而重繪不一定會(huì)引起回流罐呼。

5.編碼實(shí)戰(zhàn)

6.擴(kuò)展思考

引起repain(重繪)和reflow(回流)的一些操作?

reflow 的成本比 repaint 的成本高得多的多侦高。DOM Tree 里的每個(gè)結(jié)點(diǎn)都會(huì)有 reflow 方法嫉柴,一個(gè)結(jié)點(diǎn)的 reflow 很有可能導(dǎo)致子結(jié)點(diǎn),甚至父點(diǎn)以及同級(jí)結(jié)點(diǎn)的 reflow奉呛。

當(dāng)你增加计螺、刪除夯尽、修改 DOM 結(jié)點(diǎn)時(shí),會(huì)導(dǎo)致 reflow 或 repaint登馒。

當(dāng)你移動(dòng) DOM 的位置匙握,或是搞個(gè)動(dòng)畫(huà)的時(shí)候。

當(dāng)你修改 /刪除CSS 樣式的時(shí)候谊娇。

當(dāng)你 Resize 窗口的時(shí)候肺孤,或是滾動(dòng)的時(shí)候罗晕。

當(dāng)你修改網(wǎng)頁(yè)的默認(rèn)字體時(shí)济欢。

當(dāng)你設(shè)置 style 屬性的值 (Setting a property of the style attribute)。

注:display:none 會(huì)觸發(fā) reflow小渊,而 visibility:hidden 只會(huì)觸發(fā) repaint法褥,因?yàn)闆](méi)有發(fā)現(xiàn)位置變化。

7.參考文獻(xiàn)

參考一:reflow(回流)和repaint(重繪)及其優(yōu)化

參考二:瀏覽器加載渲染網(wǎng)頁(yè)過(guò)程解析酬屉?

8.更多討論

如何減少repain(重繪)和reflow(回流)半等?

reflow是不可避免的,只能將reflow對(duì)性能的影響減到最小,給出下面幾條建議:

1. 不要一條一條地修改 DOM 的樣式呐萨。通過(guò)設(shè)置style屬性改變結(jié)點(diǎn)樣式的話杀饵,每設(shè)置一次都會(huì)導(dǎo)致一次reflow。所以最好通過(guò)設(shè)置class的方式谬擦,這樣可以將多次改變樣式屬性的操作合并成一次操作切距。

2. 讓要操作的元素進(jìn)行”離線處理”,處理完后一起更新惨远;

- 使用DocumentFragment進(jìn)行緩存操作,引發(fā)一次回流和重繪谜悟;

var fragment = document.createDocumentFragment();

fragment.appendChild(document.createTextNode('keenboy test 111'));

fragment.appendChild(document.createElement('br'));

fragment.appendChild(document.createTextNode('keenboy test 222'));

document.body.appendChild(fragment);

- 使用display:none技術(shù),只引發(fā)兩次回流和重繪;

原理:由于display屬性為none的元素不在渲染樹(shù)中北秽,對(duì)隱藏的元素操 作不會(huì)引發(fā)其他元素的重排葡幸。如果要對(duì)一個(gè)元素進(jìn)行復(fù)雜的操作時(shí),可以先隱藏它贺氓,操作完成后再顯示蔚叨。這樣只在隱藏和顯示時(shí)觸發(fā)2次重排。

3.設(shè)置元素的position為absolute或fixed辙培;

元素脫離標(biāo)準(zhǔn)文檔流缅叠,也從DOM樹(shù)結(jié)構(gòu)中脫離出來(lái),在需要reflow時(shí)只需要reflow自身與下級(jí)元素虏冻。

4.不要用tables布局肤粱;

tables中某個(gè)元素一旦觸發(fā)reflow就會(huì)導(dǎo)致table里所有的其它元素reflow。在適合用table的場(chǎng)合厨相,可以設(shè)置table-layout為auto或fixed领曼,這樣可以讓table一行一行的渲染鸥鹉,這種做法也是為了限制reflow的影響范圍。

5.避免使用CSS的JavaScript表達(dá)式庶骄,如果css里有expression毁渗,每次都會(huì)重新計(jì)算一遍。

鳴謝

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末单刁,一起剝皮案震驚了整個(gè)濱河市灸异,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌羔飞,老刑警劉巖肺樟,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異逻淌,居然都是意外死亡么伯,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)卡儒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)田柔,“玉大人,你說(shuō)我怎么就攤上這事骨望∮脖” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵擎鸠,是天一觀的道長(zhǎng)缀磕。 經(jīng)常有香客問(wèn)我,道長(zhǎng)糠亩,這世上最難降的妖魔是什么虐骑? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮赎线,結(jié)果婚禮上廷没,老公的妹妹穿的比我還像新娘。我一直安慰自己垂寥,他們只是感情好颠黎,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著滞项,像睡著了一般狭归。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上文判,一...
    開(kāi)封第一講書(shū)人閱讀 51,631評(píng)論 1 305
  • 那天过椎,我揣著相機(jī)與錄音,去河邊找鬼戏仓。 笑死疚宇,一個(gè)胖子當(dāng)著我的面吹牛亡鼠,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播敷待,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼间涵,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了榜揖?” 一聲冷哼從身側(cè)響起勾哩,我...
    開(kāi)封第一講書(shū)人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎举哟,沒(méi)想到半個(gè)月后思劳,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡炎滞,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年敢艰,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了诬乞。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片册赛。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖震嫉,靈堂內(nèi)的尸體忽然破棺而出森瘪,到底是詐尸還是另有隱情,我是刑警寧澤票堵,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布扼睬,位于F島的核電站,受9級(jí)特大地震影響悴势,放射性物質(zhì)發(fā)生泄漏窗宇。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一特纤、第九天 我趴在偏房一處隱蔽的房頂上張望军俊。 院中可真熱鬧,春花似錦捧存、人聲如沸粪躬。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)镰官。三九已至,卻和暖如春吗货,著一層夾襖步出監(jiān)牢的瞬間泳唠,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工宙搬, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留笨腥,地道東北人孙援。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像扇雕,于是被迫代替她去往敵國(guó)和親拓售。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

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