Zum Hauptinhalt springen




Eine reale Fallstudie zur Optimierung der Leistung von React SPA.

El rendimiento del sitio Netz 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 Rekrutierungstechnologien ein Refactoring-Projekt durchlaufen, um eine seiner Webanwendungen zu verbessern, AirSHIFT, para un mejor rendimiento de entrada del Nutzername. Así es como lo hicieron.

Langsame Reaktion, geringere Produktivität

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 Klient enriquecidas que incluyen varias tablas de cuadrícula de horarios de turnos organizados por día, semana, mes y más.

airshift_visual-3001408

Als das Engineering-Team von Recruit Technologies der AirSHIFT-App neue Funktionen hinzufügte, erhielten sie mehr Feedback zu langsamer Leistung. Yosuke Furukawa, technischer Leiter von AirSHIFT, sagte:

In einer Studie zur Nutzerforschung waren wir überrascht, als einer der Ladenbesitzer sagte, er würde seinen Platz verlassen, um nach einem Klick auf einen Knopf Kaffee zu kochen, nur um die Zeit totzuschlagen, die darauf wartet, dass der Schichttisch geladen wird.

Nach Durchführung der Untersuchungen stellte das Engineering-Team fest, dass viele ihrer Benutzer vor 10 Jahren versuchten, massive Schichttabellen auf Computer mit niedrigen Spezifikationen wie einen 1-GHz-Celeron-M-Laptop zu laden.

Endloser Spinner auf Low-End-Geräten.

La aplicación AirSHIFT estaba bloqueando el hilo principal con Skripte 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.

Haupt-Thread-Breakdown-7210124

Beim Laden der Schichttabelle wurden etwa 80% der Ladezeit durch Ausführen von Skripten verbraucht.

Después de perfilar su rendimiento en Chrome DevTools con la limitación de CPU y red habilitada, quedó claro que se necesitaba optimieren 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. Virtualisieren Sie große Tabellen

Das Anzeigen der Schichttabelle erforderte mehrere kostspielige Schritte: Erstellen des virtuellen DOM und Rendern auf dem Bildschirm im Verhältnis zur Anzahl der Mitarbeiter und Zeitfenster. Wenn ein Restaurant beispielsweise 50 arbeitende Mitglieder hat und Sie den monatlichen Schichtplan überprüfen möchten, ist dies eine Tabelle mit 50 (Mitgliedern) multipliziert mit 30 (Tagen), was dazu führt, dass 1.500 Zellkomponenten gerendert werden. Dies ist eine sehr teure Operation, insbesondere für Geräte mit niedrigen Spezifikationen. In Wirklichkeit war es schlimmer. Bei der Untersuchung stellten sie fest, dass es Geschäfte gab, in denen 200 Mitarbeiter verwaltet wurden und die rund 6.000 Zellkomponenten in einer einzigen monatlichen Tabelle benötigten.

Um die Kosten für diesen Vorgang zu senken, hat AirSHIFT die Schichttabelle virtualisiert. Die Anwendung stellt jetzt nur die Komponenten im Ansichtsfenster und die Komponenten außerhalb des Bildschirms bereit.

virtualize_before-9209523

Vorher: Rendern aller Zellen der Verschiebungstabelle.

virtualize_after-8560709

Nachher: Rendern Sie einfach die Zellen im Ansichtsfenster.

In diesem Fall wird AirSHIFT verwendet virtualisiert reagieren da es Anforderungen gab, komplexe zweidimensionale Rastertabellen zu ermöglichen. Sie suchen auch nach Möglichkeiten, die Implementierung so zu konvertieren, dass sie in Zukunft das Lichtreaktionsfenster verwendet.

Ergebnisse

Die Tabellenvirtualisierung allein reduzierte die Skriptzeit um 6 Sekunden (in einer Macbook Pro 4x langsamer + schnellen 3G-beschleunigten Umgebung). Dies war die effektivste Leistungsverbesserung im Refactoring-Projekt.

virtualize_results_before-4813935

Vorher: ca. 10 Sekunden Skript nach Benutzereingabe.

