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

时间:2013-10-27 09:23:40

标签: javascript performance algorithm dom

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

浏览器/ javascript是否使用像闪存一样的弹性赛道?或者它是更多的事件驱动,每次有变化时重绘整个显示?

“弹性赛道”是一个闪光范例,你可以想象一个闪烁的大循环。在用户处理期间,时间变化积累,并且在闪存处理期间,闪存引擎会四处奔跑并一遍又一遍地应用所有更改。

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

我可以想到混合算法,如果没有任何变化,没有任何事情发生 - 但是如果它们被允许建立 - 有点像我的水槽上的菜肴。

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

1 个答案:

答案 0 :(得分:6)

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?