一尘不染

JavaScript是否使用弹性跑道算法进行处理

algorithm

我正在尝试制定一种有效的算法来更改一堆节点上的许多类,并且我发现我对javascript如何遍历DOM有很大的洞。

浏览器/ JavaScript是否使用Flash等弹性赛道?还是由事件驱动,每次更改时都会重新绘制整个显示?

“弹性跑道”是一种闪光范式,您可以在其中想象到一个很大的大圈,它周围会闪烁。在用户处理期间,会建立更改,而在闪存处理期间,Flash引擎会四处运行并反复应用所有更改。

另一种选择是事件模型,其中每次属性更改时,整个屏幕都会重绘-这可能是浏览器的工作,但我不确定。

我可以想到混合算法,如果没有变化,什么也不会发生-但是如果允许它们建立起来-就像我的水槽上的盘子一样。

是否有人对用于处理属性更改和DOM插入的算法有一个简短的描述。


阅读 208

收藏
2020-07-28

共1个答案

一尘不染

Flash的“弹性跑道”是从浏览器继承的。当然,在浏览器范围内,我们不会这样称呼-我们将其称为事件循环。

javascript事件循环的历史始于在Netscape上进行渐进式GIF和JPEG渲染。渐进式渲染(部分加载内容的绘图)是Netscape实施异步下载渲染引擎所必需的。当Brendan
Eich实现javascript时,该异步事件循环已经存在。因此,向其添加另一层是一项相当简单的任务。

因此,浏览器的事件循环如下所示:

    Event loop
        ┌──────────┐
        │          │
        │          │
        │          ▼
        │        check if there's any new ───────▶ parse data
        │        data on the network                    │
        │          │                                    │
        │          ▼                                    │
        │        check if we need to execute  ◀─────────┘
        │        any javascript ──────────────────▶ execute
        │          │                               javascript
        │          ▼                                  │
        │        check if we need to ◀────────────────┘
        │        redraw the page  ──────────────▶ redraw page
        │          │                                   │
        │          │                                   │
        └────◀─────┴─────────────────◀─────────────────┘

其余的,正如他们所说,是历史。当Microsoft复制javascript时,他们不得不复制事件循环以保持与Netscape的兼容性。因此,形式上每个人都必须做同样的事情以保持与Netscape和IE的兼容性。

请注意,JavaScript没有任何功能可以手动递归到事件循环中(某些语言,例如tcl,可以做到),因此浏览器必须等到没有其他javascript执行后才能重画页面。在脚本结束之前不能强制进行页面重绘。

因此,当您尝试在创建后立即读取它们时,诸如元素的宽度或高度之类的计算值有时会返回错误的值-
浏览器尚未绘制它们。如果您确实需要在页面重绘后执行代码,则解决方法是setTimeout使用超时值为0的a来允许浏览器运行事件循环的一轮。


其他细节:

似乎有一种例外情况会触发昂贵的回流。请注意,重排是浏览器计算页面布局。如果浏览器需要绘制更改的页面,通常会触发该事件。

当页面中的某些内容发生更改时,将对重排计算进行排队-
不会立即执行。如以上说明中所述,重排将仅在javascript执行结束时执行。但是有一种情况会导致浏览器立即执行重排计算:如果您尝试读取任何计算出的值,例如宽度和高度。

2020-07-28