ngParis #11
26 May 2014Introduction
Cette fois-ci, c'était chez Meetic, qui ont de chouettes locaux en plein Paris, mais on peut passer devant sans s'en rendre compte vu que ce n'est pas marqué sur la façade.
Améliorer les performances de ses applications Angular
Jonathan Meiss, ancien collègue Octo désormais chez Meetic, nous présentait toute une liste d'astuces pour améliorer les performances d'une appli Angular. Globalement c'était des choses assez basiques et connues.
On a pas mal parlé de ngRepeat qui est là que généralement les problèmes de perf se font sentir. Déjà il est éviden que la page va être moins performante si on doit afficher 1000 élement que si on n'en affiche que 10. Du coup, il peut être intéressant de faire appel à limitTo pour paginer les résultats. Une autre solution est de tirer parti de l'infinite scroll qui permet de ne charger des éléments que quand ils vont apparaitre dans le viewport. Il conseille la library ng-infinite-scroll pour ça.
Toujours sur les ngRepeat, il faut bien sur éviter de faire des boucles sur des résultats de fonctions (ie pas de ng-repeat="item in filteredList()") car cela force à recalculer le contenu de filteredList à chaque digest cycle. Mieux vaut soit utiliser des filter dans la vue, soit itérer sur une variable du scope.
Dernier conseil sur ngRepeat; angular génère un id unique à chaque élement sur lequel il itère pour les différencier. Si on le laisse faire il utilise les clés interne de l'objet pour générer son id. Si on sait qu'une de nos clés (id par exemple) est unique dans la liste, autant lui spécifier avec track by
pour lui simplifier son calcul et lui éviter d'ajouter des éléments inutiles au DOM.
On est ensuite passé sur le two-way binding qui est l'élément qui nous a fait rêver au début d'angular, mais qui reste un processus couteux. A partir de 2000 watchers, les performances commencent à en patir. Si on sait qu'on ne fait qu'afficher sans avoir besoin de modifier des données, on peut ajouter bo-text="user.name"
sur l'élément sur lequel on itère pour qu'angular ne crée pas de two-way binding.
Il nous a fait un petit retour sur ngIf et ngShow et les cas d'usages pour chacun. ngIf ne va ajouter des éléments dans le DOM que si la condition est vraie, il ne faut donc pas l'utiliser si la condition change souvent, au risque de créer trop de rendering au browser. Au contraire, si le contenu affiché dans l'élément nécessite un processing intense, il vaut mieux le mettre dans un ngIf plutot qu'un ngShow. ngShow quand à lui est utile si on veut "cacher" des éléments dans le DOM pour les afficher plus tard rapidement.
Bien sur, il conseille d'activer le cache:true sur les ressources, et $q.all quand possible pour parallelliser les requetes aux API. Idem pour définir des resolve dans son router (à noter que si une seule des resolve fail, alors le controlleur cible ne sera pas instancier. Il peut donc être intéressant de ne définir qu'un seul resolve, qui englobe une promise custom avec $q.all et retourner un unique object avec des clés undefined si les sous-promises failent, et gérer les fallbacks dans le controlleur).
Finalement, il ne faut pas oublier que la performance ne se calcule pas en ms réelles, mais en perception utilisateur. Il peut donc parfois être intéressant d'utiliser des résolve pour afficher à l'user une page avec toutes les données, mais parfois de les afficher au fur et à mesure. A noter qu'en dessous de 100ms le cerveau humain considère une action comme immédiate. On peut donc afficher un spinner à l'utilisateur pour lui indiquer qu'une action est en cours, mais ne l'afficher que si le traitement prends plus de 100ms pour lui éviter un flicker inutile. Si on veut aller au bout des best practices, on peut commencer à afficher des placeholders pendant le chargement pour lui montrer que quelque chose se passe. Il est important aussi de lui laisser accès à des fonctions de base (sidebar, menu) pour lui permettre de naviguer si la navigation prends trop de temps (plutot que de se retrouver sur une page freezée et qu'il soit obligé de quitter la page).
Finalement John a fini par un troll en disant que si vraiment vous voulez des pages réactives qui se chargent vite, utilisez React.
SVG
Présentation molle et avec des soucis techniques. Au final on a juste (re)appris que SVG c'était cool parce que c'était vectoriel et donc ça scale aux résolutions. Mais surtout c'est du XML dans le DOM, donc ça se scripte en Angular très facilement et ça se style en CSS. Et on peut faire des formes complexes à base de suite de points pour faire par exemple une carte de france des régions.
Voila, voila.
Le talk était fait par un statisticien qui était passionné (et passionant) quand il parlait des données, mais semblait découvrir en Angular ce qui pour moi faisait partie des bases. Au final, d'un point de vue technique je n'ai rien appris, et d'un point de vue des données en elle-même, cela semblait certes le passioner, mais n'ayant pas la même fougue pour les nombres, ça m'est juste passé au dessus de la tête.
Dommage, donc.
Want to add something ? Feel free to get in touch on Twitter : @pixelastic