O slideshow foi denunciado.
Utilizamos seu perfil e dados de atividades no LinkedIn para personalizar e exibir anúncios mais relevantes. Altere suas preferências de anúncios quando desejar.

Angular Performance: Then, Now and the Future. Todd Motto

11.444 visualizações

Publicada em

FOWA London 2015

Covering Angular of the past and present, and diving into the future - covering performance aspects and practices, how they work and why you should adopt them.

Publicada em: Tecnologia, Software
  • Girls for sex in your area are there: tinyurl.com/areahotsex
       Responder 
    Tem certeza que deseja  Sim  Não
    Insira sua mensagem aqui
  • account activity. WTF!! Why I’m being penalized for winning?? Has this happened to you? Also just checked your web page again…you’re giving this service away for £30 . HAVE YOU LOST YOUR MIND?!!! ◆◆◆ http://t.cn/A6vAxKsh
       Responder 
    Tem certeza que deseja  Sim  Não
    Insira sua mensagem aqui
  • Real people just like you are kissing the idea of punching the clock for someone else goodbye, and embracing a new way of living. The internet economy is exploding, and there are literally THOUSANDS of great earnings opportunities available right now, all just one click away. ♥♥♥ http://t.cn/AisJWUCf
       Responder 
    Tem certeza que deseja  Sim  Não
    Insira sua mensagem aqui
  • Sex in your area is here: ♥♥♥ http://bit.ly/2ZDZFYj ♥♥♥
       Responder 
    Tem certeza que deseja  Sim  Não
    Insira sua mensagem aqui
  • Dating direct: ♥♥♥ http://bit.ly/2ZDZFYj ♥♥♥
       Responder 
    Tem certeza que deseja  Sim  Não
    Insira sua mensagem aqui

