什么是回流與重繪 (Reflow & Repaint)

寫在前面

在討論今天的主角之前谬莹,我們要先了解一下瀏覽器的渲染機(jī)制。以Google,Firefox,Safari為例,Firefox 使用Geoko——Mozilla 自主研發(fā)的渲染引擎附帽,SafariChrome 都使用 webkit埠戳。

我們主要以 Webkit的主流程為例

  • 瀏覽器使用流式布局模型 (Flow Based Layout)
  • 解析HTML 生成 DOM
  • 解析CSS 生成CSSOM 規(guī)則樹
  • DOM 樹與 CSSOM 規(guī)則樹合并在一起生成渲染樹Render Tree
  • 根據(jù)渲染樹遍歷拿到每個節(jié)點(diǎn)開始布局,計(jì)算每個節(jié)點(diǎn)的位置大小信息
  • 將渲染樹每個節(jié)點(diǎn)繪制到屏幕

回流(Reflow)

上面我們知道蕉扮,我們會根據(jù) Render Tree 去遍歷渲染整胃,所以當(dāng)我們的節(jié)點(diǎn)發(fā)生改變時(shí),瀏覽器重新渲染部分節(jié)點(diǎn)或者全部文檔喳钟,我們稱這個過程為回流

大致整理會導(dǎo)致回流的一些操作

  • 頁面首次渲染
  • 瀏覽器窗口大小發(fā)生改變
  • 元素尺寸或位置發(fā)生改變
  • 元素內(nèi)容變化(文字?jǐn)?shù)量或圖片大小等等)
  • 元素字體大小變化
  • 添加或者刪除可見的DOM元素
  • 激活CSS偽類(例如::hover)
  • 查詢某些屬性或調(diào)用某些方法

主要有下面幾個API

盒子操作相關(guān)

  • elem.offsetLeft, elem.offsetTop, elem.offsetWidth, elem.offsetHeight, elem.offsetParent
  • elem.clientLeft, elem.clientTop, elem.clientWidth, elem.clientHeight
  • elem.getClientRects(), elem.getBoundingClientRect()

滾動相關(guān)

  • elem.scrollBy(), elem.scrollTo()
  • elem.scrollIntoView(), elem.scrollIntoViewIfNeeded()
  • elem.scrollWidth, elem.scrollHeight
  • elem.scrollLeft, elem.scrollTop

其他

上述主要是我們經(jīng)常使用的一些API,其他還有一個api已經(jīng)有熱心網(wǎng)友幫我們整理出來了

我們可以看一下
What forces layout / reflow

重繪(Repaint)

當(dāng)我們操作的節(jié)點(diǎn)上的元素并不導(dǎo)致元素位置發(fā)生變化時(shí)屁使,比如color,background-color,visibility(注意雖然節(jié)點(diǎn)隱藏了,但是元素還在荚藻,并且位置也不會發(fā)生變化)

瀏覽器會將新的樣式賦值給這些節(jié)點(diǎn)屋灌,我們稱這個過程為重繪

影響

按照常理也很好理解,因?yàn)槲恢糜τ笮〉劝l(fā)生的回流操作相比于僅僅是顏色的變化共郭,帶給我們的視覺直觀感受來說,回流是比較大的疾呻。

事實(shí)上除嘹,回流確實(shí)比重繪的成本更大,并且有時(shí)候并不是只回流一個元素岸蜗,甚至?xí)痈冈鼗蛘咦釉匾黄鸹亓鳌?/p>

現(xiàn)代瀏覽器會對頻繁的回流或重繪操作進(jìn)行優(yōu)化尉咕,瀏覽器會維護(hù)一個隊(duì)列,當(dāng)我們頁面發(fā)生回流或重繪時(shí)璃岳,有時(shí)候并不是立即執(zhí)行年缎,而是先放入維護(hù)的隊(duì)列中,到達(dá)一定時(shí)間后統(tǒng)一去進(jìn)行繪制

當(dāng)你訪問以下屬性或方法時(shí)铃慷,瀏覽器會立刻清空隊(duì)列

clientWidth单芜、clientHeightclientTop犁柜、clientLeft

