国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

你應(yīng)該要知道的重繪與重排

liukai90 / 3127人閱讀

摘要:合并樣式操作比如可以合并成批量修改使元素脫離文檔流,再對(duì)其進(jìn)行操作,然后再把元素帶回文檔中,這種辦法可以有效減少重繪重排的次數(shù)。

前言

現(xiàn)代web框架大多都是數(shù)據(jù)驅(qū)動(dòng)類的,比如 react, vue,所以開發(fā)者不需要直接接觸 DOM,修改 data 便可以驅(qū)動(dòng)界面更新。但是作為前端工程師,了解瀏覽器的重繪與重排還是很有必要的,可以幫助我們寫出更好性能的 web 應(yīng)用。

瀏覽器的渲染

CSS Tree: 瀏覽器將 CSS 解析成 CSSOM 的樹形結(jié)構(gòu)

DOM Tree:瀏覽器將 HTML 解析成樹形的數(shù)據(jù)結(jié)構(gòu)

Render Tree:將 DOM 與 CSSOM 合并成一個(gè)渲染樹

有了渲染樹(Render Tree),瀏覽器就知道網(wǎng)頁(yè)中有哪些節(jié)點(diǎn),以及各個(gè)節(jié)點(diǎn)與 CSS 的關(guān)系,從而知道每個(gè)節(jié)點(diǎn)的位置和幾何屬性,然后繪制頁(yè)面。

重繪與重排

當(dāng) DOM 的變化影響了元素的幾何屬性(比如 width 和 height ),就會(huì)導(dǎo)致瀏覽器重新計(jì)算元素的幾何屬性,同樣受到該元素影響的其他元素也會(huì)發(fā)生重新計(jì)算。此時(shí),瀏覽器會(huì)使渲染樹中受到影響的部分失效,并重新構(gòu)造渲染樹。這個(gè)過程被稱為重排(也叫“回流”)(reflow),完成重排之后,瀏覽器會(huì)重新繪制受影響的部分到頁(yè)面上,這個(gè)過程就是重繪(repaint)。

所以重排一定會(huì)引起重繪,而重繪不一定會(huì)引起重排,比如一個(gè)元素的改變并沒有影響布局的改變(background-color的改變),在這種情況下,只會(huì)發(fā)生一個(gè)重繪(不需要重排)。

引起重排的因素

可以總結(jié)出,當(dāng)元素的幾何屬性或頁(yè)面布局發(fā)生改變就會(huì)引起重排,比如:

對(duì)可見 DOM 元素的操作(添加,刪除或順序變化)

元素位置發(fā)生改變

元素的幾何屬性發(fā)生改變(比如:外邊距、內(nèi)邊距、邊框?qū)挾纫约皟?nèi)容改變引起的寬高的改變)

頁(yè)面首次渲染

偽類樣式激活(hover等)

瀏覽器視口尺寸發(fā)生改變(滾動(dòng)或縮放)

如何優(yōu)化

重繪與重排都是代價(jià)昂貴的操作(因?yàn)槊看沃嘏哦紩?huì)產(chǎn)生計(jì)算消耗),它們會(huì)導(dǎo)致 web 應(yīng)用的 UI 反應(yīng)遲鈍,所以開發(fā)者在編寫應(yīng)用程序的時(shí)候應(yīng)當(dāng)盡量減少這類過程的發(fā)生。

渲染樹隊(duì)列

因?yàn)檫^多的重繪與重排可能會(huì)導(dǎo)致應(yīng)用的卡頓,所以瀏覽器會(huì)對(duì)這個(gè)有一個(gè)優(yōu)化的過程。大多數(shù)瀏覽器會(huì)通過隊(duì)列化來批量執(zhí)行(比如把腳本對(duì) DOM 的修改放入一個(gè)隊(duì)列,在隊(duì)列所有操作都結(jié)束后再進(jìn)行一次繪制)。但是開發(fā)者有時(shí)可能不知不覺的強(qiáng)制刷新渲染隊(duì)列來立即進(jìn)行重排重繪,比如獲取頁(yè)面布局信息會(huì)導(dǎo)致渲染隊(duì)列的強(qiáng)制刷新,以下屬性或方法會(huì)立即觸發(fā)頁(yè)面繪制:

offsetTop、offsetLeft、offsetWidth、offsetHeight

scrollTop、scrollLeft、scrollWidth、scrollHeight

clientTop、clientLeft、clientWidth、clientHeight

getComputedStyle()

以上屬性和方法都是要瀏覽器返回最新的布局信息,所以瀏覽器會(huì)立刻執(zhí)行渲染隊(duì)列中的“待處理變化”, 并觸發(fā)重排重繪然后返回最新的值。所以在修改樣式的過程中,應(yīng)該盡量避免使用以上屬性和方法。

減少重繪與重排

為了減少重繪重排的發(fā)生次數(shù),開發(fā)者應(yīng)該合并多次對(duì) DOM 的修改和對(duì)樣式的修改,然后一次性處理。

合并樣式操作

比如:

var el = document.querySelector("div");
el.style.borderLeft = "1px";
el.style.borderRight = "2px";
el.style.padding = "5px";

可以合并成:

var el = document.querySelector("div");
el.style.cssText = "border-left: 1px; border-right: 1px; padding: 5px;"
批量修改DOM

使元素脫離文檔流,再對(duì)其進(jìn)行操作,然后再把元素帶回文檔中,這種辦法可以有效減少重繪重排的次數(shù)。有三種基本辦法可以使元素脫離文檔流:

