Angular2 - 繁重的计算 + 加载程序显示/隐藏 - 我的 DOM 与页面上的内容不匹配

Angular2 - heavy computation + loader show / hide - my DOM doesn't match what's on the page

我在 Angular 2 中工作,试图在大量计算之前显示加载器并在之后隐藏它。当我显示加载程序时,DOM 正在更新,但视图没有重新绘制。因此,我的加载程序从未出现。

完整代码为 here.

这怎么可能?

问题

问题是我的浏览器因繁重的计算而冻结。浏览器在我显示加载程序后没有机会重新绘制,因为当它尝试重新绘制时,繁重的计算阻塞了堆栈。


我们想要的堆栈

  1. 加载程序显示
  2. 浏览器重绘
  3. 计算量大
  4. 加载器隐藏
  5. 浏览器重绘

换句话说,我们要确保在繁重的计算(我将调用此函数 "H")进入堆栈之前,加载程序 reveal 进入堆栈,这样 "H" 就不会在浏览器尝试重绘时阻塞堆栈。


我们如何将其放入堆栈

我通过观看 brilliant video 关于异步/事件循环/任务队列等的内容找到了解决方案

解决方法是:

<loader-show>
setTimeout(() => {
   <heavy-computation>
   <loader-hide>
}, 20)

将 "H" 和加载程序都隐藏在 setTimeout 中。这样loader reveal会进栈,然后"H"和loader hiding会进任务队列,只有当栈为空(即after loader reveal).

但注意到 setTimeout 中的“20”毫秒延迟?视频中的另一个关键元素是

the browser repaints every 16 milliseconds

意味着我的 setTimeout 必须延迟 >16 秒才能 确保 浏览器将在 "H" 执行和阻止之前重新绘制视图堆栈。


其他提示

  • 将繁重的计算移至后端。
  • 使用 CSS-based 装载程序。

参考代码

Here是解出来的代码