Qwik is a frontend framework for creating web applications that offers lightning fast page load times, regardless of the size and complexity of your site.
In this article, we’ll learn how to get started with Qwik and explore the building blocks of a Qwik application by creating a simple example app. We’ll also review the concept of hydration, learn why it slows down our apps, and see how Qwik avoids hydration, boosting our application’s performance. Let’s get started!
The concept of lazy loading was introduced to speed up the first render. With lazy loading, instead of sending your whole application to the browser at one time, you can divide your application into multiple smaller parts called chunks. When the application loads for the first time, you’ll only send and execute the required code on the client side, speeding up the first render.
In server-side rendering, your application’s first render is already done on the server side and sent to the browser as HTML, speeding up the time of the initial render significantly.
Most web apps aren’t a static webpage. Therefore, client-side frameworks must recreate the page after server-side rendering by attaching event listeners, creating a DOM tree, and restoring the application state to make it interactive. This process is called hydration. The downside of hydration is that even though the page is rendered on the user’s screen, it might not be interactive until hydration downloads and re-executes the code again.
As a framework without hydration, this is exactly the problem that Qwik tries to solve.
Getting started with Qwik
To get started, you’ll need to have Node.js ≥v16.8 installed.
Qwik comes with a CLI tool that helps you scaffold your application. First, generate your app using the following command:
The command above will prompt you to name the application; let’s choose
dice-roller. It’ll also prompt you to select the type of application; select Basic App (QwikCity). This will generate a directory called
dice-roller within a Qwik application.
Let’s navigate to the
dice-roller directory using the following command:
Now, let’s start the dev server to run our app:
To see how the app looks, open
Qwik app structure
If you open the project directory in your code editor, you’ll see the following folder structure:
There are a few key things to understand here:
- TypeScript: By default, Qwik applications support TypeScript, as indicated by
- Vite: During development, Qwik uses Vite
src: By default, the
srcdirectory is used for source code
publicdirectory is used for static assets
Example Qwik app: Dice roll app
For this app, we’re using QwikCity, which is a meta framework for Qwik, just like Next.js is to React. We’ll use QwikCity to provide a directory-based router and access to the tree of components. If you open
src/components/routes/index.tsx, you’ll see the default route
/ exporting a Qwik component with some content.
Replace the content of file with the following code, which simulates a six face dice roll:
If you save the file and open the browser at
https://localhost:5174, you’ll see the following app:
Ignore the header and footer, they’re part of default application. The code that you changed is outlined with red box. Let’s understand it in detail.
As the name suggests, the
component$method creates a component. The
component$method comes from the
builder.io/qwikpackage. Notice the
$symbol; it has a special meaning that we’ll discuss soon.
Again, like React, a component can have
props, which you can use to pass inputs to the component. A Qwik component uses
jsx. The JSX template is returned from a component that creates the UI.
The useStore is a Qwik Hook that allows you to create a state like React’s
useState. Whenever an app reads or write these values, Qwik is aware of it, re-rendering the UI accordingly.
The onClick$ is an attribute that allows you to bind a click event handler on an element. You can create event handlers for various types of events. Finally, the
randomValuemethod generates a random value between one and six.
In summary, in Qwik, you have components, JSX, Hooks, and events, like React. However, there is a significant difference compared to React, and that’s how Qwik avoids hydration.
The dollar sign
Qwik comes with an optimizer, which is responsible for extracting code for lazy loading. This optimizer goes through the app code, and when it encounters the dollar sign, it creates what is called a symbol. These symbols can then be easily lazy loaded.
In the component example above, you have two places where
$ exists; first at
component$, and second in
Qwik will generate symbols for the following:
- For component
$ sign is also a signal to the developer that the code has a special meaning.
After the code is rendered on the server-side, Qwik will generate HTML and send it to the browser. The markup will look like the following:
Looking at the
<button> element, you’ll notice that it has a weird attribute,
This attribute has a strange-looking value:
This strange value is called QRL, or a Qwik URL. This URL provides the following information:
- The name of the symbol to get from the chunk
Using this URL, Qwikloader will know what code to fetch and execute from the chunk generated by the optimizer. But what about the state? How does the newly fetched code know the current state of the application?
Qwik also saves the state of application in serialized form using a
<script> tag in the HTML. It looks something like the following:
Qwik uses the serialized state for the following reasons:
- To restart the execution on the client-side after it’s paused on the server
- To create subscriptions on the client-side to re-render only the component that changed
Once you finish your application, you can deploy it to any environment where Node.js is available. Qwik provides built-in to integrations that allow you to quickly deploy to hosting services like Netlify, Vercel, and more.
You can add any integration by running the following command:
At the time of writing, Qwik supports the following integrations:
For instance, if you want to deploy on Netlify, you can run the following command:
Then, you can run the following commands to deploy your application to Netlify:
In this article, we covered various rendering techniques, some of the key APIs of Qwik like component, hooks, events.
Then, we learned how Qwik makes applications resumable using Optimizer, Qwikloader, and QRL. This is just tip of the iceberg. To learn more, go to https://qwik.builder.io to learn more about QwikCity, Builder, Partytown and so on.