了解JavaScript中的重绘和重排

最近,在研究使React的虚拟DOM如此快速发展的原因时,我意识到我们对javascript性能的了解很少。因此,我写这篇文章的目的是帮助提高人们对重绘和重排以及JavaScript性能的认识。”

在深入研究之前,我们是否知道浏览器如何工作?

一图胜千言。因此,让我们大致了解浏览器的工作原理!

什么是“浏览器引擎”和“渲染引擎”?

浏览器引擎的主要工作是将HTML文档和网页的其他资源转换为用户设备上的交互式视觉表示。
除“浏览器引擎”外,有关概念的其他两个常用术语是:“布局引擎layout engine”和“渲染引擎rendering engine”。从理论上讲,布局和渲染(或“绘画”)可以由单独的引擎处理。但是实际上,它们紧密耦合,很少单独考虑。

让我们了解浏览器如何在屏幕上绘制用户界面。

当您在某个链接或URL浏览器上按下Enter键时,对该页面进行HTTP请求,相应的服务器会提供(通常)HTML文档作为响应.

  • 浏览器解析HTML源代码,并构造一个DOM树和一个数据表示形式,其中每个HTML标签在树中都有一个对应的节点,标签之间的文本块也获得一个文本节点表示形式。DOM树中的根节点是documentElement标记)
  • 浏览器解析CSS代码,使其有意义。样式信息级联:基本规则在User-Agent样式表中(浏览器默认设置),然后可能有用户样式表,作者样式表(如页面的作者)-外部样式,导入样式,内联样式以及最终样式被编码为styleHTML标签的属性
  • 接下来是构造渲染树。渲染树有点像DOM树,但不完全匹配。渲染树了解样式,因此,如果您将div用display: none隐藏起来,它将不会在渲染树中表示。对于其他不可见元素(例如,head以及其中的所有元素)也是如此。另一方面,例如在渲染树状文本节点中可能存在用多个节点表示的DOM元素,例如,

    需求中的每一行都需要一个渲染节点。渲染树中的节点称为frame或box(根据box模型,在CSS box中)。这些节点中的每个节点都有CSS框属性-宽度,高度,边框,边距等

  • 构造渲染树后,浏览器可以在屏幕上绘制(绘制)渲染树节点

这是浏览器如何在屏幕上绘制用户界面的快照。

它发生在几分之一秒之内,我们甚至根本没有注意到所有这一切。

浏览器如何绘制布局并尝试检测作为节点的根元素,兄弟姐妹及其子元素,并相应地重新布置其布局。
让我们举一个例子



  Repaint And Reflow


    
  

How's The Josh? High Sir...

Nothing to display
...

表示此HTML文档的DOM树基本上在每个标签上都有一个节点,在节点之间的每一段文本中都有一个文本节点(为简单起见,我们也忽略了空格也是文本节点这一事实):

documentElement (html)
    head
        title
    body
        p
            strong
                [text node]
        p
            strong
                b
                    [text node]         
        div 
            [text node]
        
        div
            img
        
        ...

该渲染树是DOM树的视觉部分。它缺少一些东西-头部和隐藏的div,但是它具有用于文本行的其他节点

root (RenderView)
    body
        p
            line 1
        line 2
        line 3
        ...
        
    div
        img
        
    ...

染树的根节点是包含所有其他元素的框架(框)。您可以将其视为浏览器窗口的内部部分,因为这是页面可能散布的受限区域。技术上的WebKit调用根节点RenderView和它对应于CSS初始包含块,这基本上是从页面(顶端的视口矩形00)至(window.innerWidthwindow.innerHeight

弄清楚在屏幕上显示什么以及如何精确显示需要在渲染树中进行递归遍历(flow)。

重涂和重排

始终至少有一个初始页面布局以及绘画(当然,除非您更喜欢页面空白:))。之后,更改用于构造渲染树的输入信息可能会导致以下一项或两项:

  • 渲染树的一部分(或整个树)将需要重新验证,并且节点尺寸需要重新计算。这就是所谓的回流,或布局,布点或。请注意,至少有一个重排-页面的初始布局
  • 由于节点几何属性的更改或样式更改(例如更改背景颜色),因此需要更新屏幕的某些部分。此屏幕更新称为repaint或redraw。

重画和重排可能很昂贵,可能会损害用户体验,并使UI显得呆滞

重画

顾名思义,Repaint只不过是屏幕上的重画元素,因为元素的外观发生变化,这会影响元素的可见性,但不会影响布局。
例。

  1. Changing visibility of an element.
  2. Changing an outline of the element.
  3. Changing background.
    根据Opera的说法,重画是一项昂贵的操作,因为它迫使浏览器验证/检查所有其他dom节点的可见性。

回流

的回流装置重新计算元件的位置和几何形状在文档中,用于重新呈现部分的目的或所有文档的。由于重排是浏览器中的一个用户阻止操作,因此对于开发人员了解如何缩短重排时间以及了解各种文档属性(DOM深度,CSS规则效率,不同类型的样式更改)对重排的影响非常有用。时间。有时,重排文档中的单个元素可能需要重排其父元素以及紧随其后的所有元素。

虚拟DOM与实DOM

每次DOM更改时,浏览器都需要重新计算CSS,进行布局并重新绘制网页。这是在真正的dom中花费时间的原因。

为了最大程度地减少时间,Ember使用键/值观察技术,而Angular使用脏检查。使用此技术,他们只能更新更改的dom节点或在Angular情况下标记为脏节点的节点。

如果不是这种情况,则在Gmail中编写新电子邮件时,您将无法立即看到新电子邮件。

但是,如今的浏览器已经变得足够聪明,他们正在尝试缩短重新粉刷屏幕所需的时间。可以做的最大的事情就是最小化和批处理进行重绘的DOM更改。

减少和消除对另一种抽象层次的DOM更改的策略是React的Virtual DOM背后的思想。

是什么让React的虚拟DOM如此之快?

React并没有做任何新的事情。这只是一项战略举措。它的作用是将真实DOM的副本存储在内存中。修改DOM时,它首先将这些更改应用于内存中的DOM。然后,使用它的差异算法,找出真正发生了什么变化。
最后,它批量更改并调用一次将它们应用于实际。因此,最大程度地减少了重焊和重涂。

参考

Understanding Repaint and Reflow in JavaScript

你可能感兴趣的:(了解JavaScript中的重绘和重排)