我正在研究增强角度消化循环的选项。
我有一个相当复杂的应用程序,在任何给定时间都有成千上万的活跃观察者。
作为app的功能的一部分,我正在注册滚动事件(并在动画帧中处理它们),因此摘要基本上在每个滚动上执行,这导致fps偶尔下降。
我通过一次性绑定减少了观察者数量,现在我只剩下几千名观察者。
目前我正在尝试编写一个指令来暂停视口元素之外的所有观察者。
所以我开始玩角形内部并提出以下指令:
app.directive('ngSuspendable', function () {
return {
restrict: 'A',
scope: true,
link: function (scope, element, attr) {
var _watchersMap = {};
var _suspended = true;
suspendWatchersTree();
function suspendWatchersTreeRecursive(currentScope, includeSiblings) {
while (currentScope != null) {
if ((currentScope.$$watchers != null) &&
(currentScope.$$watchers.length > 0) &&
(typeof _watchersMap[currentScope.$id] == "undefined")) {
_watchersMap[currentScope.$id] = currentScope.$$watchers;
currentScope.$$watchers = [];
}
if (currentScope.$$childHead != null) {
suspendWatchersTreeRecursive(currentScope.$$childHead, true);
}
if (includeSiblings) {
currentScope = currentScope.$$nextSibling;
}
else {
currentScope = null;
}
}
}
function unsuspendWatchersTreeRecursive(currentScope, includeSiblings) {
while (currentScope != null) {
if ((typeof _watchersMap[currentScope.$id] != "undefined") &&
(_watchersMap[currentScope.$id].length > 0)) {
if ((currentScope.$$watchers != null) &&
(currentScope.$$watchers.length > 0)) {
currentScope.$$watchers = currentScope.$$watchers.concat(_watchersMap[currentScope.$id]);
}
else {
currentScope.$$watchers = _watchersMap[currentScope.$id];
}
}
if (currentScope.$$childHead != null) {
unsuspendWatchersTreeRecursive(currentScope.$$childHead, true);
}
if (includeSiblings) {
currentScope = currentScope.$$nextSibling;
}
else {
currentScope = null;
}
}
}
function suspendWatchersTree() {
suspendWatchersTreeRecursive(scope, false);
}
function unsuspendWatchersTree() {
unsuspendWatchersTreeRecursive(scope, false);
}
scope.inView = function(evnt, model, htmlElementId, triggeringEvent, isInView, inViewPart) {
if (!isInView) {
suspendWatchersTree();
_suspended = true;
}
if ((isInView) && (_suspended)) {
unsuspendWatchersTree();
_watchersMap = {};
_suspended = false;
}
}
}
}
});
初始化时,该指令从当前作用域和所有子作用域中删除所有观察者(不确定它是否也捕获了孤立的作用域)。 然后,当元素在视图中时,它会添加回观察者,并在视野之外将其删除。
我知道它并不一定会捕获所有观察者,因为一些观察者可能会在链接后添加,但这似乎可以忽略不计,并且一旦元素进入视图并再次出现,它们将被删除。如果我可以以某种方式挂钩观察者的添加并将其添加到地图上,当被怀疑可能很好但我想它不是必须的。
这似乎运作良好,但我不确定这种方法的注意事项。我喜欢玩角形内部和弄乱东西并达到不稳定的条件。
非常感谢任何想法和评论。
答案 0 :(得分:0)
我已使用最新更改更新了上述代码。 进一步测试显示它运行良好,一些手表可能不会在初始化时暂停,但这是我可以忍受的价格。它大大增强了我的摘要循环,并通过删除视口元素之外的不需要的手表来提升应用程序性能。