AngularJS 性能優化二三事
在過去的兩年中,angularjs 的使用率有了很大的提升。簡單的雙向綁定是促使其流行的主要原因之一,但與此同時,它導致了在一個應用中出現了大量的 watcher。在后臺,angularJS 會執行所謂的 “臟值檢查”。之所以要做臟值檢查目的是為了檢查在 “scope” 中的數據是否發生了變化;框架必須周期性的檢測數據是否發生了變化… 臟值檢查會每 40ms 更新一次.. 想想看.. 如果它需要檢查超多數據的時候; Crap!!
讓我們來看看如何改善 angularJS 的性能..
減少 watcher 數量
可能很多人都會抱怨 angular js 應用的性能; 特別是當他們用了 ng-repeat 的時候;為什么會這樣? Watcher 應該是這背后的主要原因。一個 angular 指令會產生一個 watcher (比如 ng-src;ng-href;)
下面的例子很詳細的解釋了這種情況
http://plnkr.co/edit/jwrHVb?p=preview
看看上面的例子,你加載的數據越多; 產生的 watchers 就越多;
解決方案
通過使用 bindonce 指令來避免使用雙向綁定; 當你不需要雙向綁定的時候,試試看用 bindonce 指令,比如 bo-if; bo-show; 看看下面這個精簡過 watcher 數量的例子
http://plnkr.co/edit/0DGOrk?p=preview
文檔和源碼放在這里
https://github.com/Pasvaz/bindonce
延遲加載 angular controller
在初始化的時候加載控制器對小應用來說很合適;但是如果應用的 scope 很大怎么辦?
如果我們在特定頁面初始化的時候,把控制器動態的加載到我們的 DOM 上會怎樣? 很贊,對不對?
如果這些控制器是在特定頁面加載之后,動態的加載到 DOM 上的話; 不單應用的初始化會很快; 而且也會降低在 DOM 中生成的對象數量;
下面例子是如何動態加載控制器到 DOM
https://github.com/ifyio/angularjs-lazy-loading-with-requirejs
刪除那些不在你 viewport 中的,多余的 html 對象
對于不定長列表最常見的問題…. 尤其是在用 ng-repeat 的時候; 就是你必須把所有數據都加載進來,即使你只需要顯示其中一部分數據; 每次重復會生成至少同樣數量的 watcher;
所以為什么不只加載顯示所必要的那部分數據呢。是不是很 Crazyyyyyyyyyy?試試這個
https://github.com/angular-ui/ui-utils/blob/master/modules/scroll/README.md
這個指令只加載那些在 viewport 中的對象,并清除那些看不到的;
這不僅僅削減了watcher數量,同時也降低了瀏覽器中 DOM 的大小。是不是超酷?
你覺得呢?告訴我唄。