Performance-Fallstricke für React-Anwendungen und wie man sie findet

BlaBlaCar bietet einen internationalen Transportservice, der ein breites Publikum im Web und im mobilen Web erreicht. Das Publikum kann auf jedem Gerät und in jedem Netzwerk navigieren, vom klobigen 3G auf einem 3 Jahre alten billigen Smartphone bis zur schnellen Wi-Fi-Verbindung auf dem neuesten iPhone.

Heutzutage erwarten Benutzer, dass das Web schnell ist. Eine Studie von Soasta zeigt, dass eine schnelle Erfahrung Ihre Absprungrate senkt und zu längeren Sitzungen führt. Weitere Informationen finden Sie bei Google: 53% der Handybenutzer verlassen Websites, deren Ladezeit länger als 3 Sekunden beträgt.

Die Leistung Ihrer App ist ein bekannter Schlüsselfaktor für die Verbesserung der Benutzerbindung und der Rücklaufquote - was wahrscheinlich auch Ihr Unternehmen wünscht.

Leistungsprobleme zu erkennen, zu beheben und das Verhalten unserer neuen React-App zu überwachen, ist unsere Aufgabe bei BlaBlaCar als Frontend-Entwickler.

Schneller liefern

Erster aussagekräftiger Anstrich und erster Dialog sind zwei wichtige Konzepte, wenn es um Ladungsprobleme geht. Ersteres ist der Moment, in dem Ihr erster Inhalt Ihrem Benutzer angezeigt wird, und letzteres ist der Moment, in dem der Benutzer mit Ihrer Seite interagieren kann. Beide müssen so früh wie möglich kommen, um eine bessere Erfahrung zu machen.

Was meinst du mit

Behalten Sie den Überblick über den Code

Eine der naheliegendsten Möglichkeiten zur Verbesserung der Ladezeit besteht darin, das globale Gewicht Ihrer Seite zu verringern. Leichtere Assets werden natürlich schneller geladen, aber es ist nicht immer einfach zu wissen, welche Teile Ihres Skripts sich am stärksten auf das Gewicht auswirken.

Bei BlaBlaCar verwenden wir Webpack 3, um unsere Skripte zu bündeln, und es wird mit einer Vielzahl von Tools geliefert, mit denen Sie analysieren können, was in Ihren Bundles enthalten ist. Alles was Sie tun müssen, ist eine Statistikdatei zu generieren, wenn Sie Ihr Projekt mit diesem Befehl erstellen:

webpack --profile --json> stats.json

Sie können diese Datei mit verschiedenen Tools wie dem Webpack-Bundle-Analyzer verwenden und sehen, welche Skripte und Bibliotheken die schwersten sind. Ich empfehle dies häufig, insbesondere wenn Sie Ihrem Projekt externe Bibliotheken hinzufügen.

Weiß, was du mitbringst

Teilen Sie Ihre Anwendung in kleinere Teile auf

Wenn einige Teile Ihrer Anwendung nicht sofort verfügbar sein müssen, ziehen Sie in Betracht, die erforderlichen Skripts in einem separaten Bundle abzulegen und sie später bei Bedarf zu laden. Webpack bietet eine einfache Möglichkeit, dies durch die Funktion dynamic import () zu tun.

Klasse MyComponent erweitert React.Component {
  state = {
    Balken: null
  }

  componentWillMount () {
    importieren ('Komponenten / Balken'). dann ((Balken) => {
      this.setState ({Bar})
    })
  }

  render () {
    const {Bar} = this.state
    if (! Bar) {
      return 
Wird geladen ...     } else {       return     }   } }

Bei BlaBlaCar verwenden wir React Loadable, um auf einfache Weise kleinere Bundles für die verschiedenen Teile unserer App für eine Seite zu erstellen. Dies hilft sehr, die Größe des Hauptpakets zu reduzieren und nur das zu laden, was beim ersten Rendern erforderlich ist. Es bietet auch eine nette API, um Ladezustand und Fehler zu behandeln.

Rufen Sie Ihre Skripte bei Bedarf auf magische Weise ab

