Fermer

janvier 6, 2020

Liste de contrôle des performances frontales 2020 [PDF, Apple Pages, MS Word]


À propos de l'auteur

Vitaly Friedman aime le beau contenu et n'aime pas céder facilement. Lorsqu'il n'écrit pas ou ne parle pas lors d'une conférence, il court très probablement…
En savoir plus sur
Vitaly
Friedman

Faisons 2020… vite! Une liste de contrôle annuelle des performances front-end (PDF / Pages Apple / MS Word), avec tout ce que vous devez savoir pour créer des expériences rapides sur le Web aujourd'hui. Mise à jour depuis 2016. Merci à nos chers amis de LogRocket une solution de surveillance des performances frontale qui aide à reproduire les bogues et à résoudre les problèmes plus rapidement.

Les performances Web sont une bête délicate, n'est-ce pas? Comment savons-nous réellement où nous en sommes en termes de performances et quels sont exactement nos goulots d'étranglement ? Est-ce du code JavaScript coûteux, une livraison lente des polices Web, des images lourdes ou un rendu lent? Cela vaut-il la peine d'explorer les tremblements d'arbre, le levage de la portée, le fractionnement du code et tous les modèles de chargement sophistiqués avec l'observateur d'intersection, la poussée du serveur, les conseils des clients, HTTP / 2, les travailleurs de service et – oh mon – travailleurs de pointe? Et, plus important encore, où pouvons-nous même commencer à améliorer les performances et comment établir une culture de la performance à long terme?

À l'époque, les performances n'étaient souvent qu'une simple réflexion . Souvent différé jusqu'à la toute fin du projet, il se résumait à une minification, une concaténation, une optimisation des actifs et potentiellement quelques ajustements fins dans le fichier de configuration du serveur . En regardant en arrière maintenant, les choses semblent avoir changé de façon assez significative.

Les performances ne sont pas seulement une préoccupation technique: elles affectent tout, de l'accessibilité à la convivialité à l'optimisation des moteurs de recherche, et lors de l'intégration dans le flux de travail, les décisions de conception doivent être éclairées par leurs implications en termes de performances. Les performances doivent être mesurées, surveillées et affinées en permanence et la complexité croissante du Web pose de nouveaux défis qui rendent difficile le suivi des métriques, car les métriques varient considérablement en fonction de l'appareil, du navigateur, du protocole , le type de réseau et la latence (les CDN, les FAI, les caches, les mandataires, les pare-feu, les équilibreurs de charge et les serveurs jouent tous un rôle dans les performances).

Donc, si nous avons créé une vue d'ensemble de toutes les choses que nous devons garder à l'esprit lors de l'amélioration performance – du tout début du processus jusqu'à la version finale du site Web – à quoi ressemblerait cette liste? Vous trouverez ci-dessous une liste de contrôle des performances frontales (espérons-le impartiale et objective) pour 2020 – un aperçu mis à jour des problèmes que vous devrez peut-être prendre en compte pour vous assurer que vos temps de réponse sont rapides, l'interaction utilisateur est fluide. et vos sites ne drainent pas la bande passante de l'utilisateur.

Table des matières

(Vous pouvez aussi simplement télécharger la liste de contrôle PDF (166 Ko) ou télécharger le fichier Apple Pages éditable (275 Ko) ou le fichier .docx (151 Ko). Bonne optimisation, tout le monde!)

Préparatifs: planification et mesures

Les micro-optimisations sont idéales pour maintenir les performances sur la bonne voie, mais il est essentiel d'avoir des objectifs clairement définis à l'esprit – des objectifs mesurables qui pourraient influencer les décisions prises tout au long du processus. Il existe plusieurs modèles différents, et ceux dont il est question ci-dessous sont assez subjectifs – assurez-vous simplement de définir vos propres priorités dès le début.

  1. Établissez une culture de la performance.
    Dans de nombreuses organisations, les développeurs frontaux savent exactement ce que les problèmes sous-jacents courants et les schémas de chargement à utiliser pour les résoudre. Cependant, tant qu'il n'y aura pas d'approbation établie de la culture de la performance, chaque décision se transformera en champ de bataille des départements, divisant l'organisation en silos. Vous avez besoin d'une adhésion des parties prenantes de l'entreprise, et pour l'obtenir, vous devez établir une étude de cas, ou une preuve de concept en utilisant la API de performance sur les avantages de la vitesse pour les mesures et la clé Indicateurs de performance ( KPI ) dont ils se soucient.

    Sans un fort alignement entre les équipes de développement / conception et commerciales / marketing, les performances ne vont pas durer à long terme. Étudiez les réclamations courantes qui arrivent dans le service client et l'équipe de vente, étudiez l'analyse des taux de rebond élevés et des baisses de conversion. Découvrez comment l'amélioration des performances peut aider à résoudre certains de ces problèmes courants. Ajustez l'argument en fonction du groupe de parties prenantes à qui vous parlez.

    Exécutez des tests de performances et mesurez les résultats – à la fois sur mobile et sur ordinateur (par exemple, avec Google Analytics ) . Il vous aidera à créer une étude de cas sur mesure avec des données réelles. De plus, l'utilisation de données d'études de cas et d'expériences publiées sur WPO Stats aidera à accroître la sensibilité des entreprises quant à l'importance des performances et à leur impact sur l'expérience utilisateur et les mesures commerciales. Dire que la performance importe à elle seule ne suffit pas – vous devez également établir des objectifs mesurables et traçables et les observer au fil du temps.

    Comment y arriver? Dans son exposé sur Construire des performances à long terme Allison McKnight partage une étude de cas complète sur la manière dont elle a aidé à établir une culture de la performance à Etsy ( diapositives ). Plus récemment, Tammy Averts a parlé des habitudes des équipes de performance très efficaces dans les petites et les grandes organisations.

 Brad Frost et Jonathan Fielding's Performance Budget Calculator
