Conformité des frameworks

Conformité dans l'écosystème du framework JavaScript

Dans notre article de blog de présentation, nous avons expliqué comment nous avons beaucoup appris en créant et en utilisant des frameworks et des outils pour développer et gérer des applications Web à grande échelle telles que la recherche Google, Maps, Photos, etc. En empêchant les développeurs d'écrire du code susceptible d'affecter négativement l'expérience utilisateur, nous avons prouvé que les frameworks pouvaient jouer un rôle clé dans l'amélioration des performances et de la qualité des applications.

En interne chez Google, nous avons utilisé le terme conformité pour décrire cette méthodologie. Cet article explique comment nous prévoyons de partager ce concept en Open Source dans l'écosystème du framework JavaScript.

Qu'est-ce que la conformité ?

Chez Google, la conformité était une évolution. Les équipes se sont appuyées sur un petit groupe d'intervenants très expérimentés qui ont examiné le code de manière approfondie, signalant les éléments qui nuisaient à la qualité et à la gestion des applications, bien au-delà des problèmes d'exactitude. Pour étendre cette approche aux équipes de développeurs d'applications en pleine expansion, un système de conformité a été développé afin de codifier les bonnes pratiques de manière automatisée et applicable. Cela a permis de maintenir un haut niveau de qualité des applications et de gestion du codebase, quel que soit le nombre de contributeurs de code.

La conformité est un système qui garantit que les développeurs restent sur la bonne voie. Elle renforce la confiance et garantit des résultats prévisibles. Elle rend les équipes productives et devient crucial pour l'évolutivité, à mesure que les équipes se développent et que de nouvelles fonctionnalités sont développées simultanément. Elle permet aux développeurs de se concentrer sur la création de fonctionnalités produit, en les affranchissant des moindres détails et de l'évolution du paysage dans divers domaines tels que les performances, l'accessibilité, la sécurité, etc. N'importe qui peut refuser la conformité à tout moment. Elle doit être personnalisable dans la mesure où les équipes auront la possibilité d'appliquer ce qu'elles décident d'engager.

La conformité est fondée sur des valeurs par défaut fortes et fournit des règles exploitables pouvant être appliquées au moment de la création. Cela se décompose en trois principes :

1. Valeurs par défaut fortes

Un aspect fondamental de la conformité consiste à s'assurer que les outils utilisés par les développeurs ont des valeurs par défaut strictes. Cela signifie que les solutions ne sont pas seulement intégrées dans des frameworks, mais que les modèles de conception de framework facilitent l'application des bonnes pratiques et permettent de suivre des antimodèles difficiles à suivre. Le framework aide les développeurs à gérer la conception d'applications et la structure du code.

Pour optimiser les performances de chargement, chaque ressource (polices, CSS, JavaScript, images, etc.) doit être optimisée. Il s'agit d'un défi complexe impliquant l'élimination des octets, la réduction des allers-retours et la séparation des éléments nécessaires au premier affichage, à la préparation visuelle et à l'interaction utilisateur. Par exemple, vous pouvez extraire les fichiers CSS critiques et définir la priorité des images importantes.

2. Règles exploitables

Même si les optimisations de base sont en place, les développeurs doivent faire des choix. Il existe un éventail de possibilités d'optimisation en ce qui concerne la quantité de contribution des développeurs nécessaire:

  • Valeurs par défaut qui ne nécessitent aucune intervention du développeur, comme l'intégration du CSS critique.
  • Exiger l'activation du développeur. Par exemple, vous pouvez utiliser un composant d'image fourni par le framework pour dimensionner et mettre à l'échelle des images.
  • Exiger l'activation du développeur et la personnalisation. Par exemple, ajouter des tags aux images importantes qui doivent être chargées en amont.
  • Il ne s'agit pas d'une fonctionnalité spécifique, mais d'éléments qui nécessitent tout de même la décision du développeur. Par exemple, évitez les polices ou les scripts synchrones qui retardent l'affichage anticipé.

Schéma représentant le spectre entre les optimisations automatiques et manuelles pour les développeurs

Les optimisations nécessitant une décision de la part des développeurs présentent un risque pour les performances de l'application. À mesure que des fonctionnalités sont ajoutées et que votre équipe évolue, même les développeurs les plus expérimentés ne peuvent pas suivre l'évolution constante des bonnes pratiques ni optimiser l'utilisation de leur temps. Pour assurer la conformité, des règles exploitables appropriées sont aussi importantes que des valeurs par défaut fortes pour garantir que l'application continue de répondre à une certaine norme, même lorsque les développeurs continuent d'apporter des modifications.

3. Date et heure de création

Il est important de détecter et d'anticiper les problèmes de performances dès le début du cycle de développement. Le temps de création, avant la validation du code, est idéal pour détecter et résoudre les problèmes. Plus un problème est détecté tard dans le cycle de vie du développement, plus il est difficile et coûteux de le résoudre. Bien que cela s'applique aux problèmes d'exactitude, il est également vrai pour les problèmes de performances, car bon nombre de ces problèmes ne seront pas résolus rétroactivement une fois le commit dans le codebase effectué.

Aujourd'hui, la plupart des retours sur les performances sont hors bande via la documentation, les audits ponctuels ou sont révélés trop tard lors de la régression des métriques après le déploiement en production. Nous voulons les amener à la création.

Conformité dans les frameworks