Übernehmen Sie die Verantwortung für das serverseitige Rendering

Bei in JavaScript integrierten Webanwendungen wird Ihrem Benutzer bis zum vollständigen Laden und Ausführen Ihres Skripts nichts außer einer leeren Seite angezeigt. Dies verlangsamt Ihre erste aussagekräftige Farbe und wirkt sich auch negativ auf die Suchmaschinenoptimierung aus, da Ihre Seite nichts enthält, bevor JavaScript ausgeführt wird.

Isomorphic React-Apps lösen dieses Problem, indem auf Server und Client derselbe Code ausgeführt wird. Beim ersten Rendern ruft der Server Informationen ab, rendert Ihren React-Baum und gibt ihn in der Antwort als HTML-Code zurück. Anschließend wird der Client erneut mit dem synchronisiert, was vom Server bereitgestellt wurde, und die nächsten Benutzeraktionen werden selbst ausgeführt.

SSR ist nicht für alle Apps obligatorisch und kann vollständig ignoriert werden, wenn Sie kein SEO benötigen oder wenn Sie keinen Zugriff auf wirklich gute Server haben - oder Node JS-Server überhaupt. Außerdem wird Ihre App dadurch erheblich komplexer. Wenn Sie also keinen klaren Bedarf haben, ist das Überspringen in der Regel die beste Lösung. Weitere Informationen zur Verwendung von SSR finden Sie unter Soll ich das serverseitige Rendern von React verwenden ?. von JavaScript Stuff.

Es gibt auch andere minimalistische SEO-Lösungen wie Prerender, die je nach Zweck und Struktur Ihrer App ausreichen können.

Lassen Sie Ihren Server einen Teil des Auftrags erledigen

Sorgen Sie für eine reibungslose und schnelle Benutzererfahrung

Benutzer erwarten, dass Ihre Benutzeroberfläche auf jede Interaktion im Bruchteil einer Sekunde reagiert und die Navigation reibungslos verläuft. Wenn der erste Ladevorgang eine große Rolle spielt, ist dies auch die Leistung, die Ihre App weltweit wahrnimmt.

Gezackte Animationen, schlechte Bildlaufgeschwindigkeit oder Wartezeiten beim Klicken auf eine Schaltfläche können die Benutzer frustrieren und zu einer negativen Wahrnehmung Ihrer Anwendung führen.

Verwenden von Chrome DevTools zum Erkennen langsamer Komponenten

Wenn Sie React 16 und Google Chrome verwenden, hat sich Ihr Leben vereinfacht, da React jetzt beim Ausführen von Updates oder Rendern kleine Ereignisse an Chrome DevTools sendet. Auf diese Weise können Sie Methoden identifizieren, die viel CPU beanspruchen.

Öffnen Sie im Entwicklungsmodus die Registerkarte Leistung in Ihrer Konsole und starten Sie ein neues Profil.

Beispiel: Unser Datepicker braucht viel Zeit, um zu montieren. Dies muss korrigiert werden!

Versuchen Sie bei der Analyse Ihres Profils, sich auf Teile zu konzentrieren, die durch einen roten Balken gekennzeichnet sind, da dies eine Markierung für schwere CPU-Aufgaben ist. Das User Timing-Akkordeon zeigt alle Protokolle an, die von React für die Methoden Ihrer Komponenten gesendet wurden. Dies ist äußerst nützlich, um festzustellen, welche Teile Ihrer App sehr lange zum Aktualisieren oder Rendern benötigen.

Weitere Informationen zur Verwendung Ihrer Entwicklertools finden Sie in der offiziellen Dokumentation zu Google Chrome Devtools.

Verwenden Sie alle handlichen Werkzeuge, die Ihnen zur Verfügung stehen

Beschleunigen Sie das Aktualisieren und Rendern mit Funktionskomponenten

Funktionskomponenten sind zustandslos und implementieren nur eine Rendering-Methode. Sie werden als reine Funktionen und nicht als Klassen deklariert.