virtualize_results_after-6955380

Nachher: 4 Sekunden Skript nach Benutzereingabe.

2. Auditoría con API User Timing

Das AirSHIFT-Team hat dann die Skripte überarbeitet, die mit Benutzereingaben ausgeführt werden. das Flammentabelle
von Chrome DevTools
Mit dieser Option können Sie analysieren, was im Hauptthread tatsächlich passiert. Das AirSHIFT-Team fand es jedoch einfacher, die Anwendungsaktivität basierend auf dem React-Lebenszyklus zu analysieren.

React 16 bietet seine Leistungsverfolgung über die
Benutzerzeit-API, die Sie von der sehen können
Times Abschnitt
von Chrome DevTools. AirSHIFT verwendete den Abschnitt "Zeiten", um unnötige Logik zu finden, die in React Lifecycle-Ereignissen ausgeführt wird.

user_timing-6925370

Reagieren Sie auf Benutzerzeitereignisse.

Ergebnisse

Das AirSHIFT-Team stellte fest, dass a
Reaktionsbaum-Versöhnung
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 Programmierung.

3. Lazy Loading-Komponenten und kostspielige Logikübertragung an Web-Worker

AirSHIFT verfügt über eine integrierte Chat-Anwendung. Viele Ladenbesitzer kommunizieren mit ihren Mitarbeitern per Chat, während sie sich die Schichttabelle ansehen. Dies bedeutet, dass ein Benutzer möglicherweise eine Nachricht eingibt, während die Tabelle geladen wird. Wenn der Hauptthread mit Skripten beschäftigt ist, die die Tabelle rendern, kann die Benutzereingabe ärgerlich sein.

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

Das AirSHIFT-Team hat auch einen Teil der teuren Geschäftslogik in träge geladenen Komponenten auf migriert
Web-Worker. Dies löste das Problem mit Benutzereingaben, indem der Haupt-Thread freigegeben wurde, sodass er sich darauf konzentrieren konnte, auf Benutzereingaben zu reagieren.

In der Regel sind Entwickler bei der Verwendung von Workern mit Komplexität konfrontiert, diesmal jedoch Comlink tat das schwere Heben für sie. Nachfolgend finden Sie den Pseudocode, wie AirSHIFT bei einer der teuersten Operationen gearbeitet hat, die sie jemals hatten: Berechnung der Gesamtarbeitskosten.

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


importieren Reagieren, { faul, Suspense } desde 'react'


const Hello = faul(() => importieren('./Cost'))

const Loading = () => (
<div>Some fallback content to show während Wird geladen</div>
)


Export Standard Funktion App({ userInfo }) {
Rückkehr (
<div>
<Suspense fallback={<Loading />}>
<Cost />
</Suspense>
</div>
)
}

Verwenden Sie in der Kostenkomponente comlink, um die Berechnungslogik auszuführen


importieren Reagieren desde 'react';
importieren { proxy } desde 'comlink';


const WorkerlizedCostCalc = proxy(new Arbeiter('./WorkerlizedCostCalc.js'));
Export Standard Funktion Cost({ userInfo }) {
const instance = erwarten new WorkerlizedCostCalc();
const cost = erwarten instance.calc(userInfo);
Rückkehr <p>{cost}</p>;
}

Implementieren Sie die Berechnungslogik, die auf dem Worker ausgeführt wird, und legen Sie sie mit comlink offen


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


expose({
calc(userInfo) {
Rückkehr someExpensiveCalculation(userInfo);
}
}, selbst);

Ergebnisse

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).

Arbeiter-7404546

AirSHIFT prüft derzeit, ob andere Komponenten verzögert geladen und mehr Logik an Web-Worker ausgelagert werden können, um den Ruck weiter zu reduzieren.

4. Erstellen Sie ein Leistungsbudget

Bei all diesen Optimierungen war es wichtig sicherzustellen, dass die Anwendung im Laufe der Zeit weiterhin funktioniert. AirSHIFT verwendet jetzt Paket Größe 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 Veranstaltung de Redux
  • Leistungsdaten werden in gesammelt Elasticsearch
  • Die Leistung des 10., 25., 50. und 75. Perzentils jedes Ereignisses wird mit angezeigt Kibana

