基於AngularJS/Ionic架構開發的效能最佳化

來源:互聯網
上載者:User

標籤:hash   其他   高度   padding   更新   div   element   期望   apply   

AngularJS作為強大的前端MVVM架構,雖然已經做了很多的效能最佳化,但是我們開發過程中的不當使用還是會對效能產生巨大影響。

 

下面提出幾點最佳化的方法:

1. 使用單次綁定符號{{::value}}

AngularJS的效能最佳化方法之一是減少雙向繫結。我們知道AngularJS的雙向繫結是通過為每個需要雙向繫結的資料對象添加$$watchers,一旦某個scope的資料發生了更新,就觸發髒檢測($digest),深度優先遍曆所有scope對象的$$watchers值的old/new value是否發生變化。所以在開發過程中,我們都要小心判斷建立出的每個$$watchers是否有必要。對於只需要更新一次,以後不管資料層如何變化都不需要更新的資料,使用連續兩個冒號即可在在$$watchers列表中將這個值刪除,即減少了$digest髒檢測迴圈。

2. ng-repeat最佳化

第一種方式雖然減少了髒檢測的次數,但是單次繫結資料畢竟少數,可能加完單次綁定,效能提升並沒有太大。如果我們的代碼中使用了ng-repeat,並且list數量很大時,我們的效能會有很大下降,在移動端尤為明顯。下面幾點是對ng-repeat指令的最佳化。

  • 使用limitTo來減少第一次載入列表元素的數量,以提高初始化頁面的速度。我們也許有上百上千條資料要顯示,但是螢幕的大小畢竟有限,呈現在使用者眼前的可能就是個1280x800或者360x640大小的螢幕,那我們可以先載入使用者所能看到幾個十幾個列表。limitTo屬性就提供了這樣的功能。
  <li ng-repeat="mail in mails |limitTo:loadMailLimitTo"></li>
  • 使用track by屬性。比如我們有下面一段代碼
<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不會知道他們是一樣的元素。而通過如下的改動:

<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>
  • 如果有引入ionic架構,可以使用collection-repeat替代ng-repeat。

collection-repeat是ionic架構自己的一套顯示list的指令,原理在於不論list有多大,頁面最多隻有一定數量的item,這個item數量的大小是通過螢幕高度和單個item的高度計算出來的。滑動列表時通過更新item元素的頁面內容和位置來呈現所有的items。所以在大數量級的list呈現上,collection-repeat會比ng-repeat效能好很多。但是需要注意的是,由於collection-repeat是通過時時更新滑動位置的item內容來實現的,所以在item內部使用第一個方法的單次綁定方式,滑動後會造成頁面混亂的情況。

 

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架構的項目)

  • 初始化slidebox時先初始化顯示中間的首先顯示在使用者面前的slide,其他的slide可以在$timeout裡面延遲初始化。思想和ng-repeat的limitTo比較類似。
  • slidebox的滑動速度在ionic架構中預設速度是300ms滑完一個slide,通過改變這個速度來使滑動更快速。

基於AngularJS/Ionic架構開發的效能最佳化

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.