浏览器是根据更改还是仅重新呈现整个页面?

Jim*_*Jim 14 javascript browser performance jquery

假设我有一个带id的元素,#msg并且在某个条件下我想添加一个类以便应用样式,例如使文本显示为红色.
我可以做$('#msg').addClass(theclass)
我的问题是浏览器是如何反应的?它是重新渲染所有页面还是重新渲染该特定元素?

Tyb*_*itz 9

对于您的示例 ( addClass),这取决于您添加的类中的内容。添加类本身只会修改目标节点上的属性。

  • 某些更改会导致 重绘,即更改颜色、bgcolor 等时。只有应用了新 CSS 的元素才会重新渲染。
  • 某些更改会导致回流,即当元素或其内容占用的可见空间更改尺寸或位置时。根据他们自己的、他们的父级和子级的属性,以及那些父级和子级的属性等等,回流将影响文档树中的更多元素。

浏览器足够智能,只修改需要重新渲染的元素。一种最小化重新渲染量的技术是设置元素的position: absolutedisplay: none从文档流中临时删除它,进行更改,然后重新插入。这尤其重要,例如。你让一些元素向下滑动。如果元素在流中并且位于 DOM 树的开头,它拉伸的每个像素都会导致重新渲染。

为了好玩,让我们用桌子上的纸做一个简单的类比,在这个例子中是元素插入。桌子是您的浏览器窗口,?= 纸,_= 空白空间。您想将另一张纸放在最左上角的位置。这是开始的情况:

? ? ? ?
? ? ? ?
_ _ _ _

将新床单放在桌子上后:(?= 新,?= 移动)

? ? ? ?
? ? ? ?
? _ _ _

如果第二行是一卷长纸(= 全宽 div),则整行都会移动:

? ? ? ?
? _ _ _
???????

但是,如果您将工作表插入第三行,则不会发生回流。

注:这是理论解释。其效率因浏览器而异。
来源:高性能 Javascript,“重绘和回流”,第 70 页。


id.*_*.ot 5

根据此工具https://developer.chrome.com/devtools/docs/timeline提供的结果,我的理解是NO,整个 DOM 不会重新绘制/重新生成,只是更改了类的元素。

演示

HTML:

<p>Lorem ipsum dolar sit amet...</p>

<input id="btn" type="button" value="click me" />
Run Code Online (Sandbox Code Playgroud)

Javascript:

$(document).on('click', '#btn', function () { 
  $('p').addClass('red')  
})
Run Code Online (Sandbox Code Playgroud)

CSS:

.red {
    color: red;
}
Run Code Online (Sandbox Code Playgroud)

****edit**** 我不得不将答案从“否”更改为“是”,然后从“是”更改回“否”。该工具明确指出正在重绘的元素,其他 DOM 元素不受影响。

但是, 如果元素内/外维度发生变化,甚至需要通过javascript查询,这将需要重新绘制DOM元素,并且将重新绘制整个元素分支,然后由浏览器缓存。

在此处输入图片说明