自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

對AngularJS進(jìn)行性能調(diào)優(yōu)的7個建議

開發(fā) 后端 前端
AnglarJS作為一款優(yōu)秀的Web框架,可大大簡化前端開發(fā)的負(fù)擔(dān)。近日Sebastian Fröstl在一篇博文《AngularJS Performance Tuning for Long Lists》中表示AnglarJS在處理包含復(fù)雜數(shù)據(jù)結(jié)構(gòu)的大型列表時,其運行速度會非常慢。他在文中同時分享了解決方案。

AnglarJS作為一款優(yōu)秀的Web框架,可大大簡化前端開發(fā)的負(fù)擔(dān)。近日Sebastian Fröstl在一篇博文《AngularJS Performance Tuning for Long Lists》中表示AnglarJS在處理包含復(fù)雜數(shù)據(jù)結(jié)構(gòu)的大型列表時,其運行速度會非常慢。他在文中同時分享了解決方案。下面為該文的譯文。

AnglarJS很棒,但當(dāng)處理包含復(fù)雜數(shù)據(jù)結(jié)構(gòu)的大型列表時,其運行速度就會非常慢。這是我們將核心管理頁面遷移到AngularJS過程中遇到的問題。這些頁面在顯示500行數(shù)據(jù)時本應(yīng)該工作順暢,但首個方法的渲染時間竟花費了7秒,太可怕了。

后來,我們發(fā)現(xiàn)了在實現(xiàn)過程中存在兩個主要性能問題。一個與“ng-repeat ”指令有關(guān),另一個與過濾器有關(guān)。

下文將分享我們通過不同的方法解決性能問題的經(jīng)驗,希望可以給你帶來啟示。

一、AngularJS 中的ng-repeat在處理大型列表時,速度為什么會變慢?

AngularJS中的ng-repeat在處理2500個以上的雙向數(shù)據(jù)綁定時速度會變慢。這是由于AngularJS通過“dirty checking”函數(shù)來檢測變化。每次檢測都會花費時間,所以包含復(fù)雜數(shù)據(jù)結(jié)構(gòu)的大型列表將降低你應(yīng)用的運行速度。

二、提高性能的先決條件

時間記錄指令

為了測量一個列表渲染所花費的時間,我們寫了一個簡單的程序,通過使用“ng-repeat”的屬性“$last”來記錄時間。時間存放在TimeTracker服務(wù)中,這樣時間記錄就與服務(wù)器端的數(shù)據(jù)加載分開了。

  1. // Post repeat directive for logging the rendering time   
  2. angular.module('siApp.services').directive('postRepeatDirective',   
  3.   ['$timeout''$log',  'TimeTracker',   
  4.   function($timeout, $log, TimeTracker) {   
  5.     return function(scope, element, attrs) {   
  6.       if (scope.$last){   
  7.          $timeout(function(){   
  8.              var timeFinishedLoadingList = TimeTracker.reviewListLoaded();   
  9.              var ref = new Date(timeFinishedLoadingList);   
  10.              var end = new Date();   
  11.              $log.debug("## DOM rendering list took: " + (end - ref) + " ms");   
  12.          });   
  13.        }   
  14.     };   
  15.   }   
  16. ]);   
  17.     
  18. // Use in HTML:   
  19. <tr ng-repeat="item in items" post-repeat-directive>…</tr>   

Chrome開發(fā)者工具的時間軸(Timeline)屬性

在Chrome開發(fā)者工具的時間軸標(biāo)簽中,你可以看見事件、每秒內(nèi)瀏覽器幀數(shù)和內(nèi)存分配。“memory”工具用來檢測內(nèi)存泄漏,及頁面所需的內(nèi) 存。當(dāng)幀速率每秒低于30幀時就會出現(xiàn)頁面閃爍問題。“frames”工具可幫助了解渲染性能,還可顯示出一個JavaScript任務(wù)所花費的CPU時 間。

三、通過限制列表的大小進(jìn)行基本的調(diào)優(yōu)

緩解該問題,最好的辦法是限制所顯示列表的大小??赏ㄟ^分頁、添加無限滾動條來實現(xiàn)。

分頁

