Geplaats op 13 maart 2017 | Leestijd: 4 minuten
Two-way binding heeft webdevelopment veranderd. 'live' laten zien aan gebruikers wat er gebeurt en 'live' verwerken van de input van gebruikers zorgen voor de gebruikers voor een prettige ervaring. Een ander voordeel is dat jij als developer nauwelijks code in de view-layer van je applicatie hoeft te schrijven om waarden aan te passen of gebruikersinvoer te verwerken.
Een groot nadeel van two-way binding is performance. Het gebruik van two-way binding voegt bij de meeste projecten zo veel gemak toe dat mindere performance wordt geaccepteerd. Dit zou echter niet moeten betekenen dat we zonder performance in ons achterhoofd webapplicaties schrijven. Er zijn een aantal punten waar je als developer altijd rekening mee moet houden.
1. Het aantal watchers
De
digestcycle wordt vanaf de rootscope naar alle childscopes uitgevoerd. Per scope wordt er gekeken naar veranderingen door middel van watchers. Zo nodig wordt de UI aangepast en voeren controllers functies uit om de nieuwe waardes te verwerken. Maar ook vice versa, updates in de UI moeten resulteren in een aangepast model in code.
De digestcycle wordt uitgevoerd bij
- Events, zoals ng-click
- $interval
- $timeout
- $digest.apply()
Om de digestcycle snel te houden moeten het aantal watchers worden beperkt. Elke watchable item in de watchlist is een expressie die moet worden uitgevoerd. Elke expressie minder is voordelig. Bij gebruik van veel directives is het mogelijk dat de digestcycle meerdere keren per seconden wordt uitgevoerd. Dit resulteert in een overbelaste cpu en een minder snelle browser. Vooral bij oudere browsers is dit snel merkbaar.
Watchers worden geactiveerd bij
- {{ }} expressies in de view
- Directives zoals ng-repeat
- Variables op de scope
- Filters in de view en in de controller
- $scope.$watch
2. One-time binding
Bij one-time binding wordt de waarde van de expressie niet opnieuw vastgesteld bij elke digestcycle. Zoals de naam zegt wordt de expressie eenmalig uitgevoerd, dit is op het moment dat de view voor de eerste keer wordt geladen. De waarde op het scherm wordt bij een verandering van een model in de controller niet veranderd.
3. Vervang ngHide met ngIf wanneer dat kan
Verminder het aantal watchers in een view door ngHide te vervangen door ngIf. Expressies binnen wachters binnen een ngHide worden bij elke digestcycle opnieuw uitgevoerd. Ook wanneer dom elementen niet zichtbaar zijn voor de gebruiker. Doordat ngIf actief dom elementen verwijdert uit de view (en weer terugplaatst) worden watchers binnen ngIf niet uitgevoerd.
4. Ga voorzichtig om met ngRepeat
NgRepeat is een zware expressie. Per item in een lijst zijn er niet alleen veel nieuwe watchable items, maar ook de dom wordt bij elke digestcycle opnieuw getekend. Bij een geneste ngRepeat zullen te snel veel watchable items in de view komen.
Zorg ervoor dat een ngRepeat niet gevuld wordt met een te lange array. Gebruik bijvoorbeeld paginering bij lange array's
Performance meten
Gebruikt de Chrome plugin
AngularJS Batarang om het aantal watchers te meten. Ook krijg je met deze tool inzicht in de duur van het uitvoeren van de digestcycle.
Of gebruik
ngStats binnen elke andere browser. Door onderstaande code via de browserconsole uit te voeren krijg je direct inzicht in het aantal watchers.
(function() {var a = document.createElement("script");a.src = "https://rawgit.com/kentcdodds/ng-stats/master/dist/ng-stats.js";a.onload=function(){window.showAngularStats()};document.head.appendChild(a)})();