影響前端性能的本源——Reflow和Repaint

自從移動客戶端飛速發(fā)展開始俭缓,前端工程師們也面臨了一個非常重要的歷史轉(zhuǎn)折點。真是可以用一個短語來表示谆膳,風(fēng)口上的豬。各種地方都在招聘前端工程師撮躁,工資動輒八千一萬的摹量。我們的春天來了……不過春天過后還是會有冬天……


風(fēng)口的豬

在移動端的web開發(fā)工作中,經(jīng)常遭遇到的問題就是客戶反映,打開速度慢缨称,這個說專業(yè)點就是性能變差凝果。當(dāng)接到這種投訴的時候自己心中也是一臉懵逼,在開發(fā)環(huán)境中測試的好好睦尽,怎么正式運行之后就慢了器净。心里雖然在考慮現(xiàn)象的真實原因,但在嘴上估計很多人第一時間就回答給客戶是網(wǎng)速的問題而非自己程序的問題当凡。

開銷過大占用過多的計算資源就會導(dǎo)致性能問題山害,它出現(xiàn)的因素有很多,后端接口速度過慢沿量,網(wǎng)速狀態(tài)差……這些問題都是客觀存在浪慌,不能否認不能回避也不能控制。那么前端工作中就沒有影響性能問題的存在么朴则?回答是肯定的权纤。

瀏覽器是連接訪問者和web頁面的“橋梁”,瀏覽器渲染解析的效率就是決定頁面“呈現(xiàn)出來”速度的關(guān)鍵因素乌妒,瀏覽器的渲染解析又會受到頁面代碼質(zhì)量的影響汹想。這一大圈又把責(zé)任饒到了我們自己身上,沒關(guān)系撤蚊,有責(zé)任也不會有人來追究的古掏,我們需要的只是正視自己的工作。雖然我們嘴上可以把責(zé)任推給那些我們不能控制的因素侦啸,但是我們內(nèi)心一定要認清楚槽唾,我們的工作對性能問題也是有影響的。

筆鋒一轉(zhuǎn)光涂,我們再回來繼續(xù)庞萍。我們都知道瀏覽器的對待頁面的“姿勢”是先布局后渲染。//布局的時間略微提前于渲染顶捷。瀏覽器在對頁面經(jīng)行布局和渲染的時候挂绰,就會面對兩個很“矯情”的厲害家伙——ReflowRepaint。大神們對這倆貨肯定不陌生了服赎,我們這些小白面對這倆貨的時候第一反應(yīng)就是懵逼葵蒂,然后就是不知所措,最后就是恐懼重虑。雖然說在PC端ReflowRepaint對于性能的影響是微乎其微践付,但是在移動端這倆貨簡直就是性能殺手。

一臉懵逼

這倆貨到底是干啥的缺厉,這么生猛永高?這個地方先系上一個扣隧土,等一下下我們就解開。套用評書里的話就是“花開兩支命爬,各表一枝”曹傀。我們先來說說CSS動畫的問題,CSS3中定義關(guān)于動畫和過渡的屬性饲宛,這兩個小小的屬性能讓我們不用使用JS的情況下就能做出很炫的交互效果皆愉。這么猛的東西肯定要支付一定的代價了,代價就是瀏覽器性能艇抠。不行可以試試做一個超級復(fù)雜的動畫幕庐,看看自己的瀏覽器卡頓不?另外JS關(guān)于DOM編程也讓我們對頁面DOM的操作更加順暢便捷家淤,這些便捷和順暢也是在犧牲一定性能的情況獲得的優(yōu)勢异剥,比如一次性添加或者操作多個DOM元素,看看頁面會不會“遲鈍”絮重。

我舉得例子其實已經(jīng)說明了這倆生猛的貨的來路了冤寿。

Repaint就是“重繪”,它會在你改變 DOM 元素的視覺效果時進行绿鸣,改變布局時不會觸發(fā)疚沐。比如暂氯,opacity,background-color,visibilityoutline等都會觸發(fā)潮模,“重繪”的開銷還是比較昂貴的,因為瀏覽器會在某一個DOM元素的視覺效果改變后去check這個DOM元素內(nèi)的所有節(jié)點痴施。

