Qwik – the First HTML Framework as Fast as a Lightning

If you’ve read my last article about Bun, you know that I like to try programming novelties. If any of them interest me, I usually share my experience on this blog as well. This time, however, I deliberately took my time. Qwik came out in its stable version 1.0 on May 1, 2023 and since then, I’ve been testing, researching, comparing and trying to understand it properly. And while I’m still waiting for further improvements, I think I can bring this new HTML framework closer to you. Let’s do it.

Why does the creator of Angular use React?

The subtitle is intentionally a bit sensational, but it doesn’t mislead. The co-founder of Qwik is none other than the father of Angular, Slovak Miško Hevery. I, as an angularist, like it, however, I’m less impressed that Qwik itself uses the syntax and methods of React. 

However, the truth is that it has good reasons for doing so. React is basically minimalist, and if something is to be ultrafast, it must adhere to minimalist principles (the backend language GoLang is also an example). The bottom line is that if you know React, you know Qwik.

What is revolutionary about Qwik?

Basically, everything we know about frontend frameworks. The main goal of Qwik is to be fast. I mean really fast – it ranges somewhere on the level of pure HTML without JavaScript, without performing complex component rendering and meaningless loading of everything that’ll be used later. And it’s successful at that.

Just go to the main page of Qwik, where you’ll find demonstrations of sites where the framework is already implemented. Average ratings of their speed are 97% according to Google metrics.

How is it possible that Qwik is so fast?

Qwik combines some of the basic principles we already know from various other frameworks and some of its own revolutionary ideas put into practice.

  1. SSR – Server Side Rendering: The initial load of the page and the execution of the basic states are performed on the server side where the page is hosted. Only HTML will then return to the client.
  2. The framework itself isn’t transmitted to clients: only Qwik Loader, which has less than 1-2 kb, is transmitted.
  3. Qwik is compatible with Bun, Deno, Netlify and Node.js and works with Vite and esbuild in the background

These principles are well known and, if well covered, can help any framework. But what is Qwik really the best at? Let’s compare it.

How a regular website works

A regular modern site downloads basic HTML and a bunch of JavaScript on the first load. Then it lazy-loads a lot of JavaScript and then creates various component structures, listeners, etc. using a frontend framework. This whole process is also called hydration. In complex applications, it sometimes takes up to seconds to see something and be able to interact. 

How Qwik works

Qwik, on the other hand, doesn’t know hydration in the true sense of the word. HTML is first loaded on the server where the page is hosted. Subsequently, it creates a session for the given client/browser, performs basic states and finally sends only minimalistic HTML to the said client. 

Hydration in a normal application and in Qwik

But we wouldn’t do much with pure HTML. We need to run events, interact with actions, store statuses and solve renderings. How does Qwik do it? Like this:

  1. All variables, component states or temporary values are recorded as an attribute in HTML on the elements.
  2. Events and actions are also recorded, in the form of text in an attribute.
  3. Qwik serializes everything using JSON.stringify – it solves errors such as cyclic references, serialization of built-in objects (date, maps), DOM references, promise as well as functions.
  4. Only one global listener is used.
  5. Thanks to querySelectorAll, all events are globally captured and then compared and evaluated on the basis of selectors.
  6. Qwik uses built-in state management – for reactivity, it uses a proxy, which is very similar to signals. The difference is only that the input is always an object and not a primitive type. Everyone who knows the signals, knows that no change detection à la Angular is necessary.
  7. Each component that is visible renders only HTML. The other components, the code itself and the actions are delayed as long as possible.
This is what HTML looks like when everything is recorded as an HTML text attribute.

In short – everything is lazy-loaded

In Qwik, therefore, everything that’s possible to lazy-load, is lazy-loaded. Each component is loaded only when it’s really necessary to render it. The same applies to actions – when initializing the signal on the SSR, text HTML button is returned, but it isn’t executed. The action occurs only with a successful pressing, which is captured in the global listener. Subsequently, a part of the onClick$ event is downloaded and executed, and the value is rendered and serialized into HTML.

How does Qwik do it? Thanks to division. A component can be written in one file and Qwik will make sure that each of its methods, actions, HTML, styles and everything else are divided and compiled into separate files and chunks. So if your app has 10,000 files, Qwik will split them so that they can easily become hundreds of thousands of files. 

And when Qwik, at the moment when the user presses the button, finds out that it doesn’t have the method yet, it simply quickly downloads the file from the server (which usually requires only a few bytes/kilobytes) and then executes it. 

So a HTML code for the button looks like this:

Qwik marks the text attribute of the global listener above the button and when pressed, it defines what to download and which method to perform.

And to make it even easier, Qwik determines, in addition to the division of components, their life cycle. It divides it into three states:

  1. Task: Performs a task before rendering or after a status change – executable on both SSR and client.
  2. Render: Renders the component after Task and before VisibleTask.
  3. VisibleTask: Performs the task when the component is rendered and visible at the same time – executable only on the client.

Based on them, it can then quickly determine where individual tasks will be performed. 

What is the future of Qwik?

So what exactly is Qwik? It’s React, Svelte and Angular with SSR in one 🙂 But it’s nothing new. When I look at what Bun comes with, or what Angular is currently adding in versions 16 and 17, I know that in the IT field everyone learns from and gets inspired by everyone. And that’s how it should be.

And what do I think about Qwik after more than 5 months of testing? Well, it’s crazy fast, but also crazy simple, which I don’t like so much. But I can imagine that it can be a great inspiration for other, more mature frameworks. SSR with initialized status, only one global listener and as much lazy-loading as possible are ideas really worth addressing.

Sources:

https://dev.to/builderio/a-first-look-at-qwik-the-html-first-framework-af
https://www.builder.io/blog/qwik-v1

Cover Image:

https://www.builder.io/blog/why-progressive-hydration-is-harder-than-you-think