offsetWidth洲鸠、offsetHeightoffsetTop馋缅、offsetLeft`

scrollWidth扒腕、scrollHeightscrollTop萤悴、scrollLeft

width瘾腰、height

getComputedStyle()

getBoundingClientRect()

所以當(dāng)我們需要使用如上api獲取數(shù)據(jù)時(shí),我們要注重渲染時(shí)機(jī)以及取值時(shí)機(jī)

避免重繪與回流

  • 避免使用 table 布局稚疹。
  • 盡可能在 DOM 樹的最末端改變class居灯。
  • 避免設(shè)置多層內(nèi)聯(lián)樣式祭务。
  • 將動畫效果應(yīng)用到position屬性為absolutefixed的元素上。
  • 避免使用CSS表達(dá)式(例如:calc())怪嫌。
  • 避免頻繁操作樣式义锥,最好一次性重寫style屬性,或者將樣式列表定義為class并一次性更改class屬性岩灭。
    -避免頻繁操作DOM拌倍,創(chuàng)建一個documentFragment,在它上面應(yīng)用所有DOM操作噪径,最后再把它添加到文檔中柱恤。
  • 也可以先為元素設(shè)置display: none,操作結(jié)束后再把它顯示出來找爱。因?yàn)樵?code>display屬性為none的元素上進(jìn)行的DOM操作不會引發(fā)回流和重繪梗顺。
  • 避免頻繁讀取會引發(fā)回流/重繪的屬性,如果確實(shí)需要多次使用车摄,就用一個變量緩存起來寺谤。
  • 對具有復(fù)雜動畫的元素使用絕對定位,使它脫離文檔流吮播,否則會引起父元素及后續(xù)元素頻繁回流变屁。

總結(jié)

我們把頁面文檔比作一個積木的話,我們抽離中間或者底部的一個積木塊意狠,我們的積木會重新找到重心并且穩(wěn)固下來粟关,我們把這個過程稱之為回流

我們在某個積木上涂上顏色,這并不會造成整個積木的穩(wěn)定环戈,我們把這個過程叫做重繪

或者說闷板,我們簡單理解會引起元素位置變化的就會reflow,會引起位置變化的,只是在以前的位置進(jìn)行改變背景顏色等院塞,只會repaint

本文首發(fā)于什么是回流與重繪 (Reflow & Repaint)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蛔垢,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子迫悠,更是在濱河造成了極大的恐慌,老刑警劉巖巩梢,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件创泄,死亡現(xiàn)場離奇詭異,居然都是意外死亡括蝠,警方通過查閱死者的電腦和手機(jī)鞠抑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來忌警,“玉大人搁拙,你說我怎么就攤上這事秒梳。” “怎么了箕速?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵酪碘,是天一觀的道長。 經(jīng)常有香客問我盐茎,道長兴垦,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任字柠,我火速辦了婚禮探越,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘窑业。我一直安慰自己钦幔,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布常柄。 她就那樣靜靜地躺著鲤氢,像睡著了一般。 火紅的嫁衣襯著肌膚如雪拐纱。 梳的紋絲不亂的頭發(fā)上铜异,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天,我揣著相機(jī)與錄音秸架,去河邊找鬼揍庄。 笑死,一個胖子當(dāng)著我的面吹牛东抹,可吹牛的內(nèi)容都是我干的蚂子。 我是一名探鬼主播,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼缭黔,長吁一口氣:“原來是場噩夢啊……” “哼食茎!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起馏谨,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤别渔,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后惧互,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體哎媚,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年喊儡,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了拨与。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡艾猜,死狀恐怖买喧,靈堂內(nèi)的尸體忽然破棺而出捻悯,到底是詐尸還是另有隱情,我是刑警寧澤淤毛,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布今缚,位于F島的核電站,受9級特大地震影響钱床,放射性物質(zhì)發(fā)生泄漏荚斯。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一查牌、第九天 我趴在偏房一處隱蔽的房頂上張望事期。 院中可真熱鬧,春花似錦纸颜、人聲如沸兽泣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽唠倦。三九已至,卻和暖如春涮较,著一層夾襖步出監(jiān)牢的瞬間稠鼻,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工狂票, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留候齿,地道東北人。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓闺属,卻偏偏與公主長得像慌盯,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子掂器,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評論 2 360

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