与Web worker,快速计时器和$ scope一起遇到AngularJS性能问题。$ apply()

时间:2015-02-13 09:32:49

标签: javascript angularjs performance twitter-bootstrap web-worker

我有一个计时器,它运行在一个间隔为10毫秒的Web worker中。每次计时器滴答时,在控制器中调用一个函数,该函数递增一个变量。该变量由我页面上的引导进度条使用。

我遇到的问题是进度条没有更新,除非我在函数调用中调用$ scope。$ apply(),其中值被更新。

同时,我有一个数组,其中有一堆复杂的对象(100多个对象)在$ scope上。因为我需要调用$ scope。$ apply()以便每当我的计时器滴答时让视图进行更改,它也会更新这个对象列表(每10ms),这会减慢我的应用程序。

有没有人对如何解决这个问题有任何想法?如果我能提供更多详细信息,请通知我。

3 个答案:

答案 0 :(得分:0)

如果您知道变量只需要在某个$scope中进行更新,则可以在$scope.$digest()上调用$scope。与$apply()相反,$digest()只会在$scope(及其子项)上运行观察者,而不是整个应用程序。

答案 1 :(得分:0)

每10毫秒更新一次非常频繁。如果一切都保持不变,这将是每秒100次更新:大约是许多视频格式的帧速率的4倍。加快速度的一种非常简单的方法是大幅减少这种情况。

我可以想到的一种可能适合大多数架构的方法是使用节流功能,例如来自lodash的`_.throttle':

var throttledApply = _.throttle($scope.apply, 500);

然后当你收到消息时,你会有类似的东西:

worker.onmessage = function(e) {
  // ... Other processing code ...
  throttledApply();
};

如果您正在使用Bootstrap进度条,它仍应在显示的值之间平滑过渡,即使它们之间的差异很大。

答案 2 :(得分:0)

如果100个对象的元素在任何时候都不是在屏幕上实际可见,那么你只能在屏幕上包含那些元素(因此只有观察者可以使用它们),例如{{{ 3}}(我的一位同事不得不轻微破解它以使其完全按照需要进行操作:我忘记了细节)