AirSHIFT überwacht jetzt das Ladeereignis der Schichttabelle, um sicherzustellen, dass es für Benutzer mit 75. Perzentil in 3 Sekunden abgeschlossen ist. Dies ist derzeit ein nicht angewendetes Budget, sie erwägen jedoch automatische Benachrichtigungen über Elasticsearch, wenn sie Ihr Budget überschreiten.

kibana-9058952

Das Kibana-Dashboard zeigt die täglichen Leistungsdaten nach Perzentilen an.

Ergebnisse

In der obigen Grafik sehen Sie, dass AirSHIFT jetzt hauptsächlich das 3-Sekunden-Budget für Benutzer des 75. Perzentils erreicht und die Verschiebungstabelle für Benutzer des 25. Perzentils in einer Sekunde lädt. Durch die Erfassung von RUM-Leistungsdaten von verschiedenen Bedingungen und Geräten kann AirSHIFT dies jetzt tun Überprüfen Sie, ob eine neue Feature-Version die Leistung der Anwendung wirklich beeinträchtigt oder nicht.

5. Performance-Hackathons

Obwohl all diese Bemühungen zur Leistungsoptimierung wichtig und wirkungsvoll waren, ist es nicht immer einfach, Engineering- und Geschäftsteams dazu zu bringen, nicht funktionale Entwicklungen zu priorisieren. Ein Teil der Herausforderung besteht darin, dass einige dieser Leistungsoptimierungen nicht geplant werden können. Sie erfordern Experimente und eine Versuch-und-Irrtum-Denkweise.

AirSHIFT führt jetzt interne eintägige Leistungs-Hackathons durch, damit sich Ingenieure nur auf leistungsbezogene Arbeiten konzentrieren können. Bei diesen Hackathons beseitigen sie alle Einschränkungen und respektieren die Kreativität der Ingenieure. Daher ist jede Implementierung, die zur Geschwindigkeit beiträgt, eine Überlegung wert. Um den Hackathon zu beschleunigen, teilt AirSHIFT die Gruppe in kleine Teams auf und jedes Team konkurriert darum, wer den größten bekommen kann Leuchtturm Verbesserung der Leistungsbewertung. Teams werden sehr wettbewerbsfähig! 🔥

Hackathon-2457180

Ergebnisse

Der Hackathon-Ansatz funktioniert gut für sie.

  • Leistungsengpässe können leicht erkannt werden, indem mehrere Ansätze während des Hackathons getestet und jeweils mit Lighthouse gemessen werden.
  • Nach dem Hackathon ist es ziemlich einfach, das Team davon zu überzeugen, welche Optimierung es für die Produktionsfreigabe priorisieren sollte.
  • Es ist auch ein wirksamer Weg, um die Bedeutung der Geschwindigkeit zu verteidigen. Alle Teilnehmer können den Zusammenhang zwischen der Art und Weise, wie Sie codieren, und der Umsetzung in die Leistung verstehen.

Ein netter Nebeneffekt war, dass sich viele andere Entwicklungsteams innerhalb von Recruit für diesen praktischen Ansatz interessierten und das AirSHIFT-Team jetzt Hackathons mit mehreren Geschwindigkeiten innerhalb des Unternehmens ermöglicht.

Zusammenfassung

Es war definitiv nicht die einfachste Reise für AirSHIFT, an diesen Optimierungen zu arbeiten, aber es hat sich auf jeden Fall gelohnt. Jetzt lädt AirSHIFT die Schichttabelle in 1,5 Sekunden auf den Median, was eine 6-fache Verbesserung gegenüber der Leistung vor dem Projekt darstellt.


Nachdem die Leistungsoptimierungen veröffentlicht wurden, sagte ein Benutzer:

Vielen Dank, dass Sie das Laden des Schichttisches beschleunigt haben. Die Organisation der Schichtarbeit ist jetzt viel effizienter.