分頁,我們可以使用AngularJS的“limitTo”過濾器(AngularJS1.1.4版本以后)和“startFrom”過濾器。可以通過限制顯示列表的大小來減少渲染時間。這是減少渲染時間最高效的方法。

  1. // Pagination in controller   
  2. $scope.currentPage = 0;   
  3. $scope.pageSize = 75;   
  4. $scope.numberOfPages = function() {   
  5.     return Math.ceil($scope.displayedItemsList.length/ $scope.pageSize);   
  6. };   
  7.     
  8. // Start from filter   
  9. angular.module('app').filter('startFrom'function() {   
  10.     return function(input, start) {           
  11.         return input.slice(start);   
  12. };   
  13.     
  14. // Use in HTML   
  15. // Pagination buttons   
  16. <button ng-repeat="i in getNumber(numberOfPages()) track by $index" ng-click="setCurrentPage($index)">{{$index + 1}}</button   
  17.     
  18. // Displayed list   
  19. <tr ng-repeat="item in displayedItemsList | startFrom: currentPage * pageSize  | limitTo:pageSize" /tr>   

如果你不能/不想使用分頁,但過濾過程又很慢,這時一定要檢查前五步,并使用“ng-show”隱藏掉多余的列表元素。

無限滾動條

如果你希望進(jìn)一步了解該方法,可訪問 http://binarymuse.github.io/ngInfiniteScroll/

四、七大調(diào)優(yōu)法則

1. 渲染沒有數(shù)據(jù)綁定的列表

這是最明顯的解決方案,因為數(shù)據(jù)綁定是性能問題最可能的根源。如果你只想顯示一次列表,并不需要更新、改變數(shù)據(jù),放棄數(shù)據(jù)綁定是絕佳的辦法。不過可惜的是,你會失去對數(shù)據(jù)的控制權(quán),但除了該法,我們別無選擇。進(jìn)一步了解: https://github.com/Pasvaz/bindonce。

2.不要使用內(nèi)聯(lián)方法計算數(shù)據(jù)

為了在控制器中直接過濾列表,不要使用可獲得過濾鏈接的方法。“ng-repeat”會評估每個 [$digest(http://docs.angularjs.org/api/ng.$rootScope.Scope#$digest)%5D表達(dá)式。在我們的案例中,“filteredItems()”返回過濾鏈接。如果評估過程很慢,它將迅速降低整個應(yīng)用的速度。

  1. <li ng-repeat="item in filteredItems()">//這并不是一個好方法,因為要頻繁地評估。   
  2. <li ng-repeat="item in items">//這是要采用的方法   

3.使用兩個列表(一個用來進(jìn)行視圖顯示,一個作為數(shù)據(jù)源)

將要顯示的列表與總的數(shù)據(jù)列表分開,是非常有用的模型。你可以對一些過濾進(jìn)行預(yù)處理,并將存于緩存中的鏈接應(yīng)用到視圖上。下面案例展示了基本實現(xiàn)過程。filteredLists變量保存著緩存中的鏈接,applyFilter方法來處理映射。

  1. /* Controller */   
  2. // Basic list   
  3. var items = [{name:"John", active:true }, {name:"Adam"}, {name:"Chris"}, {name:"Heather"}];   
  4.     
  5. // Init displayedList   
  6. $scope.displayedItems = items;   
  7.     
  8. // Filter Cache   
  9. var filteredLists['active'] = $filter('filter)(items, {"active" : true});   
  10.     
  11. // Apply the filter   
  12. $scope.applyFilter = function(type) {   
  13.     if (filteredLists.hasOwnProperty(type){ // Check if filter is cached   
  14.         $scope.displayedItems = filteredLists[type];   
  15.     } else {   
  16.         /* Non cached filtering */   
  17.     }   
  18. }   
  19.     
  20. // Reset filter   
  21. $scope.resetFilter = function() {   
  22.     $scope.displayedItems = items;   
  23. }   
  24.     
  25. /* View */   
  26. <button ng-click="applyFilter('active')">Select active</button>   
  27. <ul><li ng-repeat="item in displayedItems">{{item.name}}<li></ul>   

#p#

4.在其他模板中使用ng-if來代替ng-show

如果你用指令、模板來渲染額外的信息,例如通過點擊來顯示列表項的詳細(xì)信息,一定要使用  ng-if(AngularJSv. 1.1.5以后)。ng-if可阻止渲染(與ng-show相比)。所以其它DOM和數(shù)據(jù)綁定可根據(jù)需要進(jìn)行評估。

  1. <li ng-repeat="item in items">   
  2.     <p> {{ item.title }} </p>   
  3.     <button ng-click="item.showDetails = !item.showDetails">Show details</buttons>   
  4.     <div ng-if="item.showDetails">   
  5.         {{item.details}}   
  6.     </div>   
  7. </li>   

5.不要使用ng-mouseenter、ng-mouseleave等指令

使用內(nèi)部指令,像ng-mouseenter,AngularJS會使你的頁面閃爍。瀏覽器的幀速率通常低于每秒30幀。使用jQuery創(chuàng)建動畫、鼠標(biāo)懸浮效果可以解決該問題。確保將鼠標(biāo)事件放入jQuery的.live()函數(shù)中。

6.關(guān)于過濾的小提示:通過ng-show隱藏多余的元素

對于長列表,使用過濾同樣會減低工作效率,因為每個過濾都會創(chuàng)建一個原始列表的子鏈接。在很多情況下,數(shù)據(jù)沒有變化,過濾結(jié)果也會保持不變。所以對數(shù)據(jù)列表進(jìn)行預(yù)過濾,并根據(jù)情況將它應(yīng)用到視圖中,會大大節(jié)約處理時間。

在ng-repeat指令中使用過濾器,每個過濾器會返回一個原始鏈接的子集。AngularJS 從DOM中移除多余元素(通過調(diào)用 $destroy),同時也會從$scope中移除他們。當(dāng)過濾器的輸入發(fā)生改變時,子集也會隨著變化,元素必須進(jìn)行重新鏈接,或著再調(diào) 用$destroy。

大部分情況下,這樣做很好,但一旦用戶經(jīng)常過濾,或者列表非常巨大,不斷的鏈接與銷毀將影響性能。為了加快過濾的速度,你可以使用ng-show 和ng-hide指令。在控制器中,進(jìn)行過濾,并為每項添加一個屬性。依靠該屬性來觸發(fā)ng-show。結(jié)果是,只為這些元素增加ng-hide類,來代 替將它們移除子列表、$scope和DOM。

觸發(fā)ng-show的方法之一是使用表達(dá)式語法。ng-show的值由表達(dá)式語法來確定。可以看下面的例子:

  1. <input ng-model="query"></input>   
  2. <li ng-repeat="item in items" ng-show="([item.name] | filter:query).length">{{item.name}}
  3. </li><span style="font-size: 14px; line-height: 24px; font-family: Helvetica, Tahoma, Arial, sans-serif; white-space: normal;"></span>   

另一個方法是為ng-show傳遞一個屬性,并在單獨的子控制器進(jìn)行計算。該方法稍有點復(fù)雜,但卻是更明晰的方法。

7.關(guān)于過濾的小提示:防抖動輸入

解決第6點提出的持續(xù)過濾問題的另一個方法是防抖動用戶輸入。例如,如果用戶輸入一個搜索關(guān)鍵詞,只當(dāng)用戶停止輸入后,過濾器才會被激活。使用該防抖動服務(wù)的一個很好的解決方案請見:http://jsfiddle.net/Warspawn/6K7Kd/。將它應(yīng)用到你的視圖及控制器中,如下所示。

  1. /* Controller */   
  2. // Watch the queryInput and debounce the filtering by 350 ms.   
  3. $scope.$watch('queryInput'function(newValue, oldValue) {   
  4.     if (newValue === oldValue) { return; }   
  5.     $debounce(applyQuery, 350);   
  6. });   
  7. var applyQuery = function() {   
  8.     $scope.filter.query = $scope.query;   
  9. };   
  10.     
  11. /* View */   
  12. <input ng-model="queryInput"/>   
  13. <li ng-repeat= item in items | filter:filter.query>{{ item.title }} </li>   

原文鏈接:http://tech.small-improvements.com/2013/09/10/angularjs-performance-with-large-lists/

譯文鏈接:http://www.iteye.com/news/28313

責(zé)任編輯:陳四芳 來源: iteye.com
相關(guān)推薦

2010-05-05 14:04:31

Oracle 性能

2011-03-10 14:40:54

LAMPMysql

2017-07-21 08:55:13

TomcatJVM容器

2023-02-07 08:00:00

MySQL數(shù)據(jù)庫技巧

2011-04-07 16:15:31

MySQL服務(wù)器調(diào)優(yōu)

2012-06-20 11:05:47

性能調(diào)優(yōu)攻略

2017-11-17 08:56:59

Java性能優(yōu)化技巧

2021-03-04 08:39:21

SparkRDD調(diào)優(yōu)

2014-04-24 10:11:17

iOS性能調(diào)優(yōu)

2020-10-20 11:13:19

性能調(diào)優(yōu)標(biāo)準(zhǔn)

2012-03-26 10:55:03

JavaJava EE

2011-05-20 15:02:01

Oracle性能調(diào)優(yōu)

2011-11-14 10:28:23

2020-11-30 11:40:35

NginxLinux性能調(diào)優(yōu)

2010-08-18 09:32:45

DB2優(yōu)化性能

2011-03-18 11:21:48

2015-11-10 09:25:05

HTTP2提升性能

2014-12-01 11:30:06

PostgreSQL

2024-11-11 08:11:39

2016-03-25 09:59:38

性能調(diào)優(yōu)LinuxMySQL
點贊
收藏

51CTO技術(shù)棧公眾號