Pour maintenir une expérience utilisateur d'une qualité optimale en termes de performances de chargement, vous devez répondre aux questions suivantes:

  1. En quoi consiste un chargement optimal, et quels sont les problèmes courants susceptibles d'avoir un impact négatif sur celui-ci ?
  2. Quelles solutions peuvent être intégrées et ne nécessitent pas l'intervention des développeurs ?
  3. Comment pouvons-nous nous assurer que le développeur utilise ces solutions et les exploite de manière optimale ?
  4. Quelles autres options le développeur pourrait-il prendre pour avoir un impact sur les performances de chargement ?
  5. Quels sont les modèles de code qui peuvent nous renseigner sur ces choix (n° 3 et 4 ci-dessus) dès le début de la création ?
  6. Quelles règles pouvons-nous formuler pour évaluer ces modèles de code ? Comment peuvent-elles être présentées au développeur au moment de la création tout en étant parfaitement intégrées à son workflow ?

Pour intégrer le modèle de conformité interne de Google aux frameworks Open Source, notre équipe a effectué de nombreux tests sur Next.js, et nous sommes impatients de partager notre vision et nos projets affinés. Nous nous sommes rendu compte que le meilleur ensemble de règles permettant d'évaluer les modèles de code devra être une combinaison d'analyse de code statique et de vérifications dynamiques. Ces règles peuvent s'appliquer à plusieurs surfaces, y compris:

  • ESLint
  • TypeScript
  • Vérifications dynamiques sur le serveur de développement de l'utilisateur (post-création du DOM)
  • Bundler de module (webpack)
  • Outils CSS (encore exploratoire)

En fournissant des règles via différents outils, nous pouvons garantir leur cohérence, tout en prenant en compte les problèmes d'expérience utilisateur qui affectent directement les performances de chargement. De plus, ces règles peuvent également être présentées aux développeurs à différents moments:

  • Lors du développement local sur le serveur de développement, l'IDE du navigateur et de l'utilisateur affichera des avertissements invitant les développeurs à apporter de légères modifications au code.
  • Au moment de la compilation, les problèmes non résolus s'affichent de nouveau dans le terminal de l'utilisateur

En bref, les équipes choisiront les résultats qui les intéressent, comme les métriques Core Web Vitals ou les performances de chargement, et permettront à tous les contributeurs de code de suivre les ensembles de règles pertinents.

Bien que cela fonctionne très bien pour les nouveaux projets, il n'est pas facile de mettre à niveau des codebases volumineux pour respecter des ensembles de règles complets. Chez Google, nous disposons d'un système complet de désactivation à différents niveaux, tel que des lignes de code source individuelles, des répertoires entiers, d'anciens codebases ou des parties de l'application qui ne sont pas en cours de développement. Nous étudions activement des stratégies efficaces pour proposer cette fonctionnalité aux équipes à l'aide de frameworks Open Source.

Conformité dans Next.js

ESLint est largement utilisé par les développeurs JavaScript, et plus de 50% des applications Next.js l'utilisent dans une partie de leur workflow de compilation. Next.js v11 est directement compatible avec ESLint, qui inclut un plug-in personnalisé et une configuration partageable pour faciliter la détection des problèmes courants propres au framework pendant le développement et au moment de la compilation. Cela peut aider les développeurs à résoudre des problèmes importants au moment de la création. Par exemple, lorsqu'un composant donné est utilisé ou non d'une manière qui pourrait nuire aux performances, comme dans l'article Pas de lien HTML pour la page. Si une police, une feuille de style ou un script donné peut avoir un impact négatif sur le chargement des ressources sur une page. Par exemple, Pas de script synchrone.

Outre ESLint, Next.js accepte la vérification intégrée des types dans le développement et la production depuis la version 9, et est compatible avec TypeScript. Plusieurs composants fournis par le framework (Image, Script, Link) ont été créés en tant qu'extension d'éléments HTML (<img>, <script>, <a>) pour fournir aux développeurs une approche efficace pour ajouter du contenu à une page Web. La vérification du type permet une utilisation appropriée de ces fonctionnalités en s'assurant que les propriétés et les options attribuées se trouvent dans le champ d'application acceptable des valeurs et des types acceptés. Pour obtenir un exemple, consultez la section Largeur et hauteur d'image obligatoires.

Identifier les erreurs avec des toasts et des superpositions

Comme indiqué précédemment, les règles de conformité peuvent être appliquées dans plusieurs domaines. Les toasts et les superpositions sont actuellement à l'étude afin d'identifier les erreurs directement dans le navigateur, au sein de l'environnement de développement local de l'utilisateur.

Erreurs signalées via des toasts

De nombreux outils de vérification des erreurs et d'audit sur lesquels s'appuient les développeurs (Lighthouse, onglet "Problèmes des outils pour les développeurs Chrome") sont passifs et nécessitent une certaine interaction utilisateur pour récupérer des informations. Les développeurs sont plus susceptibles d'agir lorsque des erreurs apparaissent directement dans leurs outils existants, et lorsqu'ils fournissent des mesures concrètes et spécifiques à prendre pour résoudre le problème.

Conformité dans d'autres cadres

La conformité est d'abord explorée dans Next.js afin de l'étendre à d'autres frameworks (Nuxt, Angular, etc.). ESLint et TypeScript sont déjà utilisés dans de nombreux frameworks de différentes manières, mais le concept de système d'exécution cohérent au niveau du navigateur est activement étudié.

Conclusion

La conformité codifie les bonnes pratiques dans des ensembles de règles exploitables par les développeurs sous la forme de modèles de code simples. L'équipe Aurora s'est concentrée sur les performances de chargement, mais d'autres bonnes pratiques, telles que l'accessibilité et la sécurité, sont tout aussi applicables.

Le respect des règles de conformité devrait conduire à des résultats prévisibles. Atteindre un niveau d'expérience utilisateur élevé peut devenir un effet secondaire du développement de votre pile technologique. La conformité rend les équipes productives et garantit un haut niveau de qualité pour l'application, même si les équipes et le codebase augmentent au fil du temps.