简体   繁体   English

如何在DOM注入之后和大规模DOM操作之前强制浏览器重绘(setTimeout无效)

[英]How to force browser repaint right after DOM injection and before massive DOM manipulation (setTimeout doesn't help)

I'm displaying a large table and I'd like to show loading overlay during re-rendering (reordering of columns, applying filter). 我正在显示一张大桌子,我想在重新渲染(列重新排序,应用过滤器)期间显示加载叠加层。 Funny but window.setTimeout doesn't help. 有趣,但是window.setTimeout没有帮助。 Seems like browser rendering gets so seriously delayed it catches up with timeout delayed render events and still finishes everything in an optimized single paint batch. 似乎浏览器渲染如此严重地延迟,以赶上超时延迟的渲染事件,并且仍然可以在优化的单个绘画批处理中完成所有操作。 Question is relevant to newest stable Chrome and Firefox. 问题与最新的稳定的Chrome和Firefox有关。

this.fader.show();
window.setTimeout(function(){
    self._reshuffleMenu();
    self.table.fnDraw();
}, 100);
    window.setTimeout(function(){
    self.fader.hide();
}, 200);

So any option to control browser rendering queue? 那么有什么方法可以控制浏览器渲染队列?

Observations: 观察:

  • Chrome is stable for ommitting setTimout queued actions, while Firefox shows split behavior - sometimes paints loading overlay, sometimes ommits it. Chrome可以稳定地忽略setTimout排队的操作,而Firefox显示拆分行为-有时绘制加载叠加层,有时忽略它。

Notes: 笔记:

  • I've started with timeout set to 0, but even with 100ms rendering still queues up 我开始将超时设置为0,但是即使100ms渲染仍然排队
  • Starting a page with loading placeholder and replacing it with table rows is not an option, cause I need indicator to show up on table changes, not initial load 用加载占位符开始页面并将其替换为表行不是一种选择,因为我需要指示器来显示表更改,而不是初始加载

Javascript runtime is implemented as a single-threaded language in most of the browsers, so setTimeout is no exception from that. Javascript运行时在大多数浏览器中都是作为单线程语言实现的,因此setTimeout也不例外。 When your rendering is finished then runtime engine checks for timout events, and triggers them. 渲染完成后,运行时引擎将检查是否有timout事件,并触发它们。

Perhaps you can find more answers here: 也许您可以在这里找到更多答案:

why Javascript SetTimeout() is not multithreaded 为什么Javascript SetTimeout()不是多线程的

I was able to achieve desired behavior via requestAnimationFrame . 我能够通过requestAnimationFrame实现所需的行为。 The technique is based on calling first frame for overlay display, and doing rest of heavy rendering in next request. 该技术基于调用第一帧进行叠加显示,并在下一个请求中进行其余的繁重渲染。

requestAnimationFrame(function(){
     mvc.Fader.show(self.region);
     requestAnimationFrame(callback);
});

During research I've found this How to test (automatedly) that an operation occurs after browser repaint? 在研究过程中,我发现了“ 如何测试(自动)浏览器重绘后是否发生操作”? that gave me a hint to requestAnimationFrame. 这给了我提示requestAnimationFrame的提示。 Links lists 2 more tricks that I haven't tried yet. 链接列出了2个我还没有尝试过的技巧。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM