Passer au contenu principal




Une étude de cas réelle sur l'optimisation des performances de React SPA.

El rendimiento del sitio la toile no se trata solo del tiempo de carga. Es fundamental proporcionar una experiencia rápida y receptiva a los usuarios, especialmente para las aplicaciones de escritorio de productividad que la gente usa todos los días. El equipo de ingenieros de technologies de recrutement est passé par un projet de refactoring pour améliorer une de vos applications web, AirSHIFT, para un mejor rendimiento de entrada del Nom d'utilisateur. Así es como lo hicieron.

Réponse lente, productivité réduite

AirSHIFT es una aplicación web de escritorio que ayuda a los propietarios de tiendas, como restaurantes y cafés, a gestionar el trabajo por turnos de los miembros de su personal. Construida con React, la aplicación de una sola página proporciona funciones de client enriquecidas que incluyen varias tablas de cuadrícula de horarios de turnos organizados por día, semana, mes y más.

airshift_visual-3001408

Au fur et à mesure que l'équipe d'ingénieurs de Recruit Technologies ajoutait de nouvelles fonctionnalités à l'application AirSHIFT, elle commençait à recevoir davantage de commentaires sur les performances lentes. Le directeur technique d'AirSHIFT, Yosuke Furukawa, a déclaré :

Dans une étude de recherche d'utilisateurs, nous avons été surpris lorsque l'un des propriétaires de magasin a déclaré qu'il quitterait son siège pour faire du café après avoir cliqué sur un bouton, juste pour perdre du temps à attendre que la table des équipes se charge.

Après avoir mené des recherches, l'équipe d'ingénieurs s'est rendu compte que nombre de leurs utilisateurs essayaient de charger des tables tournantes massives sur des ordinateurs à faible spécification, comme un ordinateur portable Celeron M à 1 GHz d'il y a 10 ans.

Spinner sans fin sur les appareils bas de gamme.

La aplicación AirSHIFT estaba bloqueando el hilo principal con scripts costosos, pero el equipo de ingeniería no se dio cuenta de lo costosos que eran los scripts porque se estaban desarrollando y probando en computadoras de especificaciones ricas con conexiones Wi-Fi rápidas.

fil principal-ventilation-7210124

Lors du chargement de la table de décalage, environ 80% du temps de chargement ont été consommés par l'exécution de scripts.

Después de perfilar su rendimiento en Chrome DevTools con la limitación de CPU y red habilitada, quedó claro que se necesitaba optimiser el rendimiento. AirSHIFT formó un grupo de trabajo para abordar este problema. Aquí hay 5 cosas en las que se centraron para hacer que su aplicación responda mejor a la entrada del usuario.

1. Virtualisez les grandes tables

L'affichage du tableau des équipes a nécessité plusieurs étapes coûteuses : construire le DOM virtuel et le restituer à l'écran au prorata du nombre d'employés et de plages horaires. Par exemple, si un restaurant compte 50 membres actifs et souhaite vérifier son horaire de travail mensuel, il s'agirait d'un tableau de 50 (membres) multiplié par 30 (jours), ce qui donnerait 1 500 composants de cellules à afficher. Il s'agit d'une opération très coûteuse, en particulier pour les appareils à faible spécification. En réalité, les choses étaient pires. À partir de l'enquête, ils ont découvert qu'il y avait des magasins gérant 200 membres du personnel, ce qui nécessitait environ 6 000 composants de cellules dans un seul tableau mensuel.

Pour réduire le coût de cette opération, AirSHIFT a virtualisé la table des équipes. L'application ne monte désormais que les composants dans la fenêtre d'affichage et démonte les composants hors écran.

virtualize_before-9209523

Avant : rendu de toutes les cellules de la table des décalages.

virtualize_after-8560709

Après : n'affiche que les cellules dans la fenêtre d'affichage.

Dans ce cas, AirSHIFT a utilisé réagir virtualisé car il y avait des exigences autour de l'activation de tableaux de grille bidimensionnels complexes. Ils explorent également des moyens de convertir la mise en œuvre pour utiliser la fenêtre de réaction à la lumière à l'avenir.

Résultats

La virtualisation des tables à elle seule a réduit le temps de script de 6 secondes (dans un environnement accéléré Macbook Pro + Fast 3G 4x plus lent). Il s'agit de l'amélioration des performances la plus marquante du projet de refactoring.

