javascript - javascript是否使用弹性赛道算法进行处理

标签 javascript performance algorithm dom

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

浏览器/javascript 是否像 flash 一样使用弹性跑道?或者是更多的事件驱动,每次有变化时整个显示都会重新绘制?

“弹性跑道”是一种闪光范例,您可以在其中想象一个巨大的大环,闪光环绕着它。在用户处理时间期间,更改会累积,而在 Flash 处理时间期间,Flash 引擎会反复运行并应用所有更改。

另一种方法是事件模型,每次属性更改时都会重新绘制整个屏幕 - 这可能是浏览器所做的,但我不确定。

我可以想到混合算法,如果没有变化,什么也不会发生——但如果有变化,它们就可以累积起来——有点像我水槽上的盘子。

有没有人能快速描述用于处理属性更改和 DOM 插入的算法。

最佳答案

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 可以执行才重绘页面。在脚本结束之前不能强制重绘页面。

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


其他详细信息:

似乎有一种异常情况会触发昂贵的回流。请注意,重排是浏览器计算页面布局。它通常在浏览器需要绘制更改后的页面时触发。

当页面中的某些内容发生变化时,回流计算会排队 - 不会立即执行。正如上面的描述,回流只会在 javascript 执行结束时执行。但是有一种情况会导致浏览器立即执行回流计算:如果您尝试读取任何计算值,例如宽度和高度。

有关更多信息,请参阅此相关问题:When does reflow happen in a DOM environment?

关于javascript - javascript是否使用弹性赛道算法进行处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19616477/

相关文章:

javascript - jQuery .html() 和 .append() 呈现内容的方式与 HTML DOM innerHTML 属性不同

javascript - 绑定(bind)范围对象的 Angularjs 数学

c# - while 循环中的高 CPU 使用率,正在检查按键事件

java - 使用java监控unix系统性能

algorithm - 了解涉及列表附加(使用@)的递归 SML 函数的运行时

Python:math.factorial 是否已内存?

javascript - 将变量发送到另一个 php 文件

javascript - 动态类: are they prepended or appended?

android - 如何连接2个文件

java - Mergesort 实现.. 计算数组中的反转次数