**Reflow **就是“回流”擎厢,它的影響更大。它會在某一個DOM元素的位置發(fā)生改變后觸發(fā)辣吃,而且它會重新計算所有元素的位置和在頁面中的占有的面積动遭,這樣的話將會引起頁面某一個部分甚至整個頁面的重新渲染。改變某一個元素會影響它所有的子節(jié)點 (children)神得、祖先節(jié)點 (ancestors) 及兄弟節(jié)點(siblings)厘惦。

舉個例子就能明白了這兩個概念。譬如有一顆大樹哩簿,季節(jié)變換了葉子也會從綠色變成黃色宵蕉,這個就是Repaint。如果樹枝或者其他什么部位被砍了或者插枝嫁接了节榜,大樹會自動恢復(fù)傷口或?qū)⑿轮Π蔀樽约旱囊徊糠窒勐辏詈笞兂梢粋€完整的大樹。這個過程就類似Reflow宗苍。

Reflow和Repaint都是瀏覽器慢的元兇稼稿。用戶和Web頁面都不能在Reflow和Repaint執(zhí)行時做任何操作和響應(yīng)薄榛,而且在極端的情況下,CSS會拖慢JS的執(zhí)行速度让歼,這就是瀏覽器有的時候就是在操作之后沒反應(yīng)的原因之一敞恋。

在“兩害相權(quán)取其輕,兩利相權(quán)取其重”的思想照耀下谋右,發(fā)現(xiàn)這倆貨相比之下Reflow(回流)的開銷更為昂貴耳舅,這么貴的東西我們肯定是會繞著走,什么情況下會觸發(fā)Reflow倚评?

  • 添加浦徊、刪除或者改變DOM元素的可見性時:使用JS去改變DOM元素時會觸發(fā)Reflow。
  • 添加天梧、刪除或者改變CSS樣式:直接改變CSS Style或者元素的class可能會影響布局盔性,還有改變一個元素的寬度能夠影響它所在的DOM節(jié)點中的所有元素,以及它周圍的那些元素呢岗。
  • CSS3 動畫(animation)和過渡(transition): 動畫的每一frame都會觸發(fā)Reflow冕香。
  • 使用offsetWidthoffsetHeight:這一點很特別,你讀一個DOM的offsetWidthoffsetHeight屬性同樣會觸發(fā)一下Reflow后豫,因為這兩個屬性需要依賴一些元素去計算悉尾。
  • 用戶交互:用戶可以通過:hover一下<a>鏈接,在input里面輸入文字挫酿,拖動瀏覽器的大小构眯,改變字體大小,更換樣式表或者字體等都會觸發(fā)reflow早龟。

既然我們知道了觸發(fā)Reflow的條件了惫霸,我們發(fā)其道而行就能避免增加額外的資源開銷。這個地方我就懶的自己去寫了葱弟,我摘抄了其他一些同行總結(jié)的經(jīng)驗壹店,做了一個信息拼合,大家將就看吧芝加。

一些常用的提高性能的原則