virtualize_results_before-4813935

Avant : environ 10 secondes de script après la saisie de l'utilisateur.

virtualize_results_after-6955380

Après : 4 secondes de script après la saisie de l'utilisateur.

2. Auditoría con API User Timing

Ensuite, l'équipe AirSHIFT a refactorisé les scripts qui s'exécutent sur l'entrée de l'utilisateur. Les tableau des flammes
de Chrome DevTools
vous permet d'analyser ce qui se passe réellement sur le thread principal. Mais l'équipe AirSHIFT a trouvé plus facile d'analyser l'activité des applications en fonction du cycle de vie de React.

React 16 fournit son suivi des performances via le
API de temps utilisateur, que vous pouvez voir depuis le
tranche horaire
depuis Chrome DevTools. AirSHIFT a utilisé la section Times pour trouver une logique inutile qui s'exécute sur les événements du cycle de vie React.

user_timing-6925370

Réagissez aux événements de temps de l'utilisateur.

Résultats

L'équipe AirSHIFT a découvert qu'un
Réconciliation de l'arbre de réaction
estaba sucediendo justo antes de cada ruta de navegación. Esto significaba que React estaba actualizando la tabla de turnos innecesariamente antes de las navegaciones. Una actualización innecesaria del estado de Redux estaba causando este problema. Arreglarlo ahorró alrededor de 750 ms de tiempo de scripting. AirSHIFT también realizó otras microoptimizaciones que eventualmente llevaron a una reducción total de 1 segundo en el tiempo de programmation.

3. Chargement paresseux des composants et transfert de la logique coûteuse aux travailleurs Web

AirSHIFT a une application de chat intégrée. De nombreux propriétaires de magasins communiquent avec les membres de leur personnel via le chat tout en consultant le tableau des équipes, ce qui signifie qu'un utilisateur peut taper un message pendant le chargement du tableau. Si le thread principal est occupé par des scripts qui restituent la table, l'entrée de l'utilisateur peut être gênante.

Para mejorar esta experiencia, AirSHIFT ahora usa React.lazy y Suspense para mostrar marcadores de posición para el Contenu de la tabla mientras carga lentamente los componentes reales.

L'équipe AirSHIFT a également migré une partie de la logique métier coûteuse à l'intérieur des composants chargés paresseusement vers
travailleurs du Web. Cela a résolu le problème de jank d'entrée utilisateur en libérant le thread principal afin qu'il puisse se concentrer sur la réponse à l'entrée utilisateur.

Normalement, les développeurs sont confrontés à la complexité lorsqu'ils utilisent des travailleurs, mais cette fois Comlink fait le gros du travail pour eux. Vous trouverez ci-dessous un pseudocode expliquant comment AirSHIFT a travaillé sur l'une des opérations les plus coûteuses qu'ils aient jamais eues : le calcul des coûts de main-d'œuvre totaux.

Au Appli.js, use React.lazy y Suspense para mostrar contenido de respaldo mientras se carga


importer Réagir, { fainéant, Suspense } desde 'react'


const Hello = fainéant(() => importer('./Cost'))

const Loading = () => (
<div>Some fallback content to show tandis que Chargement en cours</div>
)


exportation défaut une fonction Appli({ userInfo }) {
revenir (
<div>
<Suspense fallback={<Loading />}>
<Cost />
</Suspense>
</div>
)
}

Dans le composant Coût, utilisez comlink pour exécuter la logique de calcul


importer Réagir desde 'react';
importer { proxy } desde 'comlink';


const WorkerlizedCostCalc = proxy(new Ouvrier('./WorkerlizedCostCalc.js'));
exportation défaut une fonction Cost({ userInfo }) {
const instance = attendre new WorkerlizedCostCalc();
const cost = attendre instance.calc(userInfo);
revenir <p>{cost}</p>;
}

Implémenter une logique de calcul qui s'exécute sur le worker et l'exposer avec comlink


importer { expose } desde 'comlink'
importer { someExpensiveCalculation } desde './CostCalc.js'


expose({
calc(userInfo) {
revenir someExpensiveCalculation(userInfo);
}
}, soi);

Résultats