Diese Komponententypen lassen sich viel schneller aktualisieren und rendern, da sie keine Lebenszyklusmethode implementieren und keinen Status oder diesen Kontext aufweisen. Wenn einige Ihrer Komponenten keine benötigen, sollten Sie sie als funktionale Komponenten deklarieren.

const MyComponent = (Requisiten) => 
{props.foo}

Wählen Sie aus, wann Ihr Reaktionsbaum aktualisiert werden soll

Ein wesentliches Leistungsproblem für React-Apps sind unerwünschte Baumaktualisierungen. Ein Requisitenwechsel am oberen Rand des Baums aktualisiert alle untergeordneten Komponenten - und die untergeordneten Komponenten ihrer Kinder usw. -, was abhängig von der Größe und Komplexität Ihres React-Baums eine lange Ausführungszeit in Anspruch nehmen kann.

Sie können die Aktualisierung des gesamten Baums unterbrechen, indem Sie bei Bedarf die Lebenszyklusmethoden shouldComponentUpdate implementieren. Beachten Sie, dass dies verhindert, dass alle Nachkommen Ihrer Komponente aktualisiert werden, nicht nur deren direkte untergeordnete Elemente.

Eine andere Möglichkeit, dies zu verhindern, besteht darin, Komponenten mithilfe von React.PureComponent zu implementieren: Reine Komponenten ähneln regulären React.Component, außer dass sie ihre eigene shouldComponentUpdate-Methode implementieren, die einen flachen Vergleich von Zuständen und Requisiten vornimmt, bevor die Komponente aktualisiert wird. Dies bedeutet, dass eine reine Komponente erst dann aktualisiert wird, wenn sich ihre direkten Requisiten oder ihr Status geändert haben, was zu Leistungsverbesserungen führen kann, wenn sie auf sehr komplexe Komponenten angewendet wird.

Stellen Sie sicher, dass es nur geändert wird, wenn Sie es möchten

Suchen Sie nach gezackten Animationen und Scrollen

FPS-Verluste (Frames pro Sekunde) während Animationen und Scrollen können in den meisten Fällen unerwünschten Skriptausführungen zugeschrieben werden. Mit den Chrome Dev Tools und den React Dev Tools können Sie leicht feststellen, welche Komponenten aktualisiert werden.

In jedem Fall sollten Sie beim Animieren von Komponenten - oder beim Scrollen - vermeiden, den lokalen Status Ihrer Komponente oder den globalen Status Ihrer App wiederholt zu aktualisieren. Wenn Sie Informationen aktualisieren müssen, können Sie Ihre Updates entprellen oder in Ihrem lokalen Kontext statt in Ihrem Bundesstaat speichern, um ein unnötiges erneutes Rendern zu vermeiden.

Weitergehen

Das Überprüfen von Leistungsproblemen ist eine Aufgabe, die Sie regelmäßig ausführen müssen, während Sie eine neue Anwendung entwickeln. Wenn Sie wissen, wie Sie häufige Probleme vermeiden, können Sie eine bessere Qualität erzielen.

Ich empfehle immer einen kurzen Überblick über das Verhalten und die Geschwindigkeit Ihrer App, wenn Sie neue Funktionen entwickeln oder Kernupdates durchführen, da eine einfache Änderung unermessliche Auswirkungen haben kann. Versuchen Sie, einige dieser Aufgaben zu automatisieren: Die Bündelgröße kann einfach mit einem benutzerdefinierten Skript als Hook überprüft werden. Es gibt auch Überwachungstools wie Speedcurve, die Sie in Ihr CI und den gesamten Release-Prozess integrieren und vor der Auslieferung schnell Regressionen erkennen können.

Es ist immer besser, wenn es automatisiert ist

Während dieser Zeit habe ich mich hauptsächlich auf die Optimierung und Leistung von JavaScript konzentriert, aber es gibt viele andere Quellen für Leistungsprobleme in einer React-App. Ich würde gerne auf einige von ihnen näher eingehen, aber für diesen Artikel wäre ein ganz neuer Artikel erforderlich, und ich habe keine Zeit mehr!

Also bleibt gespannt auf unsere nächsten magischen Geschichten!