Angular Performance: Then, Now and the Future. Todd Motto

  1. AngularJS the performance parts@toddmotto
  2. » Lead Engineer @ Mozio » Google Developer Expert » @toddmotto » Blog at toddmotto.com
  3. Topics » New features (1.2 - 1.3+) » Generic changes » Perf features » Performance driven Angular » $digest loop/$$watchers/$$asyncQueue » Quick wins, tips and tricks » Structure practices, advanced techniques
  4. 1.2to1.3+
  5. 1.2to1.3+genericchanges
  6. » IE8 support dropped » DOM manipulation » ~4.3 times faster » 73% less garbage » $digest loop » ~3.5 times faster » 78% less garbage » 400+ bug fixes
  7. 1.2to1.3+perffeatures
  8. » One-time bind syntax » ngModelOptions » bindToController property » ngModel.$validators » ngMessage/ngMessages » strictDI » $applyAsync in $http » Disable debug info
  9. onetimebindings <p>{{ ::vm.name }}</p> <p ng-bind="::vm.name"></p> <div ng-if="::vm.user.loggedIn"></div> <div ng-class="::{ loggedIn: vm.user.loggedIn }"></div> <ul> <li ng-repeat="user in ::vm.users"> {{ ::user.name }} </li> </ul>
  10. onetimebindings » Defined with :: » $watched until not "undefined" » $$watcher is unbound » Will not update upon Model changes » One-time, not one-way » Great for single static rendering
  11. ng-Model-Options <!-- updateOn --> <input type="text" ng-model="vm.model" ng-model-options="{ updateOn: 'default blur' }">
  12. ng-Model-Options <!-- debounce: - example will debounce 250ms when typing - example will update model immediately on "blur" --> <input type="text" ng-model="vm.model" ng-model-options="{ updateOn: 'default blur', debounce: { 'default': 250, 'blur': 0 } }">
  13. ng-Model-Options // directive controller function FooDirCtrl() { // undo model changes if (condition) { this.model.$rollbackViewValue(); } }
  14. ng-Model-Options » Fine tune how Model updates are done » Define event types » Add debounce to delay Model synchronisation » e.g. { debounce: 250 } = $digest ~250ms » $rollbackViewValue for undoing model changes
  15. bindToController // directive controller function FooDirCtrl() { this.bar = {}; this.doSomething = function doSomething(arg) { this.bar.foobar = arg; }.bind(this); }
  16. bindToController // directive controller function FooDirCtrl($scope) { this.bar = {}; this.doSomething = function doSomething(arg) { this.bar.foobar = arg; // reference the isolate property $scope.name = arg.prop; }.bind(this); }
  17. bindToController function fooDirective() { return { ... scope: {}, bindToController: { name: '=' }, ... }; }
  18. bindToController // directive controller function FooDirCtrl() { this.bar = {}; this.doSomething = function doSomething(arg) { this.bar.foobar = arg; // reference the isolate property this.name = arg.prop; }.bind(this); }
  19. bindToController » Used with "controllerAs" (class-like) » Binds isolate props to the Controller instance » No $scope » $scope remains "special use only" » Not used for data » Used for $watch/$on/etc
  20. ngModel.$validators // old school function visaValidator() { var VISA_REGEXP = /^4[0-9]{12}(?:[0-9]{3})?$/; function link($scope, element, attrs, ngModel) { ngModel.$parsers.unshift(function (value) { var valid = VISA_REGEXP.test(value); ngModel.$setValidity('visaValidator', valid); return valid ? value : undefined; }); } return { require : 'ngModel', link : link }; } angular.module('app').directive('visaValidator', visaValidator);
  21. ngModel.$validators // new school function visaValidator() { var VISA_REGEXP = /^4[0-9]{12}(?:[0-9]{3})?$/; function link($scope, element, attrs, ngModel) { ngModel.$validators.visaValidator = function (value) { return VISA_REGEXP.test(value); // Boolean }; } return { require : 'ngModel', link : link }; } angular.module('app').directive('visaValidator', visaValidator);
  22. ngModel.$validators <form name="myForm"> <label> <input type="text" ng-model="myForm.card" visa-validator> <div ng-if="myForm.myPassword.$error.visaValidator"> Not a valid VISA format! </div> </label> </form>
  23. ngModel.$validators » ngModel.$validators Object » Instead of $parsers/$formatters » Return a Boolean from the bound function » Use with the $error Object in the View
  24. ngMessage/ngMessages <form name="myForm"> <label> Enter email: <input type="text" ng-model="field" name="myField" required ng-minlength="5" ng-maxlength="100"> </label> <div ng-messages="myForm.myField.$error" role="alert"> <div ng-message="required"> You did not enter a field </div> <div ng-message="minlength, maxlength"> Your email must be between 5 and 100 characters long </div> </div> </form>
  25. ngMessage/ngMessages » Conditional validation » ngModel.$error Object » Acts like a switch case
  26. strictDI <div ng-app="myApp" ng-strict-di> <!-- app --> </div>
  27. strictDI // implicit annotation function SomeService($scope, $timeout) { //... } angular .module('app') .factory('SomeService', SomeService);
  28. strictDI function SomeService($scope, $timeout) { //... } // Array annotations SomeService.$inject = ['$scope', '$timeout']; angular .module('app') .factory('SomeService', SomeService);
  29. strictDI » Runs the application's $injector in strict mode » Throws an error on Services using implicit annotations » Use ng-annotate to automate this process
  30. $applyAsyncwith$http function config($httpProvider) { $httpProvider.useApplyAsync(true); } angular .module('app', []) .config(config); More: blog.thoughtram.io/angularjs/2015/01/14/exploring-angular-1.3-speed-up-with-applyAsync.html
  31. $applyAsyncwith$http » Enables $applyAsync to be used with $http » Schedules an async $apply for batched requests » For requests that resolve within ~10ms » Pushes into $$asyncQueue » Single $digest
  32. Disabledebuginfo function config($compileProvider) { $compileProvider.debugInfoEnabled(false); } angular .module('app', []) .config(config);
  33. Disabledebuginfo <!-- enabled --> <div ng-controller="MainCtrl as vm" class="ng-scope ng-binding"> <my-directive class="ng-isolate-scope"> // content </my-directive> </div> <!-- disabled --> <div ng-controller="MainCtrl as vm"> <my-directive> // content </my-directive> </div>
  34. Disabledebuginfo » Disable in production for performance boosts » Removes $scope references on elements » Doesn't add classes to DOM nodes with binding info » Enable in console with angular.reloadWithDebugInfo();
  35. PerformancedrivenAngular
  36. Understandwhatimpacts performance beforeyou code
  37. Underthe hood: $digest
  38. $digestfundamentals » $digest loop » $$watchers ($watch) » $$asyncQueue ($evalAsync)
  39. $digest: $digestloop » Triggered by $scope.$apply / built-in events » Iterates $$watchers Array on $scope » If model value is different from last calculated then corresponding listener executes » Exits loop, Angular loops again (10 max) » Repaints DOM (View expressions updated)
  40. $digest: $$watchers » View events/bindings {{ foo }} » Angular adds a watch to the $watch list » Only $watched if bound in the View » Dirty checked in the $digest loop » Minimise use of $$watchers / avoid if possible
  41. $digest: $$asyncQueue » $evalAsync » Runs first in $digest » May run $digest again to flush $$asyncQueue
  42. trackby Scenarios: * Large DOM lists * Slow DOM updates * $digests blocking UI thread (lagging)
  43. trackby <!-- before --> <ul> <li ng-repeat="user in vm.users"> {{ user.name }} </li> </ul>
  44. trackby <!-- after --> <ul> <li ng-repeat="user in vm.users track by user.id"> {{ user.name }} </li> </ul>
  45. trackby » Minimal DOM repaints (only what's changed) » Uses Object references instead of Angular hashes
  46. ng-if/switchvsng-show/hide <!-- ng-show --> <ul ng-show="vm.exposeNav"> <li ng-repeat="menu in vm.menus"></li> </ul> <!-- ng-if --> <ul ng-if="vm.exposeNav"> <li ng-repeat="menu in vm.menus"></li> </ul>
  47. ng-if/switchvsng-show/hide » ng-if/switch reconstruct the DOM » ng-if/switch for less frequent/heavier rendering » ng-show/hide toggle "ng-hide" class » ng-show/hide for more frequent/lighter rendering » ng-show/hide less performant due to $$watchers (when hidden)
  48. ng-bindover{{handlebars}} <!-- handlebars --> <p>{{ vm.username }}</p> <!-- ng-bind --> <p ng-bind="vm.username"></p> <!-- perf example --> <p> Welcome <span ng-bind="vm.username"></span> to Facebook </p>
  49. ng-bindover{{handlebars}} » No DOM flicker (invisible bindings) with ng-bind » Significantly faster » ng-perf.com/2014/10/30/tip-4-ng-bind-is-faster- than-expression-bind-and-one-time-bind » Lesser need for ng-cloak » Angular won't evaluate entire text content
  50. $applyor$digest? // forces a $rootScope.$digest(); $scope.$apply(); // forces a [current $scope].$digest(); $scope.$digest();
  51. $applyor$digest? » $scope certainties » Prevent a full $rootScope.$digest() if you're certain only child $scopes need updating » Improve performance by not forcing a full $rootScope.$digest » $scope.$digest runs on current and child $scopes » $scope.$apply triggers $rootScope.$digest call
  52. $destroyunbinding function myFunction () { // handle element clicks } // bind element.on('click', myFunction); // unbind $scope.$on('$destroy', function () { element.off('click', myFunction); });
  53. $destroyunbinding » Remove event listeners that may cause memory leaks » DOM nodes that are destroyed » Manually unbind by listening to $destroy » $scope.$on events are automatically removed
  54. Deep$watchvs$watchCollection var prop = [{...},{...},{...},{...}]; $scope.$watch('prop', function (newValue, oldValue) { }, true); $scope.$watchCollection('prop', function (newValue, oldValue) { });
  55. Deep$watchvs$watchCollection » Deep $watch uses deep Object tree comparison (expensive) » $watchCollection goes only one level deep » Shallow reference of all top level items » Try not to use either unless you have to » Not as testable » Signs of bad architecture » Litter Controllers
  56. avoidingDOMfilters <!-- vm.date = 1444175093303 --> <p>{{ vm.date | date: 'dd-MM-yyyy' }}</p>
  57. avoidingDOMfilters function SomeCtrl($filter) { // date passed in elsewhere var time = 1444175093303; // Parsed in JS before bound to the DOM this.parsedDate = $filter('date')(time, 'dd-MM-yyyy'); } angular .module('app') .controller('SomeCtrl', SomeCtrl);
  58. avoidingDOMfilters <p>{{ vm.parsedDate }}</p>
  59. avoidingDOMfilters » DOM filters run twice per $digest » Preprocess in a Controller » Bind parsed value to the View
  60. Takeaways » Understand the $digest loop » Investigate the performance side of each Directive/API you use » Consider using JavaScript over DOM bindings where possible ($filter etc.) » Check Angular's GitHub repo for changelogs/ releases
  61. Thankyou @toddmotto speakerdeck.com/toddmotto

×