最近在开发Hybrid APP (我用的是Ionic Frameworks) 的过程中,随着首页栏目的逐渐增加,APP在手机上的执行效率越来越低,有时在切换频道的时候会有明显的卡顿和执行延迟。
在检查完代码逻辑和算法后,并没有发现什么问题 (网络通讯,本地缓存)。最近在翻阅代码的过程中,突然意识到可能是由于频道增加,页面中双向绑定使用数量变多,导致 AngularJS 在作 digest loop
的时候,由于 $$watchers
数量过多导致程序变慢。
要想确定猜想,需要先能统计到页面中随着频道进入$$watchers
的数量,于是写了如下代码,在Chrome的控制台中执行,便可以方便的进行统计。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| function getWatchers(root) { root = angular.element(root || document.documentElement); var watcherCount = 0;
function getElemWatchers(element) { var isolateWatchers = getWatchersFromScope(element.data().$isolateScope); var scopeWatchers = getWatchersFromScope(element.data().$scope); var watchers = scopeWatchers.concat(isolateWatchers); angular.forEach(element.children(), function (childElement) { watchers = watchers.concat(getElemWatchers(angular.element(childElement))); }); return watchers; }
function getWatchersFromScope(scope) { if (scope) { return scope.$$watchers || []; } else { return []; } }
return getElemWatchers(root); } getWatchers().length
|
随即发现,在频道页面不断加载的过程中, $$watchers
的数量在不断增加,最多的时候有 5000个之多。
发现问题就好解决了。由于频道内容列表页面在一次加载后就不需要再进行变化监听,所以这里打算对代码中的data-binding
部分使用 bindonce 的方式解决。
这里还有两个关于 bindonce 的示例:
使用AngularJS 原有Bind
使用Bindonce