Der Status quo
Nach jetzigem Stand blockiert React das Rendering weiterer Komponenten, wenn schon ein anderer Rendering-Prozess im Gange ist. Eine wunderbare Analogie, die auch die React-Doku anführt, ist Version Control. Wenn ihr zu mehreren – oder auch alleine – an einem Projekt arbeitet, nutzt ihr höchstwahrscheinlich Git oder ein anderes Version Control System. Ihr arbeitet in Branches. Wenn ein Feature soweit fertig ist, merged ihr in den Masterbranch und die anderen können pullen. Soweit, so State of the Art. Vor Version Control Systemen wie Git mussten Entwickler, wollten sie etwas an den Dateien innerhalb eines Projektes ändern, ihre Teammitglieder anweisen, solange die Finger von dem Projekt zu lassen, bis sie die Änderung implementiert hatten. Der gesamte Entwicklungsprozess war für den Änderungszeitraum geblockt.
Etwa so kann man sich den Rendering-Prozess heutiger UI-Libraries vorstellen. Sobald ein Update gerendert wird, also zum Beispiel neue DOM-Nodes erstellt und Code innerhalb von Komponenten ausgeführt wird, kann die Library – zum Beispiel React – diesen Prozess nicht stoppen.
Bereits begonnene Renderings können unterbrochen werden
Was die Concurrent-Mode-Features so revolutionär macht, ist, dass damit der Rendering-Vorgang unterbrechbar wird. Damit soll die User-Experience signifikant besser werden. Wenn der User zukünftig beim Nutzen einer React-App eine Eingabe macht, hält React den Browser in Zukunft nicht mehr so lange davon ab, den Input zu updaten, bis der vorher in Gang gesetzte Rendering-Prozess abgeschlossen ist, sondern kann das Update des Inputs quasi zwischenschalten und die aktualisierte Liste im Hintergrund weiterrendern. Dann aktualisiert React den DOM und der Nutzer sieht die Änderungen auf dem Bildschirm.
Konzeptuell könntet ihr euch das vorstellen, als würde React jedes Update auf einem eigenen Branch vorbereiten: Dabei könnt ihr ein weniger wichtiges Feature auch einfach mal liegen lassen und an etwas anderem weitermachen.
Mit dem Concurrent Mode wird die Notwendigkeit von Debouncing und Drosselung des UI reduziert. Ihr müsst Renderings nicht mehr künstlich aufhalten, um stockende Interfaces zu verhindern. Sie beginnen zwar sofort, können bei Bedarf aber jederzeit unterbrochen werden.
Build-in intentional Loading Sequences
Folgendes Szenario: Der User navigiert zwischen zwei Screens in einer App. Manchmal sind vielleicht nicht genug Code und Daten geladen, um dem User einen ausreichenden Ladestatus anzuzeigen. Zu einem leeren Bildschirm zu wechseln oder ewig einen Spinner angezeigt zu bekommen, nervt. Eine elegantere Lösung ist es, solange auf der Ausgangsansicht zu bleiben, bis ausreichend Daten und Code geladen sind, um auch den zweiten vollständig anzuzeigen. Das geht, ist aber gar nicht so einfach – zumindest bisher: Mit Concurrent Mode ist dieses Feature der Default. React bereitet den neuen Screen im Hintergrund – will man bei der Git-Metapher bleiben: auf einem neuen Branch – bereits vor, währenddessen bleibt der Ausgangs-Screen aber vollständig erhalten. Der Wechsel zum neuen Screen erfolgt erst, wenn eure App soweit ist.
Für CPU-gebundene Updates wie das Erstellen von DOM-Nodes oder die Ausführung von Code bedeutet der Concurrent Mode, dass ein dringenderes Update ein weniger wichtiges Rendering unterbrechen kann. Für IO-gebundene Updates, wie Code oder Daten von einem Netzwerk zu fetchen, bedeutet Concurrency, dass React im Speicher bereits mit dem Rendern beginnt, bevor alle Daten verfügbar sind. Dem Nutzer wird in der Zwischenzeit anstelle eines leeren Screens oder Spinners einfach der vorherige Screen angezeigt. An der Art, wie ihr mit React arbeitet, wird der Concurrent Mode nichts ändern. Komponenten, State und Props funktionieren genau wie vorher auch. Wenn ihr die Ansicht aktualisieren wollt, setzt ihr den State. React entscheidet nach einer Heuristik, wie „dringend“ ein Update ist, die könnt ihr aber nach Bedarf im Einzelfall mit ein paar wenigen Zeilen Code anpassen.
TLDR: Beim Concurrent Mode geht es um Prioritäten. Nach Status quo kann React ein einmal begonnenes Rendering nicht unterbrechen. Mit Concurrency Mode hat React ein Auge auf Dinge, die sonst gerade anstehen: Gibt es eine Sache mit einer höheren Priorität – zum Beispiel ein anderes Update oder andere Aufgaben, die der Browser ausführen muss – wird React diese in Zukunft vorziehen. Die Priorisierung orientiert sich an Erkenntnissen aus der Mensch-Computer-Interaktionsforschung: Interaktionen wie zum Beispiel Texteingaben müssen in relativ kurzer Zeit stattfinden, bei Klicks oder Seitenwechseln darf das Ganze etwas länger dauern, ohne dass wir als Nutzer das Gefühl haben, das dauere jetzt zu lange.
Achtung: Noch ist die Neuerung im sogenannten Experimental State! Die Doku rät dringend davon ab, das neue Feature jetzt schon in euren Projekten zu nutzen. Zum Ausprobieren verfügbar ist das Ganze ab sofort für Neugierige und Experimentierfreudige – ausdrücklich in einem Rahmen, in dem ihr nicht wirklich etwas kaputt machen könnt. Wer gerne experimentiert und jetzt schon testen will: Viel Spaß!
Zum Weiterlesen:
- React Hooks: Lohnt die Umstellung auf das Programmier-Konzept?
- Version 4 der React-Dev-Tools – das bringt das Update