日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

重绘和回流----降低回流减少性能影响

發(fā)布時間:2025/5/22 编程问答 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 重绘和回流----降低回流减少性能影响 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

回流和重繪

原創(chuàng)?2016年02月29日 14:49:02
  • 640

回流與重繪

1. 當render tree中的一部分(或全部)因為元素的規(guī)模尺寸,布局,隱藏等改變而需要重新構建。這就稱為回流(reflow)。每個頁面至少需要一次回流,就是在頁面第一次加載的時候。在回流的時候,瀏覽器會使渲染樹中受到影響的部分失效,并重新構造這部分渲染樹,完成回流后,瀏覽器會重新繪制受影響的部分到屏幕中,該過程成為重繪。

2. 當render tree中的一些元素需要更新屬性,而這些屬性只是影響元素的外觀,風格,而不會影響布局的,比如background-color。則就叫稱為重繪。

注意:回流必將引起重繪,而重繪不一定會引起回流。

回流何時發(fā)生:

當頁面布局和幾何屬性改變時就需要回流。下述情況會發(fā)生瀏覽器回流:

1、添加或者刪除可見的DOM元素;

2、元素位置改變;

3、元素尺寸改變——邊距、填充、邊框、寬度和高度

4、內(nèi)容改變——比如文本改變或者圖片大小改變而引起的計算值寬度和高度改變;

5、頁面渲染初始化;

6、瀏覽器窗口尺寸改變——resize事件發(fā)生時;

讓我們看看下面的代碼是如何影響回流和重繪的:

  • var?s?=?document.body.style;
  • s.padding?=?"2px";?// 回流+重繪
  • s.border?=?"1px solid red";?// 再一次 回流+重繪
  • s.color?=?"blue";?// 再一次重繪
  • s.backgroundColor?=?"#ccc";?// 再一次 重繪
  • s.fontSize?=?"14px";?// 再一次 回流+重繪
  • // 添加node,再一次 回流+重繪
  • document.body.appendChild(document.createTextNode('abc!'));
  • 說到這里大家都知道回流比重繪的代價要更高,回流的花銷跟render tree有多少節(jié)點需要重新構建有關系,假設你直接操作body,比如在body最前面插入1個元素,會導致整個render tree回流,這樣代價當然會比較高,但如果是指body后面插入1個元素,則不會影響前面元素的回流

    聰明的瀏覽器

    從上個實例代碼中可以看到幾行簡單的JS代碼就引起了6次左右的回流、重繪。而且我們也知道回流的花銷也不小,如果每句JS操作都去回流重繪的話,瀏覽器可能就會受不了。所以很多瀏覽器都會優(yōu)化這些操作,瀏覽器會維護1個隊列,把所有會引起回流、重繪的操作放入這個隊列,等隊列中的操作到了一定的數(shù)量或者到了一定的時間間隔,瀏覽器就會flush隊列,進行一個批處理。這樣就會讓多次的回流、重繪變成一次回流重繪。

    雖然有了瀏覽器的優(yōu)化,但有時候我們寫的一些代碼可能會強制瀏覽器提前flush隊列,這樣瀏覽器的優(yōu)化可能就起不到作用了。當你請求向瀏覽器請求一些 style信息的時候,就會讓瀏覽器flush隊列,比如:

    1. offsetTop, offsetLeft, offsetWidth, offsetHeight

    2. scrollTop/Left/Width/Height

    3. clientTop/Left/Width/Height

    4. width,height

    5. 請求了getComputedStyle(), 或者 IE的 currentStyle

    當你請求上面的一些屬性的時候,瀏覽器為了給你最精確的值,需要flush隊列,因為隊列中可能會有影響到這些值的操作。即使你獲取元素的布局和樣式信息跟最近發(fā)生或改變的布局信息無關,瀏覽器都會強行刷新渲染隊列。 回流: <body><div?class="error">? ? ? ? <h4>我的組件</h4>? ? ? ? <p><strong>錯誤:</strong>錯誤的描述…</p>? ? ? ? <h5>錯誤糾正</h5>? ? ? ? <ol>? ? ? ? ? ? ? ? <li>第一步</li>? ? ? ? ? ? ? ? <li>第二步</li>? ? ? ? </ol></div> </body> 在上面的HTML片段中,對該段落(<p>標簽)回流將會引發(fā)強烈的回流,因為它是一個子節(jié)點。這也導致了祖先的回流(div.error和body – 視瀏覽器而定)。此外,h5和ol也會有簡單的回流,因為其在DOM中在回流元素之后。就Opera而言,大部分的回流將導致頁面的重新渲染。 避免回流降低性能影響

    1. 直接改變className,如果動態(tài)改變樣式,則使用cssText(考慮沒有優(yōu)化的瀏覽器)

  • // 不好的寫法
  • var?left?=?1;
  • var?top?=?1;
  • el.style.left?=?left?+?"px";
  • el.style.top?=?top?+?"px";// 比較好的寫法
  • el.className?+=?" className1";
  • ?
  • // 比較好的寫法
  • el.style.cssText?+=?";
  • left:?" + left + "px;
  • top:?" + top + "px;";
  • 2. 讓要操作的元素進行”離線處理”,處理完后一起更新

    a) 使用DocumentFragment進行緩存操作,引發(fā)一次回流和重繪;
    b) 使用display:none技術,只引發(fā)兩次回流和重繪; c) 使用cloneNode(true or false) 和 replaceChild 技術,引發(fā)一次回流和重繪;

    3.不要經(jīng)常訪問會引起瀏覽器flush隊列的屬性,如果你確實要訪問,利用緩存

  • // 別這樣寫,大哥
  • for(循環(huán))?{
  • el.style.left?=?el.offsetLeft?+?5?+?"px";
  • el.style.top?=?el.offsetTop?+?5?+?"px";
  • }
  • ?
  • // 這樣寫好點
  • var?left?=?el.offsetLeft,
  • top?=?el.offsetTop,
  • s?=?el.style;
  • for?(循環(huán))?{
  • left?+=?10;
  • top?+=?10;
  • s.left?=?left?+?"px";
  • s.top?=?top?+?"px";
  • }
  • 4. 讓元素脫離動畫流,減少回流的Render Tree的規(guī)模

  • $("#block1").animate({left:50});
  • $("#block2").animate({marginLeft:50});
  • 避免使用table布局 在布局完全建立之前,table經(jīng)常需要多個關口,因為table是個和罕見的可以影響在它們之前已經(jīng)進入的DOM元素的顯示的元素。想象一下,因為表格最后一個單元格的內(nèi)容過寬而導致縱列大小完全改變。這就是為什么所有的瀏覽器都逐步地不支持table表格的渲染(感謝Bill Scott提供)。然而有另外一個原因為什么表格布局時很糟糕的主意,根據(jù)Mozilla,即使一些小的變化將導致表格(table)中的所有其他節(jié)點回流。

    轉載于:https://www.cnblogs.com/chenhongshuang/p/8743024.html

    總結

    以上是生活随笔為你收集整理的重绘和回流----降低回流减少性能影响的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。