Metaframeworks wie Next.js, SvelteKit oder Astro sind zurzeit in aller Munde. Diese übernehmen gewisse Aufgaben rund um Hydration, wodurch die Startup-Time beschleunigt und User schneller mit Webseiten interagieren können. Qwik treibt diesen Ansatz weiter und führt Resumable ein. Doch was versteht man unter Resumable und welche Konzepte stehen noch hinter diesem Framework?
Mit Single Page Applications (SPAs) erfolgt das Rendering clientseitig. Das heißt, dass die HTML-Seite einschließlich des verwendeten JavaScripts heruntergeladen werden muss, bevor mit einer Webseite interagiert werden kann. Fachleute nennen diesen Zeitpunkt den First Meaningful Paint (FMP). Um den FMP zu verbessern, kommt in anderen Frameworks Hydration zum Einsatz. Hydration ist der Prozess, in dem die Event Listeners zum DOM hinzugefügt werden, der Komponenten-Baum aufgebaut und der Application State wiederhergestellt wird. Qwik vereinfacht diesen Prozess, indem alle notwendigen Informationen bereits im HTML vorhanden sind, wodurch clientseitig keine Anpassungen notwendig sind. Dieses Konzept wird als Resumable bezeichnet.
Abbildung 1: Hydration vs. Resumable [1]
Historie der Webentwicklung
Um Qwik und die Konzepte hinter diesem Framework zu verstehen, müssen wir uns die Geschichte der Webentwicklung anschauen. Diese kann wie folgt gegliedert werden:
- 1. Generation: Rendering am Server wie z.B. PHP und JQuery
- 2. Generation: SPA Frameworks wie Angular oder React
- 2,5. Generation: Hydration mittels Metaframeworks wie z.B. Next.js, SvelteKit oder Astro
- 3. Generation: HTML-First Konzept, JavaScript wird nur geladen, wenn es für die aktuelle User-Aktion benötigt wird, Qwik
Was ist Qwik?
Qwik ist ein JavaScript Framework, welches nur das absolute Minimum an JavaScript lädt. Nur 1Kbyte an JavaScript wird benötigt, damit eine Webseite interaktiv ist bzw. der First Meaningful Paint (FMP) erreicht ist. JavaScript selbst wird nur geladen, wenn es für eine User-Aktion benötigt wird. Dieses Konzept wird als Progressive bezeichnet. Im folgenden Beispiel wird erst beim Klick auf den Button increment das benötigte JavaScript geladen und der Counter in weiterer Folge erhöht werden. Durch das $-Zeichen weiß Qwik, dass JavaScript erst on-demand geladen werden soll.
Abbildung 2: Beispiel einer Qwik-Komponente
Dadurch wächst die Bundle Size in weiterer Folge nicht linear zur Größe des Projekts, sondern bleibt, wie im unteren Diagramm ersichtlich, konstant.
Abbildung 3: Bundle Size zu Größe des Projekts [2]
Reactivity in Qwik
Die Konzepte „Resumable“ und „Progressive“ sind das große Asset von Qwik. Wie schafft es Qwik jedoch, dass der Komponenten-Baum schnell und effektiv aufgebaut wird bzw. wie schaut die Reactivity in Qwik aus? Qwik verwendet Signals, welche eine fein granulare Reactivity ermöglichen, sodass nur jene Komponenten-Bereiche neu gerendert werden, welche sich geändert haben. Anders als bei anderen Frameworks wird dafür kein Compiler benutzt oder werden Listeners registriert, sondern es kommen Proxies zum Einsatz. Diese Proxies erzeugen serialisierbare Subscriptions, welche für das erneute Rendering benutzt werden. Im unten angeführten Beispiel wird mit useStore solch ein Proxy erzeugt. Sobald der User den Button klickt, wird das entsprechende JavaScript heruntergeladen und der betroffene Teil der Komponente neu gerendert. Wichtig ist, dass nur jene Programmteile neu geladen werden, welche von der Aktion betroffen sind. Angenommen, es gäbe in der angeführten Komponente noch einen zweiten Counter, dann würde dieser nicht neu geladen werden.
Abbildung 4: Counter Komponente in Qwik
Syntax in Qwik
Wie bereits aus den angeführten Beispielen ersichtlich, ist die Syntax in Qwik sehr stark an React angelehnt. Auch die Component Templates gleichen React bzw. wird JSX verwendet. Es wird jedoch nur dieselbe Syntax benutzt. Die darunterliegenden Konzepte sind anders als in React. In Qwik kommt kein Virtual DOM zum Einsatz.
Qwik unterscheidet sich zu anderen JSX-Frameworks wie folgt [3]:
- Komponenten werden immer mit component$ erstellt
- useSignal kann für einen reactive State verwendet werden
- Event Handlers werden mit dem $-Suffix deklariert
- Bei <input> wird onInput$ statt onChange verwendet
- HTML-Attribute werden bevorzugt, class statt className
Doch wie erfolgt das Binding mittels Signals und wie kann eine Bedingung für das Rendering angegeben werden? Wie in Abbildung 5 ersichtlich, erfolgt das Binding über bind:value und mittels isVisible.value kann eine Bedingung angegeben werden.
Abbildung 5: Qwik Komponente mit Binding und Condition
Migration zu Qwik
Die beschriebenen Konzepte sind intuitiv und verbessern nicht nur die Start-Up Time sondern auch die Runtime-Performance. Doch wie können bestehende Applikationen zu Qwik migriert werden? Für React Applikationen wurde Qwik React eingeführt. Dieses ermöglicht es, React innerhalb von Qwik zu nutzen. Hierfür kann die Funktion qwikify$ benutzt werden. Abbildung 6 zeigt, wie dies funktioniert.
Abbildung 6: React Komponente in Qwik verwenden
Für alle anderen SPA-Applikationen, wie z.B. Angular, müsste die gesamte Applikation zu Qwik migriert werden.
Vergleich zu Angular
Da die Person, die hinter Qwik steckt, Miško Hevery, als Vater von Angular gilt, ist es interessant, Qwik mit Angular zu vergleichen. Generell wird jede Angular-Applikation, wie in Abbildung 7 ersichtlich, als Komponenten-Baum repräsentiert. Zusätzlich funktioniert die Reactivity anders als in Qwik. In Angular wird bei einer User-Aktion der Komponenten-Baum von unten nach oben durchforstet und werden all jene Komponenten auf dirty gesetzt, welche von der Aktion betroffen sind.
Abbildung 7: Change Detection in Angular |
In Abbildung 7 sind dies alle Parent Komponenten der gelb eingezeichneten Komponente. Als Nächstes führt die Change Detection (CD) einen tick aus, wodurch alle auf dirty gesetzten Komponenten neu gerendert werden. Anzumerken ist, dass Angular mit der Version 16 Signals eingeführt hat und für zukünftige Versionen Signal based Components versprochen wurden, welche eine fein granulare Reactivity ermöglichen. Das heißt, dass im Falle von Abbildung 7 nur der betroffene Template-Teil der gelb gekennzeichneten Komponente neu gerendert werden würde. |
Zusätzlich setzt Angular auf Hydration und baut diesen Ansatz immer weiter aus. Mit Angular 16 wurde non-destructive Hydration eingeführt. Dieses ermöglicht es, die vom Server gerenderte HTML-Seite weiter anzureichern, Event Listeneres hinzuzufügen und den Application State aufzubauen, wodurch nicht die gesamte HTML-Seite vom Client neu geladen werden muss. Aktuell wird an progressive und partial Hydration geforscht. Diese sollen es ermöglichen, viele kleine, im Gegensatz zu einem großen Bundle, zu laden.
Abbildung 8: Destructive vs. Non-Destructive Hydration
Fazit
Qwik verfolgt einen neuen innovativen Ansatz und wird zurecht als neue Generation von JavaScript Frameworks gehandhabt. Es wird nicht nur das absolute Minimum an JavaScript geladen, sondern es ist auch nur 1Kbyte an JavaScript notwendig, um mit einer Webseite zu interagieren. Durch die einfache Einbindung von React Komponenten können bereits einige Komponenten Libraries in Qwik verwendet werden. Andere SPA-Framework-Komponenten werden jedoch nicht unterstützt. Qwik ist in keinem Beta-Status mehr, sondern kann seit Mai dieses Jahres produktiv verwendet werden. Ob Qwik alle bisherigen Frameworks ersetzt und eine neue Generation an JavaScript Frameworks einläutet wird sich noch zeigen. Die Konzepte hinter Qwik würden dafürsprechen. Vor allem Applikationen, die zu einem großen Teil auf Mobile-Devices benutzt werden, würden sehr stark davon profitieren.
Quellen
[1] https://qwik.builder.io/docs/concepts/resumable/
[2] https://twitter.com/QwikDev/status/1521202882124521472
[3] https://qwik.builder.io/docs/components/rendering/#jsx
Dieser Beitrag erschien zuerst im Red Stack Magazin: https://www.doag.org/de/home/news/red-stack-magazin-inkl-business-news-nr-1-2024-ist-online/
Robert Maier-Silldorff ist als Senior Software Developer bei iteratec GmbH tätig, hält nicht nur firmeninterne Vorträge und Workshops, sondern ist auch immer wieder als Speaker beim Vienna Angular Meetup vertreten. Zusätzlich ist er auf medium.com als Autor mit Themen rund um JavaScript und Angular unterwegs (https://medium.com/@robert.maiersilldorff). Best Practices und Clean Code sind ihm ein sehr großes Anliegen. |
Haben Sie Fragen oder benötigen Sie Unterstützung?
Mehr zu den Möglichkeiten von individueller Software und Systemen für Ihr Unternehmen finden Sie auf unserer Webseite.
Sprechen Sie uns auch gerne an.