iteratec Blog

Will Qwik replace all existing JavaScript frameworks?

Written by Robert Maier-Silldorff | Jan 9, 2024, 11:00:00 PM

Meta-frameworks such as Next.js, SvelteKit and Astro are currently the talk of the town. These handle certain tasks relating to hydration, which speeds up start-up time and allows users to interact with websites more quickly. Qwik takes this approach a step further and introduces ‘Resumable’. But what exactly is ‘Resumable’, and what other concepts underpin this framework?

Contents

  1. History of web development
  2. What is Qwik?
  3. Comparison of Qwik and Angular
  4. Signals in Angular
  5. Incremental Hydration
  6. Conclusion

With Single Page Applications (SPAs), rendering takes place on the client side. This means that the HTML page, including the JavaScript used, must be downloaded before a user can interact with a web page. Experts refer to this point in time as the First Meaningful Paint (FMP). To improve the FMP, other frameworks utilise hydration. Hydration is the process whereby event listeners are added to the DOM, the component treeis constructed and the application state is restored. Qwik simplifies this process by ensuring that all the necessary information is already present in the HTML, meaning no client-side adjustments are required. This concept is known as ‘resumable ’.

Figure 1: Hydration vs. Resumable [1]

 

History of web development

To understand Qwik and the concepts behind this framework, we need to look at the history of web development. This can be broken down as follows:

  • 1st generation: Server-side rendering, such as PHP and jQuery
  • 2nd generation: SPA frameworks such as Angular or React
  • 2.5th generation: Hydration using meta-frameworks such as Next.js, SvelteKit or Astro
  • 3rd generation: HTML-first approach, where JavaScript is only loaded when required for the current user action; Qwik

 

What is Qwik?

Qwik is a JavaScript framework that loads only the absolute minimum amount of JavaScript. Just 1 kilobyte of JavaScript is required for a web page to be interactive or for the First Meaningful Paint (FMP) to be achieved. JavaScript itself is only loaded when it is required for a user action. This concept is known as ‘progressive loading ’. In the example below, the required JavaScript is only loaded when the ‘increment’ button is clicked, and the counter is subsequently incremented. The $ symbol tells Qwik that JavaScript should only be loaded on demand.

Figure 2: Example of a Qwik component

 

As a result, the bundle size does not subsequently increase linearly with the size of the project, but remains constant, as shown in the diagram below.

Figure 3: Bundle size versus project size [2]

 

Reactivity in Qwik

The conceptsof ‘resumable’and‘progressive’are Qwik’s greatest assets. But how does Qwik manage to build the component tree quickly and effectively, and how does reactivity work in Qwik? Qwik uses signals, which enable finely granular reactivity, ensuring that only those parts of the component tree that have changed are re-rendered. Unlike other frameworks, this does not involve using a compiler or registering listeners; instead, proxies are utilised. These proxies generate serialisable subscriptions, which are used for re-rendering. In the example below, `useStore` is used to create such a proxy. As soon as the user clicks the button, the relevant JavaScript is downloaded and the affected part of the component is re-rendered. It is important to note that only those parts of the code affected by the action are reloaded. Suppose there were a second counter in the component shown; this would not be reloaded.

Figure 4: Counter component in Qwik

Syntax in Qwik

As can already be seen from the examples given, the syntax in Qwik is very closely modelled on React. The component templates are also similar to React’s, and JSX is used. However, only the syntax is the same; the underlying concepts differ from those in React. Qwik does not use a virtual DOM.

Qwik differs from other JSX frameworks as follows [3]:

  • Components are always created using ` component$ `
  • `useSignal ` can be used for a reactive state
  • Event handlers are declared with the $ suffix
  • For `<input> `, ` onInput$ ` is used instead of ` onChange `
  • HTML attributes are preferred; use ` class ` rather than ` className`

But how does binding work using signals, and how can a condition for rendering be specified? As shown in Figure 5, binding is carried out via `bind:value`, and a condition can be specified using `isVisible.value`.

Figure 5: Qwik component with binding and condition

Migration to Qwik

The concepts described are intuitive and improve not only start-up time but also runtime performance. But how can existing applications be migrated to Qwik? Qwik React was introduced for React applications. This enables React to be used within Qwik. The `qwikify$` function can be used for this purpose. Figure 6 shows how this works.

Figure 6: Using a React component in Qwik

For all other SPA applications, such as Angular, the entire application would need to be migrated to Qwik.

 

Comparison of Qwik and Angular

As the person behind Qwik, Miško Hevery, is regarded as the father of Angular, it is interesting to compare Qwik with Angular. Generally speaking, every Angular application is represented as a component tree, as shown in Figure 7. Furthermore, reactivity works differently to how it does in Qwik. In Angular, when a user action occurs, the component tree is traversed from the bottom up, and all components affected by the action are marked as ‘dirty’.

 

