摘要:本文針對(duì)的讀者具備性能優(yōu)化的相關(guān)知識(shí)雅虎條性能優(yōu)化原則高性能網(wǎng)站建設(shè)指南等擁有實(shí)戰(zhàn)經(jīng)驗(yàn)。這種機(jī)制能減少瀏覽器次數(shù),從而提高性能。僅會(huì)檢查該和它的子,當(dāng)你確定當(dāng)前操作僅影響它們時(shí),用可以稍微提升性能。
搬運(yùn)自: http://atian25.github.io/2014/05/09/angular-performace/
臟數(shù)據(jù)檢查 != 輪詢檢查更新不知不覺(jué),在項(xiàng)目中用angular已經(jīng)半年多了,踩了很多坑。
趁著放假,把a(bǔ)ngular的3本書都看了遍,結(jié)合這半年的經(jīng)驗(yàn),是該做個(gè)總結(jié)了。
希望可以給大家?guī)?lái)啟示,少踩點(diǎn)坑。
本文針對(duì)的讀者:
- 具備JavaScript性能優(yōu)化的相關(guān)知識(shí)(雅虎14條性能優(yōu)化原則、《高性能網(wǎng)站建設(shè)指南》等)
- 擁有angular實(shí)戰(zhàn)經(jīng)驗(yàn)。
談起angular的臟檢查機(jī)制(dirty-checking), 常見(jiàn)的誤解就是認(rèn)為: ng是定時(shí)輪詢?nèi)z查model是否變更。
其實(shí),ng只有在指定事件觸發(fā)后,才進(jìn)入$digest cycle:
- DOM事件,譬如用戶輸入文本,點(diǎn)擊按鈕等。(ng-click)
- XHR響應(yīng)事件 ($http)
- 瀏覽器Location變更事件 ($location)
- Timer事件($timeout, $interval)
- 執(zhí)行$digest()或$apply()
$digest后批量更新UI參考《mastering web application development with angularjs》 P294
傳統(tǒng)的JS MVC框架, 數(shù)據(jù)變更是通過(guò)setter去觸發(fā)事件,然后立即更新UI。
而angular則是進(jìn)入$digest cycle,等待所有model都穩(wěn)定后,才批量一次性更新UI。
這種機(jī)制能減少瀏覽器repaint次數(shù),從而提高性能。
提速 $digest cycle 關(guān)鍵點(diǎn)參考《mastering web application development with angularjs》 P296
另, 推薦閱讀: 構(gòu)建自己的AngularJS,第一部分:Scope和Digest
盡少的觸發(fā)$digest (P310)
盡快的執(zhí)行$digest
優(yōu)化$watch$scope.$watch(watchExpression, modelChangeCallback), watchExpression可以是String或Function。
避免watchExpression中執(zhí)行耗時(shí)操作,因?yàn)樗诿看?digest都會(huì)執(zhí)行1~2次。
避免watchExpression中操作dom,因?yàn)樗芎臅r(shí)。
console.log也很耗時(shí),記得發(fā)布時(shí)干掉它。(用grunt groundskeeper)
ng-if vs ng-show, 前者會(huì)移除DOM和對(duì)應(yīng)的watch
及時(shí)移除不必要的$watch。(angular自動(dòng)生成的可以通過(guò)下文介紹的bindonce)
> 參考《mastering web application development with angularjs》 P303~309
var unwatch = $scope.$watch("someKey", function(newValue, oldValue){ //do sth... if(someCondition){ //當(dāng)不需要的時(shí)候,及時(shí)移除watch unwatch(); } });
避免深度watch, 即第三個(gè)參數(shù)為true
參考《mastering web application development with angularjs》 P313
減少watch的變量長(zhǎng)度
如下,angular不會(huì)僅對(duì){{variable}}建立watcher,而是對(duì)整個(gè)p標(biāo)簽。
雙括號(hào)應(yīng)該被span包裹,因?yàn)閣atch的是外部element
參考《mastering web application development with angularjs》 P314
$apply vs $digestplain text other {{variable}} plain text other
//改為:plain text other plain text other
//或plain text other {{variable}} plain text other
$apply會(huì)使ng進(jìn)入$digest cycle, 并從$rootScope開(kāi)始遍歷(深度優(yōu)先)檢查數(shù)據(jù)變更。
$digest僅會(huì)檢查該scope和它的子scope,當(dāng)你確定當(dāng)前操作僅影響它們時(shí),用$digest可以稍微提升性能。
> 參考《mastering web application development with angularjs》 P308
一些不必要的操作,放到$timeout里面延遲執(zhí)行。
如果不涉及數(shù)據(jù)變更,還可以加上第三個(gè)參數(shù)false,避免調(diào)用$apply。
對(duì)時(shí)間有要求的,第二個(gè)參數(shù)可以設(shè)置為0。
$http.get("http://path/to/url").success(function(data){ $scope.name = data.name; $timeout(function(){ //do sth later, such as log }, 0, false); });
$evalAsync vs $timeout
http://stackoverflow.com/questions/17301572/angularjs-evalasync-vs-timeout
directive中執(zhí)行的$evalAsync, 會(huì)在angular操作DOM之后,瀏覽器渲染之前執(zhí)行。
controller中執(zhí)行的$evalAsync, 會(huì)在angular操作DOM之前執(zhí)行,一般不這么用。
而使用$timeout,會(huì)在瀏覽器渲染之后執(zhí)行。
優(yōu)化ng-repeat 限制列表個(gè)數(shù)列表對(duì)象的數(shù)據(jù)轉(zhuǎn)換,在放入scope之前處理。如$scope.dataList = convert(dataFromServer)
可以使用ngInfiniteScroll來(lái)做無(wú)限滾動(dòng)。
使用 track by刷新數(shù)據(jù)時(shí),我們常這么做:$scope.tasks = data || [];,這會(huì)導(dǎo)致angular移除掉所有的DOM,重新創(chuàng)建和渲染。
若優(yōu)化為ng-repeat="task in tasks track by task.id后,angular就能復(fù)用task對(duì)應(yīng)的原DOM進(jìn)行更新,減少不必要渲染。
參見(jiàn):http://www.codelord.net/2014/04/15/improving-ng-repeat-performance-with-track-by
我們都知道angular建議一個(gè)頁(yè)面最多2000個(gè)雙向綁定,但在列表頁(yè)面通常很容易超標(biāo)。
譬如一個(gè)滑動(dòng)到底部加載下頁(yè)的表格,一行20+個(gè)綁定, 展示個(gè)100行就超標(biāo)了。
下圖這個(gè)只是一個(gè)很簡(jiǎn)單的列表,還不是表格,就已經(jīng)這么多個(gè)了:
但其實(shí)很多屬性顯示后是幾乎不會(huì)變更的, 這時(shí)候就沒(méi)必要雙向綁定了。(不知道angular為何不考慮此類場(chǎng)景)
如下圖,改為bindonce或angular-once后減少了很多:
update:
1.3.0b10開(kāi)始支持內(nèi)建單次綁定, {{::foo}}
設(shè)計(jì)文檔:http://t.cn/RvIYHp9
commit: http://t.cn/RvIYHpC
目前該特性的性能似乎還有待優(yōu)化(2x slower)
在$digest過(guò)程中,filter會(huì)執(zhí)行很多次,至少兩次。
所以要避免在filter中執(zhí)行耗時(shí)操作。
參考《mastering web application development with angularjs》 P136
angular.module("filtersPerf", []).filter("double", function(){ return function(input) { //至少輸出兩次 console.log("Calling double on: "+input); return input + input; }; });
可以在controller中預(yù)先處理
//mainCtrl.js angular.module("filtersPerf", []).controller("mainCtrl", function($scope, $filter){ $scope.dataList = $filter("double")(dataFromServer); });慎用事件
減少事件廣播,使用雙向數(shù)據(jù)綁定或共享service等方法來(lái)代替。
$broadcast會(huì)遍歷scope和它的子scope,而不是只通知注冊(cè)了該事件的子scope。
一個(gè)優(yōu)化方式是使用$emit, 參見(jiàn)https://github.com/angular/angular.js/issues/4574
1.2.7版本對(duì)事件做過(guò)一個(gè)優(yōu)化,參見(jiàn)https://github.com/angular/angular.js/blob/master/CHANGELOG.md#127-emoji-clairvoyance-2014-01-03
對(duì)高頻的事件做緩沖限速,避免觸發(fā)太頻繁。
directive跟scope數(shù)據(jù)無(wú)關(guān)的操作放在compile階段,它只執(zhí)行一次。
除了directive外其他地方,特別是controller里面不要操作dom, 尤其是綁定到scope后,便是災(zāi)難。
改變以前使用JQuery那樣以DOM為中心的思維,擁抱以數(shù)據(jù)為中心的思維。參見(jiàn)
> 參見(jiàn): http://stackoverflow.com/questions/14994391/how-do-i-think-in-angularjs-if-i-have-a-jquery-background
> 翻譯: http://blog.jobbole.com/46589/
AngularJS Batarang是官方提供的chrome插件
搬運(yùn)自: http://atian25.github.io/2014/05/09/angular-performace/
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/78079.html
摘要:在理想的情況下,我們甚至可以立即將應(yīng)用程序升級(jí)到。于是,在中,我們可以得到些什么正如我們所看到的,的新增特性除之外并不是很亮眼,盡管這些特性非常好用,但對(duì)于大多數(shù)應(yīng)用程序來(lái)說(shuō)并不重要。 轉(zhuǎn)載請(qǐng)注明出處:葡萄城官網(wǎng),葡萄城為開(kāi)發(fā)者提供專業(yè)的開(kāi)發(fā)工具、解決方案和服務(wù),賦能開(kāi)發(fā)者。 本文由葡萄城翻譯并發(fā)布 showImg(https://segmentfault.com/img/bVbrk...
摘要:前端日?qǐng)?bào)精選騰訊前端團(tuán)隊(duì)社區(qū)源碼分析入門指南一些關(guān)于使用的心得基本類型與引用類型知多少掘金中文第期框架選型周刊第期入門系列模塊車棧重構(gòu)基于的網(wǎng)絡(luò)請(qǐng)求庫(kù)某熊的全棧之路的那些奇技淫巧的平凡之路模仿寫個(gè)數(shù)組監(jiān)聽(tīng)掘 2017-07-01 前端日?qǐng)?bào) 精選 Why you shouldn`t use Preact, Fast-React, etc. to replace React today -...
摘要:更多資源請(qǐng)文章轉(zhuǎn)自月份前端資源分享關(guān)于的思考一款有趣的動(dòng)畫效果跨站資源共享之二最流行的編程語(yǔ)言能做什么到底什么是閉包的第三個(gè)參數(shù)跨域資源共享詳解阮一峰前端要給力之語(yǔ)句在中的值周愛(ài)民中國(guó)第二屆視頻花絮編碼規(guī)范前端工程師手冊(cè)奇舞周刊被忽視的 更多資源請(qǐng)Star:https://github.com/maidishike... 文章轉(zhuǎn)自:https://github.com/jsfron...
摘要:但是在第一次上線后,發(fā)現(xiàn)自己的網(wǎng)頁(yè)打開(kāi)后,加載的速度需要秒,當(dāng)時(shí)第一感覺(jué)就是,我是不是應(yīng)該換框架最終在網(wǎng)絡(luò)上摸索出來(lái)一系列的解決方案,得到了現(xiàn)在只要秒就可以完成加載任務(wù)這一系列的解決方案我會(huì)在整理好后再告訴大家。 火星積雪 摘要:火星積雪 這個(gè)是目前正在開(kāi)發(fā)的一個(gè)項(xiàng)目,主要目的是為了提供一個(gè)快捷的集成應(yīng)用的,這么一個(gè)小應(yīng)用中心! 項(xiàng)目框架 angular5 angular-cli ...
閱讀 2579·2021-11-23 09:51
閱讀 3126·2019-08-30 15:54
閱讀 1080·2019-08-30 14:14
閱讀 3551·2019-08-30 13:59
閱讀 1411·2019-08-29 17:09
閱讀 1470·2019-08-29 16:24
閱讀 2855·2019-08-29 15:43
閱讀 918·2019-08-29 12:45