A pesar de la cantidad limitada de lógica que trabajaron como prueba, AirSHIFT cambió alrededor de 100 ms de su JavaScript del hilo principal al hilo de trabajo (simulado con aceleración de CPU 4x).

travailleur-7404546

AirSHIFT étudie actuellement s'ils peuvent charger paresseusement d'autres composants et décharger plus de logique sur les travailleurs Web afin de réduire davantage le jank.

4. Établissez un budget de performance

Une fois toutes ces optimisations mises en place, il était primordial de s'assurer que l'application continue de fonctionner dans le temps. AirSHIFT utilise maintenant Taille du paquet no exceder el tamaño de archivo JavaScript y CSS actual. Además de establecer estos presupuestos básicos, crearon un tablero para mostrar varios percentiles del tiempo de carga de la tabla de turnos para verificar si la aplicación funciona incluso en condiciones no ideales.

  • Ahora se mide el tiempo de finalización del script para cada un événement de Redux
  • Les données de performance sont collectées sur recherche élastique
  • La performance des 10e, 25e, 50e et 75e centiles de chaque événement est affichée avec Kibana

AirSHIFT surveille maintenant l'événement de chargement de la table de décalage pour s'assurer qu'il se termine dans les 3 secondes pour les utilisateurs du 75e centile. Il s'agit d'un budget non appliqué pour l'instant, mais ils envisagent des notifications push via Elasticsearch lorsqu'ils dépassent votre budget.

kibana-9058952

Le tableau de bord Kibana affichant les données de performances quotidiennes par centiles.

Résultats

Dans le graphique ci-dessus, vous pouvez voir qu'AirSHIFT atteint désormais principalement le budget de 3 secondes pour les utilisateurs du 75e centile et charge également la table des changements en une seconde pour les utilisateurs du 25e centile.En capturant les données de performances RUM à partir de diverses conditions et appareils, AirSHIFT peut désormais vérifiez si une nouvelle version de fonctionnalité affecte réellement les performances de l'application ou non.

5. Hackathons de performance

Bien que tous ces efforts d'optimisation des performances aient été importants et percutants, il n'est pas toujours facile d'amener les équipes commerciales et d'ingénierie à donner la priorité au développement non fonctionnel. Une partie du défi est que certaines de ces optimisations de performances ne peuvent pas être planifiées. Ils nécessitent de l'expérimentation et une mentalité d'essai et d'erreur.

AirSHIFT organise désormais des hackathons de performance internes d'une journée pour permettre aux ingénieurs de se concentrer uniquement sur le travail lié aux performances. Dans ces hackathons, ils suppriment toutes les limitations et respectent la créativité des ingénieurs, ce qui signifie que toute mise en œuvre qui contribue à la vitesse mérite d'être envisagée. Pour accélérer le hackathon, AirSHIFT divise le groupe en petites équipes et chaque équipe s'affronte pour voir qui peut en tirer le meilleur parti Phare amélioration du score de performance. Les équipes deviennent très compétitives ! 🔥

hackathon-2457180

Résultats

L'approche hackathon fonctionne bien pour eux.

  • Les goulots d'étranglement des performances peuvent être facilement repérés en essayant plusieurs approches pendant le hackathon et en mesurant chacune avec Lighthouse.
  • Après le hackathon, il est assez facile de convaincre l'équipe quelle optimisation privilégier pour la mise en production.
  • C'est aussi un moyen efficace de démontrer l'importance de la vitesse. Tous les participants peuvent comprendre la corrélation entre la façon dont vous codez et comment cela se traduit en performance.

Un effet secondaire intéressant a été que de nombreuses autres équipes d'ingénieurs au sein de Recruit se sont intéressées à cette approche pratique et l'équipe AirSHIFT organise désormais plusieurs hackathons de vitesse au sein de l'entreprise.

résumé

Ce n'était certainement pas le voyage le plus facile pour AirSHIFT de travailler sur ces optimisations, mais cela en valait certainement la peine. AirSHIFT charge maintenant la table de décalage en 1,5 seconde sur la médiane, ce qui représente une amélioration de 6 fois par rapport à ses performances d'avant-projet.


Après la publication des optimisations de performances, un utilisateur a déclaré :

Merci beaucoup d'avoir accéléré le chargement de la table de décalage. L'organisation du travail posté est maintenant beaucoup plus efficace.