Figure 7: Change Detection in Angular
(On-Push Change Detection Strategy)

In Figure 7, these are all the parent components of the component highlighted in yellow. Next, Change Detection (CD) triggers a tick, causing all components marked as ‘dirty’ to be re-rendered.

 

Signals in Angular

Signals were first introduced in Angular 16 – a new reactivity concept that has been progressively expanded in subsequent versions. This includes adjustments to the control flow as well as the integration of inputs, outputs and other elements into this new paradigm. As a result of this development, the use of zone.js is no longer strictly necessary (see https://medium.com/stackademic/angular-without-zone-js-embracing-zoneless-change-detection-82f2f1ceeb77)

A key advantage of Signals lies in their fine-grained reactivity: only those parts of the template where something has actually changed are re-rendered (see Figure 8). This leads to improved performance and a more efficient update strategy. However, this requires the use of the new control flow in combination with Signals.

Figure 8: Control Flow

Furthermore, Angular now offers a flexible, declarative way to dynamically reload parts of the template. What was previously only possible via routing with separate components can now be controlled directly within the template using defer blocks. Developers can specify when a particular block should be loaded – for example, when it enters the viewport, on a click, or after a defined timer has elapsed. Further details can be found in the official documentation at: https://angular.dev/guide/templates/defer.

To gain a practical insight into the new concepts and understand how modern Angular applications can be developed today, we recommend taking a look at the following reference repository:
👉 https://github.com/rmaiersilldorff/performance-example.git

The repository demonstrates:

New control flow
Use of the new @if, @for and @switch directives – clearer and more efficient than traditional ng-templates.

Signal-based inputs and outputs
Instead of the traditional @Input() and @Output(), the application uses input<T>() and output<T>().
Here, T is the data type (e.g. string, number, boolean, Todo, etc.).
This ensures reactive, type-safe and high-performance component communication.

Signals in the template
Direct use of signals in the view – for precise and efficient rendering.

Zoneless architecture
Implemented entirely without zone.js – lower overhead, clearer change detection.

In addition, Angular relies on hydration and is continually expanding this approach. Angular 16 introduced non-destructive hydration. This makes it possible to further enrich the HTML page rendered by the server, add event listeners and build up the application state, thereby avoiding the need for the client to reload the entire HTML page. Research is currently being carried out into progressive and partial hydration. These are intended to enable the loading of many small bundles, as opposed to a single large bundle.

Figure 9: Destructive vs. Non-Destructive Hydration

 

Incremental Hydration with *defer

With the latest versions of Angular – particularly since version 17 – there have also been fundamental changes in the area of hydration. Angular now supports incremental hydration.

What is incremental hydration?

Incremental hydration is an advanced form of hydration in which certain parts of an application initially remain ‘dehydrated’ and are only gradually ‘hydrated’ as and when required – for example, when scrolling into the viewport, through user interactions or on a timer (see https://angular.dev/guide/incremental-hydration).

Advantages of incremental hydration

  • Faster load times (FCP, LCP)
  • Less initial JavaScript overhead
  • Improved user experience on mobile devices
  • Resources are only used when actually needed

Conclusion

Qwik takes a new, innovative approach and is rightly regarded as a new generation of JavaScript frameworks. Not only is the absolute minimum amount of JavaScript loaded, but only 1 kByte of JavaScript is required to interact with a web page. Thanks to the simple integration of React components, a number of component libraries can already be used in Qwik. However, other SPA framework components are not supported. It remains to be seen whether Qwik will replace all existing frameworks and herald a new generation of JavaScript frameworks. The concepts behind Qwik would suggest so. Applications that are used predominantly on mobile devices, in particular, would benefit greatly from this.

At the same time, there have been significant developments in Angular’s recent versions, particularly in the areas of hydration and reactivity. Angular has borrowed and further developed some concepts from other SPA frameworks in this area to remain competitive. As a result, Angular is currently holding its own very well against new frameworks such as Qwik and continues to offer a powerful and tried-and-tested framework for modern web applications.

 

Sources

[1] https://qwik.builder.io/docs/concepts/resumable/

[2] https://twitter.com/QwikDev/status/1521202882124521472

[3] https://qwik.builder.io/docs/components/rendering/#jsx

This article first appeared in Red Stack magazine: https://www.doag.org/de/home/news/red-stack-magazin-inkl-business-news-nr-1-2024-ist-online/

 

Do you have any questions or need assistance?

You can find out more about the possibilities offered by bespoke software and systems for your business on our website.

Feel free to get in touch with us.