AngularJS做爲強大的前端MVVM框架,雖然已經作了不少的性能優化,可是咱們開發過程當中的不當使用仍是會對性能產生巨大影響。javascript
下面提出幾點優化的方法:css
1. 使用單次綁定符號{{::value}}html
AngularJS的性能優化方法之一是減小雙向綁定。咱們知道AngularJS的雙向綁定是經過爲每一個須要雙向綁定的數據對象添加$$watchers,一旦某個scope的數據發生了更新,就觸發髒檢測($digest),深度優先遍歷全部scope對象的$$watchers值的old/new value是否發生變化。因此在開發過程當中,咱們都要當心判斷建立出的每一個$$watchers是否有必要。對於只須要更新一次,之後無論數據層如何變化都不須要更新的數據,使用連續兩個冒號便可在在$$watchers列表中將這個值刪除,即減小了$digest髒檢測循環。前端
2. ng-repeat優化java
第一種方式雖然減小了髒檢測的次數,可是單次綁定的數據畢竟少數,可能加完單次綁定,性能提高並無太大。若是咱們的代碼中使用了ng-repeat,而且list數量很大時,咱們的性能會有很大降低,在移動端尤其明顯。下面幾點是對ng-repeat指令的優化。性能優化
<li ng-repeat="mail in mails |limitTo:loadMailLimitTo"></li>
<ul> <li ng-repeat="mail in mails"> {{mail.id}}:{{mail.title}} </li> </ul>
若是咱們想更新mails裏面的值,咱們可能會這麼作:服務器
1
|
$scope.mails = newMailListFromServer;
|
上一行代碼會告訴ng-repeat去刪除掉全部的li元素,再去從新生成一套新的li,這意味着大量的DOM操做,尤爲當li元素裏面有 複雜的邏輯判斷和雙向綁定數據。這是由於ng-repeat在建立時會給每一個mail加上$hashkey屬性,並時時跟蹤,一旦mails元素替換成服務器 返回的對象,即時他們徹底同樣,因爲他們沒有$hashkey,因此ng-repeat不會知道他們是同樣的元素。而經過以下的改動:app
<li ng-repeat="mail in mails track by mail.id"></li>
ng-repeat會跟蹤咱們建立的mail.id去判斷是否爲新的元素。這樣就減小了大量的DOM刪減添加操做。
須要注意的是,若是limitTo和track by一塊兒使用的時候,須要把track by放到最後,如框架
<li ng-repeat="mail in mails | limitTo:loadMailLimitTo track by mail.id"></li>
collection-repeat是ionic框架本身的一套顯示list的指令,原理在於不論list有多大,頁面最多隻有必定數量的item,這個item數量的大小是經過屏幕高度和單個item的高度計算出來的。滑動列表時經過更新item元素的頁面內容和位置來呈現全部的items。因此在大數量級的list呈現上,collection-repeat會比ng-repeat性能好不少。可是須要注意的是,因爲collection-repeat是經過時時更新滑動位置的item內容來實現的,因此在item內部使用第一個方法的單次綁定方式,滑動後會形成頁面混亂的狀況。ionic
3. 減小html頁面中的filter
緣由是每當filter執行時,都會走兩次$digest cycle,一次是scope中有數據改動,一次是查看是否有更多的改動須要更新數據。當數據量很大時對性能會有很大影響。咱們能夠在初始化時就格式化好數據,好比賦值到view層以前,在咱們的js代碼裏使用angular提供的$filter provider來預處理咱們的數據。
4. ng-if替代ng-show/ng-hide
緣由是ng-if與ng-show/ng-hide的不一樣之處在於,ng-if在等於false時會把元素從DOM中移除,因此全部綁在該元素上的handler會一同失效。而ng-show/ng-hide不會移除DOM元素,而是使用css style去隱藏/顯示DOM元素,因此handlers會一直存在。
5. $scope.$apply()和$scope.$digest()
咱們會用到上面兩種去執行一次髒檢測,刷新頁面數據。區別就是$scope.$apply()會從$rootscope開始,深度優先遍歷執行$digest循環,而$scope.$digest會從當前scope開始,往下層scope遍歷髒檢測。若是隻是指望當前scope的數據更新,而不涉及到parent $scope,則可使用$scope.$digest()。
6. angular animate
若是咱們的項目引入了angular-animate.js的模塊,那麼在大部分使用了指令的元素上,animate裏面的代碼都會被執行,無論當前元素是否有應用css動畫樣式。這對咱們頁面上若是有大量數據頻繁滑動,隱藏顯示的時候會有比較明顯的性能問題。若是咱們對當前scope並無漸入漸出等動畫效果的時候,能夠在當前scope初始化時加上$animate.enabled(false);固然,咱們也能夠對某個元素進行禁止動畫的動做:$animate.enabled(element, false);
7. ionicSlideBox優化(只針對使用了ionic框架的項目)