方面 方法
布局 不要用 inline style 或 table 布局硅卢,flexbox 布局也會給性能帶來一些小困擾。inline style 會在 html 下載完后進行一次額外的 Reflow藏杖,table布局的開銷遠比其他 DOM 元素的布局開銷要大将塑。flexbox 的 item 會在 HTML 下載完成后改變尺寸。
簡寫CSS 盡量簡寫CSS制市,避免使用復(fù)雜的CSS選擇器抬旺,使用 Unused CSS https://unused-css.com/), uCSS(https://github.com/oyvindeh/ucss), gulp-uncss(https://github.com/ben-eb/gulp-uncss)可以有效的減少樣式的定義和文件的大小。
優(yōu)化DOM 減少DOM的層級祥楣,減少DOM的數(shù)量开财,如果不需適配老瀏覽器汉柒,刪掉一些無用的wrapper性質(zhì)的DOM元素,總之越少越好责鳍。
慎改class 在一個DOM樹中碾褂,盡可能改那些沒有特別多子元素DOM的class,子元素少的可以改历葛,多的不推薦正塌。
避免復(fù)雜動畫 刪掉復(fù)雜的動畫,運用動畫的元素盡量是position:absolute或position:fixed的恤溶,這樣會讓他們脫離文檔流乓诽,不去影響其他的元素。
善用display:none display:none的元素不會引發(fā)Reflow和Repaint咒程,可以在讓這些元素在display之前進行一些諸如顏色鸠天、尺寸什么的改變。
批量更新元素 將狀態(tài)寫入一個類中帐姻,用JQ直接給元素添加或刪除這個類稠集,而不是直接通過方法來修改元素樣式狀態(tài)。
避免大量DOM互相影響 比如Tabs這種場景饥瓷,如果你點擊一個Tab會顯示它控制的區(qū)塊剥纷,顯示的那個區(qū)塊會影響其他的區(qū)塊,這樣可能會引起Reflow呢铆,因為它們的高度不一樣晦鞋,可以通過定個高度來優(yōu)化這種場景。
性能永遠比酷炫重要 記住一個原則刺洒,你網(wǎng)頁的動畫再牛逼鳖宾,性能還是第一位的吼砂,如果每一幀移動1個像素會造成你的頁面卡頓逆航,那寧愿每一幀移動10像素讓動畫的幀變得遲鈍一些,也不要讓頁面的性能降下來渔肩。
媽媽再也不用擔(dān)心我的學(xué)習(xí)了
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末因俐,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子周偎,更是在濱河造成了極大的恐慌抹剩,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,590評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蓉坎,死亡現(xiàn)場離奇詭異澳眷,居然都是意外死亡,警方通過查閱死者的電腦和手機蛉艾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評論 3 399
  • 文/潘曉璐 我一進店門钳踊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來衷敌,“玉大人,你說我怎么就攤上這事拓瞪〗陕蓿” “怎么了?”我有些...
    開封第一講書人閱讀 169,301評論 0 362
  • 文/不壞的土叔 我叫張陵祭埂,是天一觀的道長面氓。 經(jīng)常有香客問我,道長蛆橡,這世上最難降的妖魔是什么舌界? 我笑而不...
    開封第一講書人閱讀 60,078評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮泰演,結(jié)果婚禮上禀横,老公的妹妹穿的比我還像新娘。我一直安慰自己粥血,他們只是感情好柏锄,可當(dāng)我...
    茶點故事閱讀 69,082評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著复亏,像睡著了一般趾娃。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上缔御,一...
    開封第一講書人閱讀 52,682評論 1 312
  • 那天抬闷,我揣著相機與錄音,去河邊找鬼耕突。 笑死笤成,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的眷茁。 我是一名探鬼主播炕泳,決...
    沈念sama閱讀 41,155評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼上祈!你這毒婦竟也來了培遵?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,098評論 0 277
  • 序言:老撾萬榮一對情侶失蹤登刺,失蹤者是張志新(化名)和其女友劉穎籽腕,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體纸俭,經(jīng)...
    沈念sama閱讀 46,638評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡皇耗,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,701評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了揍很。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片郎楼。...
    茶點故事閱讀 40,852評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡矾瘾,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出箭启,到底是詐尸還是另有隱情壕翩,我是刑警寧澤,帶...
    沈念sama閱讀 36,520評論 5 351
  • 正文 年R本政府宣布傅寡,位于F島的核電站放妈,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏荐操。R本人自食惡果不足惜芜抒,卻給世界環(huán)境...
    茶點故事閱讀 42,181評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望托启。 院中可真熱鬧宅倒,春花似錦、人聲如沸屯耸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽疗绣。三九已至线召,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間多矮,已是汗流浹背缓淹。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留塔逃,地道東北人讯壶。 一個月前我還...
    沈念sama閱讀 49,279評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像湾盗,于是被迫代替她去往敵國和親伏蚊。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,851評論 2 361

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