隱藏元素,應(yīng)用修改,重新顯示
var ul = document.querySelector("ul");
ul.style.display = "none";
// code... 對(duì)ul進(jìn)行DOM操作
ul.style.display = "block";
使用文檔片段(document fragment),構(gòu)建一個(gè)空白文檔進(jìn)行 DOM 操作,然后再放回原文檔中
var fragment = document.createDocumentFragment();
// code... 對(duì)fragment進(jìn)行DOM操作
var ul = document.querySelector("ul");
ul.appendChild(fragment)
拷貝要修改的元素到一個(gè)脫離文檔流的節(jié)點(diǎn)中,修改副本,然后再替換原始元素
var ul = document.querySelector("ul");
var cloneUl = ul.cloneNode(true);
// code... 對(duì)clone節(jié)點(diǎn)進(jìn)行DOM操作
ul.parentNode.replaceChild(cloneUl, ul)
緩存布局信息

前面已經(jīng)知道,獲取頁(yè)面布局信息,會(huì)導(dǎo)致瀏覽器強(qiáng)制刷新渲染隊(duì)列。所以減少這些操作是非常有必要的,開發(fā)者可以將第一次獲取到的頁(yè)面信息緩存到局部變量中,然后再操作局部變量,比如下面的偽代碼示例:

// 低效的
element.style.left = 1 + element.offsetLeft + "px";
element.style.top = 1 + element.offsetTop + "px";
if (element.offsetTop > 500) {
    stopAnimation();
}
// 高效的
var offsetLeft = element.offsetLeft;
var offsetTop = element.offsetTop;
offsetLeft++;
offsetTop++;
element.style.left = offsetLeft + "px";
element.style.top = offsetTop + "px";
if (offsetTop > 500) {
    stopAnimation();
}
總結(jié)

為了減少重繪重排帶來的性能消耗,可以通過以下幾點(diǎn)改善 web 應(yīng)用:

批量修改 DOM 和樣式

“離線”操作 DOM 樹,脫離文檔流

緩存到局部變量,減少頁(yè)面布局信息的訪問次數(shù)

參考

高性能JavaScript

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/100993.html

相關(guān)文章

  • 掌握瀏覽器重繪(repaint)重排(reflow))-前端進(jìn)階

    摘要:就如上面的概念一樣,單單改變?cè)氐耐庥^,肯定不會(huì)引起網(wǎng)頁(yè)重新生成布局,但當(dāng)瀏覽器完成重排之后,將會(huì)重新繪制受到此次重排影響的部分。因?yàn)殛?duì)列中,可能會(huì)有影響到這些值的操作,為了給我們最精確的值,瀏覽器會(huì)立即重排重繪。 showImg(http://ww1.sinaimg.cn/large/005Y4rCogy1fya3fh2jm3j30ku0dwtb2.jpg); 很多人都知道要減少瀏覽...

    nifhlheimr 評(píng)論0 收藏0
  • 從微信小程序重力感應(yīng)API到requestAnimationFrame探索實(shí)現(xiàn)

    摘要:最近做微信小程序的開發(fā)時(shí),想做一個(gè)靠感知手機(jī)方向,使頁(yè)面上節(jié)點(diǎn)跟隨移動(dòng)的動(dòng)畫即重力感應(yīng)視差效果功能。最終實(shí)現(xiàn)的效果會(huì)有卡頓現(xiàn)象。如果是后臺(tái)標(biāo)簽頁(yè)面,重繪頻率則會(huì)大大降低。較于,能得到更完整的加速的支持。 最近做微信小程序的開發(fā)時(shí),想做一個(gè)靠感知手機(jī)方向,使頁(yè)面上節(jié)點(diǎn)跟隨移動(dòng)的動(dòng)畫(即重力感應(yīng)視差效果)功能。結(jié)果發(fā)現(xiàn)微信小程序有一些坑: 微信小程序不支持html5的DeviceOrie...

    JinB 評(píng)論0 收藏0
  • 從微信小程序重力感應(yīng)API到requestAnimationFrame探索實(shí)現(xiàn)

    摘要:最近做微信小程序的開發(fā)時(shí),想做一個(gè)靠感知手機(jī)方向,使頁(yè)面上節(jié)點(diǎn)跟隨移動(dòng)的動(dòng)畫即重力感應(yīng)視差效果功能。最終實(shí)現(xiàn)的效果會(huì)有卡頓現(xiàn)象。如果是后臺(tái)標(biāo)簽頁(yè)面,重繪頻率則會(huì)大大降低。較于,能得到更完整的加速的支持。 最近做微信小程序的開發(fā)時(shí),想做一個(gè)靠感知手機(jī)方向,使頁(yè)面上節(jié)點(diǎn)跟隨移動(dòng)的動(dòng)畫(即重力感應(yīng)視差效果)功能。結(jié)果發(fā)現(xiàn)微信小程序有一些坑: 微信小程序不支持html5的DeviceOrie...

    sarva 評(píng)論0 收藏0
  • 從微信小程序重力感應(yīng)API到requestAnimationFrame探索實(shí)現(xiàn)

    摘要:最近做微信小程序的開發(fā)時(shí),想做一個(gè)靠感知手機(jī)方向,使頁(yè)面上節(jié)點(diǎn)跟隨移動(dòng)的動(dòng)畫即重力感應(yīng)視差效果功能。最終實(shí)現(xiàn)的效果會(huì)有卡頓現(xiàn)象。如果是后臺(tái)標(biāo)簽頁(yè)面,重繪頻率則會(huì)大大降低。較于,能得到更完整的加速的支持。 最近做微信小程序的開發(fā)時(shí),想做一個(gè)靠感知手機(jī)方向,使頁(yè)面上節(jié)點(diǎn)跟隨移動(dòng)的動(dòng)畫(即重力感應(yīng)視差效果)功能。結(jié)果發(fā)現(xiàn)微信小程序有一些坑: 微信小程序不支持html5的DeviceOrie...

    soasme 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<