Performance budget builder par Brad Frost et le calculateur de budget de performances de Jonathan Fielding peut vous aider à configurer votre budget de performances et à le visualiser. ( Grand aperçu )
  1. Objectif: être au moins 20% plus rapide que votre concurrent le plus rapide.
    Selon recherche psychologique si vous voulez que les utilisateurs sentent que votre site Web est plus rapide que le site Web de votre concurrent, vous devez être au moins 20% plus rapide. Étudiez vos principaux concurrents, collectez des mesures sur leurs performances sur mobile et sur ordinateur et définissez des seuils qui vous aideraient à les dépasser. Pour obtenir des résultats et des objectifs précis, assurez-vous d'abord d'avoir une image complète de l'expérience de vos utilisateurs en étudiant vos analyses. Vous pouvez ensuite imiter l'expérience du 90e centile pour les tests.

    Pour avoir une bonne première impression de la performance de vos concurrents, vous pouvez utiliser Chrome UX Report ( CrUX un prêt- made RUM data set, introduction vidéo par Ilya Grigorik et guide détaillé par Rick Viscomi) ou Treo Sites un outil de surveillance RUM alimenté par Chrome UX Report . Alternativement, vous pouvez également utiliser Speed ​​Scorecard (fournit également un estimateur d'impact sur les revenus), Comparaison des tests d'expérience utilisateur réelle ou SiteSpeed ​​CI (basé sur des tests synthétiques).

     Treo Sites fournit une analyse concurrentielle basée sur des données réelles
    Treo Sites fournit une analyse concurrentielle basée sur des données réelles. ( Grand aperçu )

    Remarque : Si vous utilisez Page Speed ​​Insights (non, ce n'est pas obsolète), vous pouvez obtenir des données de performances CrUX pour des pages spécifiques à la place juste des agrégats. Ces données peuvent être beaucoup plus utiles pour définir des objectifs de performances pour des actifs tels que la «page de destination» ou la «liste de produits». Et si vous utilisez CI pour tester les budgets, vous devez vous assurer que votre environnement testé correspond à CrUX si vous avez utilisé CrUX pour définir la cible ( merci Patrick Meenan! ).

    Si vous avez besoin d'aide pour montrer le raisonnement derrière la priorisation de la vitesse, ou vous souhaitez visualiser la décroissance du taux de conversion ou l'augmentation du taux de rebond avec des performances plus lentes, ou peut-être auriez-vous besoin de plaider pour une solution RUM dans votre organisation, Sergey Chernyshev a construit un UX Speed ​​Calculator un outil open source qui vous aide à simuler des données et à les visualiser pour faire valoir votre point de vue.

     Juste au moment où vous avez besoin de justifier les performances pour conduire votre point à travers: UX Speed ​​Calculator visualise un impact de la performance sur les taux de rebond, la conversion et le revenu total, basé sur des données réelles
    Juste au moment où vous avez besoin de faire valoir les performances pour conduire votre point à travers: UX Speed ​​Calculator visualise un impact de perf ormanc sur les taux de rebond, la conversion et le revenu total – sur la base de données réelles. ( Grand aperçu )

    Collectez des données, configurez une feuille de calcul réduisez de 20% et définissez vos objectifs ( budgets de performance ) de cette façon. Vous avez maintenant quelque chose de mesurable à tester. Si vous gardez le budget à l'esprit et que vous essayez de ne fournir que la charge utile minimale pour obtenir un temps d'interaction rapide, alors vous êtes sur une voie raisonnable.

    Besoin de ressources pour commencer?

    Une fois vous avez un budget en place, incorporez-les dans votre processus de construction avec Webpack Performance Hints et Bundlesize Lighthouse CI PWMetrics ou Sitespeed CI pour appliquer les budgets sur les demandes d'extraction et fournir un historique des scores dans les commentaires PR.

    Pour exposer les budgets de performances à toute l'équipe, intégrer les budgets de performances dans Lighthouse via Lightwallet . Et si vous avez besoin de quelque chose de personnalisé, vous pouvez utiliser webpagetest-charts-api une API de noeuds finaux pour créer des graphiques à partir des résultats de WebPagetest.

    La conscience des performances ne doit cependant pas provenir uniquement des budgets de performances. Tout comme Pinterest vous pouvez créer une règle eslint personnalisée qui interdit l'importation à partir de fichiers et de répertoires connus pour leur lourdeur de dépendance et qui ferait gonfler le bundle. Définissez une liste de packages «sûrs» qui peuvent être partagés par l'ensemble de l'équipe.

    Réfléchissez également aux tâches essentielles du client qui sont les plus avantageuses pour votre entreprise. Étudiez, discutez et définissez des seuils de temps acceptables pour les actions critiques et établissez des repères de synchronisation utilisateur "UX ready" que toute l'organisation a approuvés. Dans de nombreux cas, les parcours des utilisateurs toucheront au travail de nombreux départements différents, donc l'alignement en termes de délais acceptables aidera à soutenir ou à empêcher les discussions sur les performances en cours de route. Assurez-vous que les coûts supplémentaires des ressources et des fonctionnalités supplémentaires sont visibles et compris.

    C'est une bonne idée d'aligner les efforts de performance avec d'autres initiatives technologiques, allant des nouvelles parties du site à la refactorisation à de nouveaux publics mondiaux. Il est plus facile d'investir lorsque le code est actualisé ou en cours d'actualisation. En outre, 20% plus rapide que la concurrence peut également signifier 20% plus rapide que votre ancien moi une fois que vous avez établi une forte culture de performance dans votre organisation. ( merci, Guy Podjarny! )

    De plus, comme l'a suggéré Patrick Meenan, il vaut la peine de planifier une séquence de chargement et des compromis pendant le processus de conception. Si vous priorisez rapidement les parties les plus critiques et définissez l'ordre dans lequel elles doivent apparaître, vous saurez également ce qui peut être retardé. Idéalement, cet ordre reflétera également la séquence de vos importations CSS et JavaScript, donc les manipuler pendant le processus de construction sera plus facile. Réfléchissez également à ce que devrait être l'expérience visuelle dans les états "intermédiaires" pendant le chargement de la page (par exemple, lorsque les polices Web ne sont pas encore chargées).

    Planning, planning, planning. Il pourrait être tentant de se lancer rapidement dans des "optimisations rapides" – et, éventuellement, ce pourrait être une bonne stratégie pour des gains rapides – mais il sera très difficile de maintenir la performance prioritaire sans planifier et définir une entreprise réaliste.

La différence entre First Paint, First Contentful Paint, First Signful Paint, Visual Complete et Time To Interactive. Grande vue . Crédit: @ denar90
 De nouvelles mesures atterrissent dans Lighthouse v6 au début de 2020. La première peinture significative (FMP) est désormais déconseillée, et la plus grande peinture contentante (LCP) et la durée totale de blocage (TBT) arriveront bientôt dans Lighthouse [19659021] De nouvelles mesures atterrissent dans Lighthouse v6 au début de 2020. La première peinture significative (FMP) est maintenant déconseillée, et la plus grande peinture contentieuse (LCP) et le temps de blocage total (TBT) arrivent bientôt dans Lighthouse. (<a href= Grand aperçu )
  1. Choisissez les bonnes mesures.
    Toutes les mesures n'ont pas la même importance . Étudiez les métriques les plus importantes pour votre application: généralement, elles seront définies par la vitesse à laquelle vous pouvez commencer à rendre les pixels les plus importants de votre interface et la vitesse à laquelle vous pouvez fournir une réactivité d'entrée pour ces pixels rendus. Cette connaissance vous donnera la meilleure cible d'optimisation pour les efforts en cours. En fin de compte, ce ne sont pas les événements de chargement ou les temps de réponse du serveur qui définissent l'expérience, mais la perception de la vivacité de l'interface .

    Qu'est-ce que cela signifie? Plutôt que de se concentrer sur le temps de chargement de la page entière (via onLoad et DOMContentLoaded par exemple), donnez la priorité au chargement de page tel que perçu par vos clients . Cela signifie se concentrer sur un ensemble de mesures légèrement différent. En fait, choisir la bonne métrique est un processus sans gagnants évidents.

    Sur la base des recherches de Tim Kadlec et des notes de Marcos Iglesias dans son ​​exposé les métriques traditionnelles pourraient être regroupées en quelques ensembles. Habituellement, nous aurons besoin de chacun d'eux pour obtenir une image complète des performances, et dans votre cas particulier, certains d'entre eux peuvent être plus importants que d'autres.

    • Les mesures basées sur la quantité mesurent le nombre de demandes, le poids et un score de performance. Bon pour déclencher des alarmes et surveiller les changements au fil du temps, pas si bon pour comprendre l'expérience utilisateur.
    • Les métriques de jalon utilisent des états pendant la durée de vie du processus de chargement, par ex. Time To First Byte et Time To Interactive . Bon pour décrire l'expérience utilisateur et la surveillance, pas très bon pour savoir ce qui se passe entre les jalons.
    • Les métriques de rendu fournissent une estimation de la rapidité du rendu du contenu (par exemple Démarrer le rendu ] Indice de vitesse ). Bon pour mesurer et peaufiner les performances de rendu, mais pas si bon pour mesurer quand un contenu important apparaît et peut être interagi avec.
    • Les métriques personnalisées mesurent un événement personnalisé particulier pour l'utilisateur, par ex. Twitter Time To First Tweet et Pinterest PinnerWaitTime . Bon pour décrire avec précision l'expérience utilisateur, pas très bon pour mettre à l'échelle les statistiques et comparer avec les concurrents.

    Pour compléter le tableau, nous recherchons généralement des statistiques utiles parmi tous ces groupes. Généralement, les plus spécifiques et les plus pertinents sont les suivants:

    • Time to Interactive (TTI)
      Le point auquel la mise en page s'est stabilisée, les polices Web clés sont visibles et le thread principal est suffisamment disponible pour gérer les entrées utilisateur – Fondamentalement, la date à laquelle un utilisateur peut interagir avec l'interface utilisateur. Les mesures clés pour comprendre combien d'attente un utilisateur doit subir pour utiliser le site sans décalage.
    • Premier délai d'entrée (FID) ou Réactivité d'entrée [19659048] Le temps entre le moment où un utilisateur interagit pour la première fois avec votre site et le moment où le navigateur est réellement en mesure de répondre à cette interaction. Complète très bien TTI car il décrit la partie manquante de l'image: ce qui se passe lorsqu'un utilisateur interagit réellement avec le site. Destiné en tant que métrique RUM uniquement. Il existe une bibliothèque JavaScript pour mesurer le FID dans le navigateur.
    • La plus grande peinture riche en contenu (LCP)
      Marque le point dans la chronologie de chargement de la page lorsque le contenu important de la page a probablement été chargé. L'hypothèse est que l'élément le plus important de la page est le plus grand visible dans la fenêtre d'affichage de l'utilisateur . Si les éléments sont rendus au-dessus et en dessous du pli, seule la partie visible est considérée comme pertinente. Actuellement une métrique cachée dans Lighthouse, à déployer si elle s'avère utile.
    • Temps de blocage total ( TBT )
      Une nouvelle métrique qui permet de quantifier la gravité de la non -une page interactive est avant qu'elle ne devienne de manière fiable interactive (c'est-à-dire que le thread principal n'a été soumis à aucune tâche de plus de 50 ms ( tâches longues ) pendant au moins 5 s). La métrique mesure le temps total entre la première peinture et le temps d'interaction (TTI) où le thread principal a été bloqué suffisamment longtemps pour empêcher la réactivité de l'entrée. Pas étonnant, alors, qu'un TBT faible soit un bon indicateur de bonnes performances. (merci, Artem, Phil)
    • Décalage de mise en page cumulatif ( CLS )
      La métrique met en évidence la fréquence à laquelle les utilisateurs subissent des changements de mise en page inattendus ( reflows ) lors de l'accès au site. Il examine les éléments instables et leur impact sur l'expérience globale. Plus le score est bas, mieux c'est.
    • Indice de vitesse
      Mesure la vitesse de remplissage visuel du contenu de la page; plus le score est bas, mieux c'est. Le score de l'indice de vitesse est calculé en fonction de la vitesse de progression visuelle, mais il s'agit simplement d'une valeur calculée. Il est également sensible à la taille de la fenêtre d'affichage. Vous devez donc définir une gamme de configurations de test qui correspondent à votre public cible. Notez que cela devient moins important avec l'arrivée de LCP en tant que nouvelle métrique ( merci, Boris Artem! ).
    • Temps CPU passé
      Une métrique qui montre combien de fois et combien de temps le fil principal est bloqué, travaillant sur la peinture, le rendu, l'écriture de scripts et le chargement. Un temps CPU élevé est un indicateur clair d'une expérience janky c'est-à-dire lorsque l'utilisateur connaît un décalage notable entre son action et une réponse. Avec WebPageTest, vous pouvez sélectionner "Capture Dev Tools Timeline" dans l'onglet "Chrome" pour exposer la répartition du thread principal lors de son exécution sur n'importe quel appareil utilisant WebPageTest.
    • Component-Level Coûts CPU
      Tout comme avec le temps CPU passé cette métrique, proposée par Stoyan Stefanov, explore l'impact de JavaScript sur le CPU. L'idée est d'utiliser le nombre d'instructions CPU par composant pour comprendre son impact sur l'expérience globale, de manière isolée. Pourrait être implémenté en utilisant Puppeteer et Chrome .
    • FrustrationIndex
      Alors que de nombreuses mesures présentées ci-dessus expliquent quand un événement particulier se produit, FrustrationIndex de Tim Vereecke examine les écarts entre au lieu de les regarder individuellement. Il examine les étapes clés perçues par l'utilisateur final, telles que le titre est visible, le premier contenu est visible, visuellement prêt et la page semble prête et calcule un score indiquant le niveau de frustration lors du chargement d'une page. Plus l'écart est grand, plus les chances qu'un utilisateur soit frustré sont grandes. Potentiellement un bon KPI pour l'expérience utilisateur. Tim a publié un article détaillé sur FrustrationIndex et son fonctionnement.
    • Impact du poids de l'annonce
      Si votre site dépend des revenus générés par la publicité, il est utile de suivre le poids de l'annonce code associé. Le script de Paddy Ganti construit deux URL (une normale et une bloquant les publicités), invite à la génération d'une comparaison vidéo via WebPageTest et signale un delta.
    • Mesures de déviation
      Comme l'a noté par Les ingénieurs de Wikipédia les données de la variance existant dans vos résultats pourraient vous informer de la fiabilité de vos instruments et de l'attention à accorder aux écarts et aux sorties. Une grande variance est un indicateur des ajustements nécessaires dans la configuration. Il permet également de comprendre si certaines pages sont plus difficiles à mesurer de manière fiable, par exemple en raison de scripts tiers provoquant des variations importantes. Il peut également être judicieux de suivre la version du navigateur pour comprendre les hausses de performances lorsqu'une nouvelle version du navigateur est déployée.
    • Mesures personnalisées
      Les mesures personnalisées sont définies par les besoins de votre entreprise et l'expérience client. Cela vous oblige à identifier les pixels importants, les scripts critiques, les CSS nécessaires et les actifs pertinents et à mesurer la vitesse à laquelle ils sont livrés à l'utilisateur . Pour celui-ci, vous pouvez surveiller Hero Rendering Times ou utiliser Performance API en marquant des horodatages particuliers pour les événements importants pour votre entreprise. De plus, vous pouvez collecter des mesures personnalisées avec WebPagetest en exécutant du JavaScript arbitraire à la fin d'un test.

    Notez que la Première peinture significative (FMP) ne fonctionne pas apparaissent dans l'aperçu ci-dessus. Il fournissait un aperçu de la vitesse à laquelle le serveur sort toutes les données . Le long FMP indiquait généralement que JavaScript bloquait le thread principal, mais pouvait également être lié à des problèmes de back-end / serveur. Cependant, la métrique a été déconseillée récemment car elle ne semble pas exacte dans environ 20% des cas. Il ne sera plus pris en charge dans les prochaines versions de Lighthouse.

    Steve Souders a une explication détaillée de la plupart de ces mesures . Il est important de noter que si le temps d'interaction est mesuré en exécutant des audits automatisés dans l'environnement de laboratoire le premier délai d'entrée représente l'expérience utilisateur réelle avec utilisateurs réels connaissant un décalage notable. En général, c'est probablement une bonne idée de toujours mesurer et suivre les deux.

    Selon le contexte de votre application, les mesures préférées peuvent différer: par exemple pour Netflix TV UI, la réactivité des entrées clés, l'utilisation de la mémoire et le TTI sont plus critiques, et pour Wikipedia, les premiers / derniers changements visuels et les mesures de temps CPU passé sont plus importants.

    Remarque : FID et TTI ne tiennent pas compte du comportement de défilement; le défilement peut se produire indépendamment car il est hors fil principal, donc pour de nombreux sites de consommation de contenu, ces métriques peuvent être beaucoup moins importantes ( merci, Patrick! ).

Les métriques de performance centrées sur l'utilisateur fournissent un meilleur aperçu dans l'expérience utilisateur réelle. Premier délai d'entrée (FID) est une nouvelle métrique qui tente d'atteindre cet objectif. ( Grand aperçu )
  1. Rassemblez des données sur un appareil représentatif de votre public.
    Pour recueillir des données précises, nous devons choisir soigneusement les appareils sur lesquels tester. Dans la plupart des entreprises, cela signifie examiner les analyses et créer des profils d'utilisateurs basés sur les types d'appareils les plus courants. Pourtant, souvent, l'analyse seule ne fournit pas une image complète. Une partie importante du public cible pourrait abandonner le site (et ne pas revenir) simplement parce que son expérience est trop lente et que ses appareils ne se présenteront probablement pas comme les appareils les plus populaires en analytique. Par conséquent, mener des recherches sur les appareils courants dans votre groupe cible pourrait également être une bonne idée.

    À l'échelle mondiale en 2018-2019, selon l'IDC, 87% de tous les téléphones mobiles expédiés sont des appareils Android . Un consommateur moyen met à niveau son téléphone tous les 2 ans et aux États-Unis le cycle de remplacement est de 33 mois . En moyenne, les téléphones les plus vendus dans le monde coûteront moins de 200 $.

    Un appareil représentatif est donc un appareil Android qui a au moins 24 mois coûtant 200 $ ou moins, fonctionnant sur 3G lent, RTT 400 ms et un transfert de 400 kbps, juste pour être un peu plus pessimiste. Cela peut être très différent pour votre entreprise, bien sûr, mais c'est une approximation suffisamment proche de la majorité des clients. En fait, il pourrait être judicieux d'examiner les best-sellers d'Amazon actuels pour votre marché cible. ( Merci à Tim Kadlec, Henri Helvetica et Alex Russel pour les pointeurs! ).

    Quels appareils de test choisir alors? Celles qui correspondent bien au profil décrit ci-dessus. C'est une bonne option pour choisir un Moto G4 / G5 Plus un appareil Samsung milieu de gamme (Galaxy A50, S8), un bon appareil intermédiaire comme un Nexus 5X, Xiaomi Mi A3 ou Xiaomi Redmi Note 7 et un appareil lent comme Alcatel 1X ou Cubot X19, peut-être dans un laboratoire d'appareils ouvert . Pour les tests sur des appareils à régulation thermique plus lents, vous pouvez également obtenir un Nexus 4, qui coûte environ 100 $.

    Vérifiez également les chipsets utilisés dans chaque appareil et ne surreprésente pas un chipset : quelques générations de Snapdragon et Apple ainsi que de Rockchip bas de gamme, Mediatek serait suffisant (merci, Patrick!) .

    Si vous n'avez pas d'appareil à portée de main, émulez l'expérience mobile sur ordinateur de bureau en testant sur un réseau 3G étranglé (par exemple 300 ms RTT, 1,6 Mbps vers le bas, 0,8 Mbps vers le haut) avec un processeur étranglé (5 × ralentissement). Basculez éventuellement vers la 3G régulière, la 4G lente (par exemple 170 ms RTT, 9 Mbps vers le bas, 9Mbps vers le haut) et le Wi-Fi. Pour rendre l'impact sur les performances plus visible, vous pouvez même introduire les mardis 2G ou configurer un réseau 3G / 4G limité dans votre bureau pour des tests plus rapides.

    Gardez à l'esprit que sur un appareil mobile, nous devrions nous attendre à un ralentissement 4 × –5 × par rapport aux ordinateurs de bureau . Les appareils mobiles ont des GPU, CPU, mémoire et caractéristiques de batterie différents. C'est pourquoi il est important d'avoir un bon profil d'un appareil moyen et de toujours tester sur un tel appareil .

  2.  Présentation du jour le plus lent de la semaine
    Présentation du jour le plus lent de la semaine. Facebook a introduit les mardis 2G pour augmenter la visibilité et la sensibilité des connexions lentes. ( Source d'image )

    Heureusement, il existe de nombreuses options qui vous aident à automatiser la collecte de données et à mesurer les performances de votre site Web au fil du temps en fonction de ces mesures. Gardez à l'esprit qu'une bonne image des performances couvre un ensemble de mesures de performances, données de laboratoire et données de terrain :

  • Les outils de test synthétique collectent les données de laboratoire dans un environnement reproductible avec paramètres de périphérique et de réseau prédéfinis (par exemple Lighthouse Calibre WebPageTest ) et
  • Real User Monitoring ( RUM ) les outils évaluent les interactions des utilisateurs en continu et collectent les données de terrain (par exemple SpeedCurve New Relic – les outils fournissent également des tests synthétiques).

Le Le premier est particulièrement utile pendant le développement de car il vous aidera à identifier, isoler et résoudre les problèmes de performances tout en travaillant sur le produit. Ce dernier est utile pour la maintenance à long terme car il vous aidera à comprendre vos goulots d'étranglement de performances lorsqu'ils se produisent en direct – lorsque les utilisateurs accèdent réellement au site.

En utilisant des API RUM intégrées telles que Synchronisation de la navigation Synchronisation des ressources Synchronisation de la peinture Tâches longues etc., les outils de test synthétique et le RUM fournissent ensemble une image complète de performances dans votre application. Vous pouvez utiliser PWMetrics Calibre SpeedCurve mPulse et Boomerang Sitespeed.io qui sont tous d'excellentes options pour la surveillance des performances. De plus, avec En-tête de synchronisation du serveur vous pouvez même
surveiller les performances du back-end et du front-end en un seul endroit.

Remarque : Il est toujours plus sûr de choisir des régulateurs de niveau réseau externes au navigateur, comme, par exemple, DevTools a des problèmes d'interaction avec HTTP / 2 push, en raison de la façon dont il est implémenté (merci, Yoav, Patrick!). Pour Mac OS, nous pouvons utiliser Network Link Conditioner pour Windows Windows Traffic Shaper pour Linux netem et pour FreeBSD dummynet .

 Lighthouse
Lighthouse un outil d'audit des performances intégré à DevTools. ( Grand aperçu )
  1. Configurer des profils "propres" et "client" pour les tests.
    Lors de l'exécution de tests dans des outils de surveillance passive, c'est une stratégie courante pour désactiver l'antivirus et le processeur d'arrière-plan , supprimez les transferts de bande passante en arrière-plan et testez avec un profil utilisateur propre sans extensions de navigateur pour éviter des résultats biaisés ( Firefox Chrome ).

    Cependant, c'est aussi une bonne idée d'étudier les extensions que vos clients utilisent fréquemment et testez également avec un profil "client" dédié. En fait, certaines extensions peuvent avoir un impact profond sur les performances ( étude ) sur votre application, et si vos utilisateurs les utilisent beaucoup, vous voudrez peut-être en tenir compte dès le départ. Les résultats du profil «propre» à eux seuls sont trop optimistes et peuvent être écrasés dans des scénarios réels.

  2. Partagez les objectifs de performance avec vos collègues.
    Assurez-vous que les objectifs de performance sont familiers à chaque membre de votre équipe pour éviter les malentendus sur toute la ligne. Chaque décision – que ce soit la conception, le marketing ou tout ce qui se situe entre les deux – a des implications en termes de performances, et la distribution des responsabilités et de la propriété à l'ensemble de l'équipe rationaliserait les décisions axées sur les performances ultérieurement. Mapper les décisions de conception par rapport au budget de performance et aux priorités définies très tôt.

Fixation d'objectifs réalistes

  1. Temps de réponse de 100 millisecondes, 60 ips.
    Pour qu'une interaction soit fluide, l'interface dispose de 100 ms pour répondre aux entrées de l'utilisateur . Plus longtemps que cela, et l'utilisateur perçoit l'application comme lente. The RAIL, a user-centered performance model gives you healthy targets: To allow for <100 milliseconds response, the page must yield control back to main thread at latest after every <50 milliseconds. Estimated Input Latency tells us if we are hitting that threshold, and ideally, it should be below 50ms. For high-pressure points like animation, it’s best to do nothing else where you can and the absolute minimum where you can't.
    RAIL
    RAILa user-centric performance model.

    Also, each frame of animation should be completed in less than 16 milliseconds, thereby achieving 60 frames per second (1 second ÷ 60 = 16.6 milliseconds) — preferably under 10 milliseconds. Because the browser needs time to paint the new frame to the screen, your code should finish executing before hitting the 16.6 milliseconds mark. We’re starting to have conversations about 120fps (e.g. iPad Pro’s screens run at 120Hz) and Surma has covered some rendering performance solutions for 120fpsbut that’s probably not a target we’re looking at just yet.

    Be pessimistic in performance expectations, but be optimistic in interface design and use idle time wisely (check idlize and idle-until-urgent). Obviously, these targets apply to runtime performance, rather than loading performance.

  2. FID < 100ms, TTI < 5s on 3G, Speed Index < 3s, Critical file size budget
    Although it might be very difficult to achieve, a good ultimate goal would be Speed Index under 3s and Time to Interactive under 5sand for repeat visits, aim for under 2s (achievable only with a service worker). Aim for Largest Contentful Paint of under 1s and minimize Total Blocking Time and Cumulative Layout Shift. An acceptable First Input Delay (highlighted as Max Potential First Input Delay in Lighthouse) is under 130–100ms. As mentioned above, we’re considering the baseline being a $200 Android phone (e.g. Moto G4) on a slow 3G network, emulated at 400ms RTT and 400kbps transfer speed.

    We have two major constraints that effectively shape a reasonable target for speedy delivery of the content on the web. On the one hand, we have network delivery constraints due to TCP Slow Start. The first 14KB of the HTML — 10 TCP packets, each 1460 bytes, making around 14.25 KB, albeit not to be taken literally — is the most critical payload chunk, and the only part of the budget that can be delivered in the first roundtrip (which is all you get in 1 sec at 400ms RTT due to mobile wake-up times).

    (Note: as TCP generally under-utilizes network connection by a significant amount, Google has developed TCP Bottleneck Bandwidth and RRT (BBR), a relatively new TCP delay-controlled TCP flow control algorithm. Designed for the modern web, it responds to actual congestion, rather than packet loss like TCP does, it is significantly fasterwith higher throughput and lower latency — and the algorithm works differently. It's still important to prioritize critical resources as early as possible, but 14 KB might not be that relevant with BBR in place.) (thanks, Victor, Barry!)

    On the other hand, we have hardware constraints on memory and CPU due to JavaScript parsing times (we’ll talk about them in detail later). To achieve the goals stated in the first paragraph, we have to consider the critical file size budget for JavaScript. Opinions vary on what that budget should be (and it heavily depends on the nature of your project), but a budget of 170KB JavaScript gzipped already would take up to 1s to parse and compile on an average phone. Assuming that 170KB expands to 3× that size when decompressed (0.7MB), that already could be the death knell of a "decent" user experience on a Moto G4/G5 Plus.

    If you want to target growing markets such as South East Asia, Africa or India, you'll have to look into a very different set of constraints. Addy Osmani covers major feature phone constraintssuch as few low costs, high-quality devices, unavailability of high-quality networks and expensive mobile data — along with PRPL-30 budget and development guidelines for these environments.

    According to Addy Osmani, a recommended size for lazy-loaded routes is also less than 35 KB
    According to Addy Osmania recommended size for lazy-loaded routes is also less than 35 KB. (Large preview)
    Addy Osmani suggests PRPL-30 performance budget (30KB gzipped + minified initial bundle) if targeting a feature phone
    Addy Osmani suggests PRPL-30 performance budget (30KB gzipped + minified initial bundle) if targeting a feature phone. (Large preview)

    In fact, Google’s Alex Russel recommends to aim for 130–170KB gzipped as a reasonable upper boundary. In real-life world, most products aren’t even close: an median bundle size today is around 417KBwhich is up 42% compared to early 2015. On a middle-class mobile device, that accounts for 15–25 seconds for Time-To-Interactive.

    Geekbench CPU performance benchmarks for the highest selling smartphones globally in 2019. JavaScript stresses single-core performance and is CPU bound
    Geekbench CPU performance benchmarks for the highest selling smartphones globally in 2019. JavaScript stresses single-core performance (remember, it’s inherently more single-threaded than the rest of the Web Platform) and is CPU bound. From Addy’s article “Loading Web Pages Fast On A $20 Feature Phone”. (Large preview)

    We could also go beyond the bundle size budget though. For example, we could set performance budgets based on the activities of the browser’s main thread, i.e. paint time before start render, or track down front-end CPU hogs. Tools such as CalibreSpeedCurve and Bundlesize can help you keep your budgets in check, and can be integrated into your build process.

    Finally, a performance budget probably shouldn’t be a fixed value. Depending on the network connection, performance budgets should adaptbut payload on slower connection is much more "expensive", regardless of how they’re used.

    Note: It might sound strange to set such rigid budgets in times of wide-spread HTTP/2, upcoming 5Grapidly evolving mobile phones and flourishing SPAs. However, they do sound reasonable when we deal with the unpredictable nature of the network and hardware, including everything from congested networks to slowly developing infrastructure, to data capsproxy browsers, save-data mode and sneaky roaming charges.

From 'Fast By Default: Modern Loading Best Practices' by Addy Osmani
From Fast By Default: Modern loading best practices by Addy Osmani (Slide 19)
Performance budgets should adapt depending on the network conditions for an average mobile device. (Image source: Katie Hempenius) (Large preview)

Defining The Environment

  1. Choose and set up your build tools.
    Don’t pay too much attention to what’s supposedly cool these days. Stick to your environment for building, be it Grunt, Gulp, Webpack, Parcel, or a combination of tools. As long as you are getting results you need and you have no issues maintaining your build process, you’re doing just fine.

    Among the build tools, Rollup is gaining traction, but Webpack seems to be the most established one, with literally hundreds of plugins available to optimize the size of your builds. Getting started with Webpack can be tough though. So if you want to get started, there are some great resources out there:

  2. Use progressive enhancement as a default.
    Still, after all these years, keeping progressive enhancement as the guiding principle of your front-end architecture and deployment is a safe bet. Design and build the core experience first, and then enhance the experience with advanced features for capable browsers, creating resilient experiences. If your website runs fast on a slow machine with a poor screen in a poor browser on a sub-optimal network, then it will only run faster on a fast machine with a good browser on a decent network.

    In fact, with adaptive module servingwe seem to be taking progressive enhancement to another level, serving "lite" core experiences to low-end devices, and enhancing with more sophisticated features for high-end devices. Progressive enhancement isn't likely to fade away any time soon, so it seems.

  3. Choose a strong performance baseline.
    With so many unknowns impacting loading — the network, thermal throttling, cache eviction, third-party scripts, parser blocking patterns, disk I/O, IPC latency, installed extensions, antivirus software and firewalls, background CPU tasks, hardware and memory constraints, differences in L2/L3 caching, RTTS — JavaScript has the heaviest cost of the experiencenext to web fonts blocking rendering by default and images often consuming too much memory. With the performance bottlenecks moving away from the server to the clientas developers, we have to consider all of these unknowns in much more detail.

    With a 170KB budget that already contains the critical-path HTML/CSS/JavaScript, router, state management, utilities, framework, and the application logic, we have to thoroughly examine network transfer cost, the parse/compile-time and the runtime cost of the framework of our choice. Luckily, we’ve seen a huge improvement over the last few years in how fast browsers can parse and compile scripts. Yet the execution of JavaScript is still the main bottleneck, so paying close attention to script execution time and network can be impactful.

    As noted by Seb Markbåge, a good way to measure start-up costs for frameworks is to first render a view, then delete it and then render again as it can tell you how the framework scales. The first render tends to warm up a bunch of lazily compiled code, which a larger tree can benefit from when it scales. The second render is basically an emulation of how code reuse on a page affects the performance characteristics as the page grows in complexity.

  4. Evaluate frameworks and dependencies.
    Now, not every project needs a framework and not every page of a single-page-application needs to load a framework. In Netflix’s case, "removing React, several libraries and the corresponding app code from the client-side reduced the total amount of JavaScript by over 200KB, causing an over-50% reduction in Netflix’s Time-to-Interactivity for the logged-out homepage." The team then utilized the time spent by users on the landing page to prefetch React for subsequent pages that users were likely to land on (read on for details).

    It might sound obvious but worth stating: some projects can also benefit benefit from removing an existing framework altogether. Once a framework is chosen, you’ll be staying with it for at least a few years, so if you need to use one, make sure your choice is informed and well considered.

    Inian Parameshwaran has measured performance footprint of top 50 frameworks (against First Contentful Paint — the time from navigation to the time when the browser renders the first bit of content from the DOM). Inian discovered that, out there in the wild, Vue and Preact are the fastest across the board — both on desktop and mobile, followed by React (slides). You could examine your framework candidates and the proposed architecture, and study how most solutions out there perform, e.g. with server-side rendering or client-side rendering, on average.

    Baseline performance cost matters. According to a study by Ankur Sethi"your React application will never load faster than about 1.1 seconds on an average phone in India, no matter how much you optimize it. Your Angular app will always take at least 2.7 seconds to boot up. The users of your Vue app will need to wait at least 1 second before they can start using it." You might not be targeting India as your primary market anyway, but users accessing your site with suboptimal network conditions will have a comparable experience. In exchange, your team gains maintainability and developer efficiency, of course. But this consideration needs to be deliberate.

    You could go as far as evaluating a framework (or any JavaScript library) on Sacha Greif’s 12-point scale scoring system by exploring features, accessibility, stability, performance, package ecosystem, community, learning curve, documentation, tooling, track record, team, compatibility, security for example. But on a tough schedule, it’s a good idea to consider at least the total cost on size + initial parse times before choosing an option; lightweight options such as PreactInfernoVueSvelte or Polymer can get the job done just fine. The size of your baseline will define the constraints for your application’s code.

    There are many tools to help you make an informed decision about the impact of your dependencies and viable alternatives:

    A good starting point is to choose a good default stack for your application. Gatsby (React), Vuepress (Vue)Preact CLIand PWA Starter Kit provide reasonable defaults for fast loading out of the box on average mobile hardware. ​​Also, take a look at web.dev framework-specific performance guidance for React and Angular that's supposed to be expanded later this year (thanks, Phillip!).

CPU and compute performance of top-selling phones
CPU and compute performance of top-selling phones (Image credit: Addy Osmani) (Large preview)
  1. Consider using PRPL pattern and app shell architecture.
    Different frameworks will have different effects on performance and will require different strategies of optimization, so you have to clearly understand all of the nuts and bolts of the framework you’ll be relying on. When building a web app, look into the PRPL pattern and application shell architecture. The idea is quite straightforward: Push the minimal code needed to get interactive for the initial route to render quickly, then use service worker for caching and pre-caching resources and then lazy-load routes that you need, asynchronously.
PRPL Pattern in the application shell architecture
PRPL stands for Pushing critical resource, Rendering initial route, Pre-caching remaining routes and Lazy-loading remaining routes on demand.
Application shell architecture
An application shell is the minimal HTML, CSS, and JavaScript powering a user interface.
  1. Have you optimized the performance of your APIs?
    APIs are communication channels for an application to expose data to internal and third-party applications via so-called endpoints. When designing and building an APIwe need a reasonable protocol to enable the communication between the server and third-party requests. Representational State Transfer (REST) is a well-established, logical choice: it defines a set of constraints that developers follow to make content accessible in a performant, reliable and scalable fashion. Web services that conform to the REST constraints, are called RESTful web services.

    As with good ol' HTTP requests, when data is retrieved from an API, any delay in server response will propagate to the end user, hence delaying rendering. When a resource wants to retrieve some data from an API, it will need to request the data from the corresponding endpoint. A component that renders data from several resources, such as an article with comments and author photos in each comment, may need several roundtrips to the server to fetch all the data before it can be rendered. Furthermore, the amount of data returned through REST is often more than what is needed to render that component.

    If many resources require data from an API, the API might become a performance bottleneck. GraphQL provides a performant solution to these issues. Per se, GraphQL is a query language for your API, and a server-side runtime for executing queries by using a type system you define for your data. Unlike REST, GraphQL can retrieve all data in a single request, and the response will be exactly what is required, without over or under-fetching data as it typically happens with REST.

    In addition, because GraphQL is using schema (metadata that tells how the data is structured), it can already organize data into the preferred structure, so, for example, with GraphQL, we could remove JavaScript code used for dealing with state managementproducing a cleaner application code that runs faster on the client.

    If you want to get started with GraphQL, Eric Baer published two fantastic articles on yours truly Smashing Magazine: A GraphQL Primer: Why We Need A New Kind Of API and A GraphQL Primer: The Evolution Of API Design (thanks for the hint, Leonardo!).

Hacker Noon
A difference between REST and GraphQL, illustrated via a conversation between Redux + REST on the left, an Apollo + GraphQL on the right. (Image source: Hacker Noon) (Large preview)
  1. Will you be using AMP or Instant Articles?
    Depending on the priorities and strategy of your organization, you might want to consider using Google’s AMP or Facebook’s Instant Articles or Apple’s Apple News. You can achieve good performance without them, but AMP does provide a solid performance framework with a free content delivery network (CDN), while Instant Articles will boost your visibility and performance on Facebook.

    The seemingly obvious benefit of these technologies for users is guaranteed performanceso at times they might even prefer AMP-/Apple News/Instant Pages-links over "regular" and potentially bloated pages. For content-heavy websites that are dealing with a lot of third-party content, these options could potentially help speed up render times dramatically.

    Unless they don't. According to Tim Kadlec, for example, "AMP documents tend to be faster than their counterparts, but they don’t necessarily mean a page is performant. AMP is not what makes the biggest difference from a performance perspective."

    A benefit for the website owner is obvious: discoverability of these formats on their respective platforms and increased visibility in search engines. You could build progressive web AMPstoo, by reusing AMPs as a data source for your PWA. Downside? Obviously, a presence in a walled garden places developers in a position to produce and maintain a separate version of their content, and in case of Instant Articles and Apple News without actual URLs (thanks Addy, Jeremy!).

  2. Choose your CDN wisely.
    Depending on how much dynamic data you have, you might be able to "outsource" some part of the content to a static site generatorpushing it to a CDN and serving a static version from it, thus avoiding database requests. You could even choose a static-hosting platform based on a CDN, enriching your pages with interactive components as enhancements (JAMStack). In fact, some of those generators (like Gatsby on top of React) are actually website compilers with many automated optimizations provided out of the box. As compilers add optimizations over time, the compiled output gets smaller and faster over time.

    Notice that CDNs can serve (and offload) dynamic content as well. So, restricting your CDN to static assets is not necessary. Double-check whether your CDN performs compression and conversion (e.g. image optimization in terms of formats, compression and resizing at the edge), support for servers workersedge-side includes, which assemble static and dynamic parts of pages at the CDN’s edge (i.e. the server closest to the user), and other tasks. If you want to be on the edge, check if your CDN supports HTTP over QUIC (HTTP/3) as well.

    Note: based on research by Patrick Meenan and Andy Davies, HTTP/2 prioritization is effectively broken on many CDNsso be careful when choosing a CDN. Patrick has more details in his recent talk on HTTP/2 Prioritization (thanks, Barry!).

Assets Optimizations

  1. Use Brotli for plain text compression.
    In 2015, Google introduced Brotlia new open-source lossless data format, which is now supported in all modern browsers. In practice, Brotli appears to be much more effective than Gzip and Deflate. It might be (very) slow to compress, depending on the settings, but slower compression will ultimately lead to higher compression rates. Still, it decompresses fast. You can also estimate Brotli compression savings for your site.

    Browsers will accept it only if the user is visiting a website over HTTPS. Brotli is widely supported, and many CDNs support it (AkamaiAWSKeyCDNFastlyCloudlareCDN77) and you can enable Brotli even on CDNs that don’t support it yet (with a service worker).

    The catch is that compressing all assets with Brotli is quite expensive, so a number of servers can’t use it just because of the cost overhead it produces. In fact, at the highest level of compression, Brotli is so slow that any potential gains in file size could be nullified by the amount of time it takes for the server to begin sending the response as it waits to dynamically compress the asset. With static compression, however, higher compression settings are preferred.

    If you can bypass the cost of dynamically compressing static assets, it’s worth the effort. Brotli can be used for any plaintext payload — HTML, CSS, SVG, JavaScript, and so on.

    The strategy? Pre-compress static assets with Brotli+Gzip at the highest level and compress (dynamic) HTML on the fly with Brotli at level 3–5. Make sure that the server handles content negotiation for Brotli or gzip properly.

A graph showing adoption of compression algorithms
Both on desktop and on mobile, only 15% of all requests are compressed with Brotli. Around 65% are compressed with gzip. The rest isn’t compressed at all. (Image source: Web Almanac: Compression) (Large preview)
  1. Use responsive images and WebP.
    As far as possible, use responsive images with srcsetsizes and the element. While you’re at it, you could also make use of the WebP format (supported in all modern browsers except Safari and iOS Safari) by serving WebP images with the element and a JPEG fallback (see Andreas Bovens' code snippet) or by using content negotiation (using Accept headers). Ire Aderinokun has a very detailed tutorial on converting images to WebPtoo.

    Sketch natively supports WebP, and WebP images can be exported from Photoshop using a WebP plugin for Photoshop. Other options are availabletoo. If you’re using WordPress or Joomla, there are extensions to help you easily implement support for WebP, such as Optimus and Cache Enabler for WordPress and Joomla’s own supported extension (via Cody Arsenault).

    It’s important to note that while WebP image file sizes compared to equivalent Guetzli and Zopflithe format doesn’t support progressive rendering like JPEGwhich is why users might see an actual image faster with a good ol' JPEG although WebP images might get faster through the network. With JPEG, we can serve a "decent" user experience with the half or even quarter of the data and load the rest later, rather than have a half-empty image as it is in the case of WebP. Your decision will depend on what you are after: with WebP, you’ll reduce the payload, and with JPEG you’ll improve perceived performance.

    On Smashing Magazine, we use the postfix -opt for image names — for example, brotli-compression-opt.png; whenever an image contains that postfix, everybody on the team knows that the image has already been optimized. And — shameless plug! — Jeremy Wagner even published a Smashing book on WebP.

Responsive Image Breakpoints Generator
The Responsive Image Breakpoints Generator automates images and markup generation.
  1. Are images properly optimized?
    When you’re working on a landing page on which it’s critical that a particular image loads blazingly fast, make sure that JPEGs are progressive and compressed with mozJPEG (which improves the start rendering time by manipulating scan levels) or take a look at GuetzliGoogle’s new open-source encoder focusing on perceptual performance, and utilizing learnings from Zopfli and WebP. The only downside: slow processing times (a minute of CPU per megapixel). For PNG, we can use Pingoand for SVG, we can use SVGO or SVGOMG. And if you need to quickly preview and copy or download all the SVG assets from a website, svg-grabber can do that for you, too.

    Every single image optimization article would state it, but keeping vector assets clean and tight is always worth reminding. Make sure to clean up unused assets, remove unnecessary metadata and reduces the number of path points in artwork (and thus SVG code). (Thanks, Jeremy!)

    There are more advanced options though. You could:

    • Use Squoosh to compress, resize and manipulate images at the optimal compression levels (lossy or lossless),
    • Use the Responsive Image Breakpoints Generator or a service such as Cloudinary or Imgix to automate image optimization. Also, in many cases, using srcset and sizes alone will reap significant benefits.
    • To check the efficiency of your responsive markup, you can use imaging-heapa command line tool that measure the efficiency across viewport sizes and device pixel ratios.
    • Lazy load images and iframes with hybrid lazy-loadingutilizing native lazy-loading and lazyloada library that detects any visibility changes triggered through user interaction (with IntersectionObserver which we’ll explore later).
    • For offscreen images, we can display a placeholder first, and when the image is within the viewport, using IntersectionObserver, trigger a network call for the image to be downloaded in background. We can then defer render until decode with img.decode() or download the image if the Image Decode API isn't available. When rendering the image, we can use fade-in animations, for example. Katie Hempenius and Addy Osmani share more insights in their talk Speed at Scale: Web Performance Tips and Tricks from the Trenches.
    • You can add automatic image compression to your Pull Requestsso no image can hit production uncompressed. The action uses mozjpeg and libvips that work with PNGs and JPGs.
    • Watch out for images that are loaded by default, but might never be displayed — e.g. in carousels, accordions and image galleries.
    • Consider Swapping Images with the Sizes Attribute by specifying different image display dimensions depending on media queries, e.g. to manipulate sizes to swap sources in a magnifier component.
    • Review image download inconsistencies to prevent unexpected downloads for foreground and background images.
    • Sometimes optimizing images alone won't do the trick. To improve the time needed to start the rendering of a critical imagelazy-load less important images and defer any scripts to load after critical images have already rendered.
    • To optimize storage interally, you could use Dropbox’s new Lepton format for losslessly compressing JPEGs by an average of 22%.
    • Watch out for the aspect-ratio property in CSS and intrinsicsize attribute which will allow us to set aspect ratios and dimensions for images, so browser can reserve a pre-defined layout slot early to avoid layout jumps during the page load.
    • If you feel adventurous, you could chop and rearrange HTTP/2 streams using Edge workersbasically a real-time filter living on the CDN, to send images faster through the network. Edge workers use JavaScript streams that use chunks which you can control (basically they are JavaScript that runs on the CDN edge that can modify the streaming responses), so you can control the delivery of images. With service worker it’s too late as you can’t control what’s on the wire, but it does work with Edge workers. So you can use them on top of static JPEGs saved progressively for a particular landing page.
    A sample output by imaging-heapa command line tool that measure the efficiency across viewport sizes and device pixel ratios. (Image source) (Large preview)

    The future of responsive images might change dramatically with the adoption of client hints. Client hints are HTTP request header fields, e.g. DPRViewport-WidthWidthSave-DataAccept (to specify image format preferences) and others. They are supposed to inform the server about the specifics of user’s browser, screen, connection etc. As a result, the server can decide how to fill in the layout with appropriately sized images, and serve only these images in desired formats. With client hints, we move the resource selection from HTML markup and into the request-response negotiation between the client and server.

    As Ilya Grigorik notedclient hints complete the picture — they aren’t an alternative to responsive images. "The element provides the necessary art-direction control in the HTML markup. Client hints provide annotations on resulting image requests that enable resource selection automation. Service Worker provides full request and response management capabilities on the client." A service worker could, for example, append new client hints headers values to the request, rewrite the URL and point the image request to a CDN, adapt response based on connectivity and user preferences, etc. It holds true not only for image assets but for pretty much all other requests as well.

    For clients that support client hints, one could measure 42% byte savings on images and 1MB+ fewer bytes for 70th+ percentile. On Smashing Magazine, we could measure 19-32% improvementtoo. Unfortunately, client hints still have to gain some browser support. Still under consideration in Firefox. However, if you supply both the normal responsive images markup and the tag for Client Hints, then the browser will evaluate the responsive images markup and request the appropriate image source using the Client Hints HTTP headers.

    Not good enough? Well, you can also improve perceived performance for images with the multiple background images technique. Keep in mind that playing with contrast and blurring out unnecessary details (or removing colors) can reduce file size as well. Ah, you need to enlarge a small photo without losing quality? Consider using Letsenhance.io.

    These optimizations so far cover just the basics. Addy Osmani has published a very detailed guide on Essential Image Optimization that goes very deep into details of image compression and color management. For example, you could blur out unnecessary parts of the image (by applying a Gaussian blur filter to them) to reduce the file size, and eventually you might even start removing colors or turn the picture into black and white to reduce the size even further. For background images, exporting photos from Photoshop with 0 to 10% quality can be absolutely acceptable as well. Ah, and don’t use JPEG-XR on the web — "the processing of decoding JPEG-XRs software-side on the CPU nullifies and even outweighs the potentially positive impact of byte size savings, especially in the context of SPAs".

Addy Osmani recommends to replace animated GIFs with looping inline videos. The file size difference is noticeable (80% savings). (Large preview)
  1. Are videos properly optimized?
    We covered images so far, but we’ve avoided a conversation about good ol' GIFs. Frankly, instead of loading heavy animated GIFs which impact both rendering performance and bandwidth, it’s a good idea to switch either to animated WebP (with GIF being a fallback) or replace them with looping HTML5 videos altogether. Yes, unlike with images, browsers do not preload content, but HTML5 videos tend to be lighter and smaller than GIFs. Not an option? Well, at least we can add lossy compression to GIFs with Lossy GIFgifsicle or giflossy.

    Tests show that inline videos within img tags display 20× faster and decode 7× faster than the GIF equivalent, in addition to being a fraction in file size.

    In the land of good news, video formats have been advancing massively over the years. For a long time, we had hoped that WebM would become the format to rule them all, and WebP (which is basically one still image inside of the WebM video container) will become a replacement for dated image formats. But despite WebP and WebM gaining support these days, the breakthrough didn’t happen.

    In 2018, the Alliance of Open Media has released a new promising video format called AV1. AV1 has compression similar to the H.265 codec (the evolution of H.264) but unlike the latter, AV1 is free. The H.265 license pricing pushed browser vendors to adopt a comparably performant AV1 instead: AV1 (just like H.265) compresses twice as good as WebM.

    AV1 Logo 2018
    AV1 has good chances of becoming the ultimate standard for video on the web. (Image credit: Wikimedia.org) (Large preview)

    In fact, Apple currently uses HEIF format and HEVC (H.265), and all the photos and videos on the latest iOS are saved in these formats, not JPEG. While HEIF and HEVC (H.265) aren’t properly exposed to the web (yet?), AV1 is — and it’s gaining browser support. So adding the AV1 source in your tag is reasonable, as all browser vendors seem to be on board.

    For now, the most widely used and supported encoding is H.264, served by MP4 files, so before serving the file, make sure that your MP4s are processed with a multipass-encodingblurred with the frei0r iirblur effect (if applicable) and moov atom metadata is moved to the head of the file, while your server accepts byte serving. Boris Schapira provides exact instructions for FFmpeg to optimize videos to the maximum. Of course, providing WebM format as an alternative would help, too.

    Have to start rendering videos quickly (e.g. background videos)? A common technique to use is to quickly show the first frame or display a short looping segment that could be interpreted as a part of the video, and then embed video aftewards (thanks, Guy Podjarny!).

    Video playback performance is a story on its ownand if you’d like to dive into it in details, take a look at Doug Sillar’s series on The Current State of Video and Video Delivery Best Practices that include details on video delivery metrics, video preloading, compression and streaming.

Zach Leatherman’s Comprehensive Guide to Font-Loading Strategies
Zach Leatherman’s Comprehensive Guide to Font-Loading Strategies provides a dozen options for better web font delivery.
  1. Are web fonts optimized?
    The first question that’s worth asking if you can get away with using UI system fonts in the first place — just make sure to double check that they appear correctly on various platforms. If it’s not the case, chances are high that the web fonts you are serving include glyphs and extra features and weights that aren’t being used. You can ask your type foundry to subset web fonts or if you are using open-source fonts, subset them on your own with Glyphhanger or Fontsquirrel. You can even automate your entire workflow with Peter Müller’s subfonta command line tool that statically analyses your page in order to generate the most optimal web font subsets, and then inject them into your page.

    WOFF2 support is great, and you can use WOFF as fallback for browsers that don’t support it — or perhaps legacy browsers could be served well enough with system fonts instead. There are many, many, many options for web font loading, and you can choose one of the strategies from Zach Leatherman’s "Comprehensive Guide to Font-Loading Strategies," (code snippets also available as Web font loading recipes).

    Probably the better options to consider today are Critical FOFT with preload and "The Compromise" method. Both of them use a two-stage render for delivering web fonts in steps — first a small supersubset required to render the page fast and accurately with the web font, and then load the rest of the family async. The difference is that "The Compromise" technique loads polyfill asynchronously only if font load events are not supported, so you don’t need to load the polyfill by default. Need a quick win? Zach Leatherman has a quick 23-min tutorial and case study to get your fonts in order.

    In general, it might be a good idea to use the preload resource hint to preload fonts, but in your markup include the hints after the link to critical CSS and JavaScript. With preloadthere is a puzzle of prioritiesso consider injecting rel="preload" elements into the DOM just before the external blocking scripts. According to Andy Davies, "resources injected using a script are hidden from the browser until the script executes, and we can use this behaviour to delay when the browser discovers the preload hint." Otherwise, font loading will cost you in the first render time.

    It’s a good idea to be selective and choose files that matter most, e.g. the ones that are critical for rendering or that would help you avoiding visible and disruptive text reflows. In general, Zach advises to preload one or two fonts of each family — it also makes sense to delay some font loading if they are less critical.

    It has become quite common to use local() value (which refers to a lo­cal font by name) when defining a font-family in the @font-face rule:

    /* Warning! Probably not a good idea! */
    @font-face {
      font-family: Open Sans;
      src: local('Open Sans Regular'),
           local('OpenSans-Regular'),
           url('opensans.woff2') format ('woff2'),
           url('opensans.woff') format('woff');
    }

    The idea is reasonable: some popular open-source fonts such as Open Sans are coming pre-installed with some drivers or apps, so if the font is avail­able lo­cally, the browser does­n’t need to down­load the web font and can dis­play the lo­cal font im­me­di­ately. As Bram Stein noted"though a lo­cal font matches the name of a web font, it most likely isn't the same font. Many web fonts dif­fer from their "desk­top" ver­sion. The text might be ren­dered dif­fer­ently, some char­ac­ters may fall back to other fonts, Open­Type fea­tures can be miss­ing en­tirely, or the line height may be dif­fer­ent."

    Also, as typefaces evolve over time, the locally installed version might be very different from the web font, with characters looking very different. So, according to Bram, it's better to never mix lo­cally in­stalled fonts and web fonts in @font-face rules.

    Nobody likes waiting for the content to be displayed. With the font-display CSS descriptorwe can control the font loading behavior and enable content to be readable immediately (font-display: optional) or almost immediately (font-display: swap). However, if you want to avoid text reflowswe still need to use the Font Loading API, specifically to group repaintsor when you are using third party hosts. Unless you can use Google Fonts with Cloudflare Workersof course.

    Talking about Google Fonts: although the support for font-display was added recentlyconsider using google-webfonts-helpera hassle-free way to self-host Google Fonts. Always self-host your fonts for maximum control if you can.

    In general, if you use font-display: optionalit might not be a good idea to also use preload as it will trigger that web font request early (causing network congestion if you have other critical path resources that need to be fetched). Use preconnect for faster cross-origin font requests, but be cautious with preload as preloading fonts from a different origin wlll incur network contention. All of these techniques are covered in Zach’s Web font loading recipes.

    It might be a good idea to opt out of web fonts (or at least second stage render) if the user has enabled Reduce Motion in accessibility preferences or has opted in for Data Saver Mode (see Save-Data header). Or when the user happens to have slow connectivity (via Network Information API). Eventually, we might also be able to use prefers-reduced-data CSS media query to not define font declarations if the user has opted into data-saving mode. The media query would basically expose if the Save-Data request header from the Client Hint HTTP extension is on/off to allow for usage with CSS. Not quite there yet though.

    To measure the web font loading performance, consider the All Text Visible metric (the moment when all fonts have loaded and all content is displayed in web fonts), Time to Real Italics as well as Web Font Reflow Count after first render. Obviously, the lower both metrics are, the better the performance is. It’s important to notice that variable fonts might require a significant performance consideration. They give designers a much broader design space for typographic choices, but it comes at the cost of a single serial request opposed to a number of individual file requests. That single request might be slow, blocking the rendering of the content on a page. So subsetting and splitting the font into character sets will still matter. On the good side though, with a variable font in place, we’ll get exactly one reflow by default, so no JavaScript will be required to group repaints.

    Now, what would make a bulletproof web font loading strategy then? Subset fonts and prepare them for the 2-stage-render, declare them with a font-display descriptor, use Font Loading API to group repaints and store fonts in a persistent service worker’s cache. On the first visit, inject the preloading of scripts just before the blocking external scripts. You could fall back to Bram Stein’s Font Face Observer if necessary. And if you’re interested in measuring the performance of font loading, Andreas Marschke explores performance tracking with Font API and UserTiming API.

    Finally, don’t forget to include unicode-range to break down a large font into smaller language-specific fonts, and use Monica Dinculescu’s font-style-matcher to minimize a jarring shift in layout, due to sizing discrepancies between the fallback and the web fonts.

    Does the future look bright? With progressive font enrichmenteventually we might be able to "download only the required part of the font on any given page, and for subsequent requests for that font to dynamically ‘patch’ the original download with additional sets of glyphs as required on successive page views", as Jason Pamental explains it. Incremental Transfer Demo is already available, and it’s work in progress.

Build Optimizations

  1. Set your priorities straight.
    It’s a good idea to know what you are dealing with first. Run an inventory of all of your assets (JavaScript, images, fonts, third-party scripts and "expensive" modules on the page, such as carousels, complex infographics and multimedia content), and break them down in groups.

    Set up a spreadsheet. Define the basic core experience for legacy browsers (i.e. fully accessible core content), the enhanced experience for capable browsers (i.e. the enriched, full experience) and the extras (assets that aren’t absolutely required and can be lazy-loaded, such as web fonts, unnecessary styles, carousel scripts, video players, social media buttons, large images). A while back, we published an article on "Improving Smashing Magazine’s Performance," which describes this approach in detail.

    When optimizing for performance we need to reflect our priorities. Load the core experience immediately, then enhancementsand then the extras.

  2. Use native JavaScript modules in production.
    Remember the good ol' cutting-the-mustard technique to send the core experience to legacy browsers and an enhanced experience to modern browsers? An updated variant of the technique could use ES2015+




    Source link