Qwik is a bold reimagining of how reactive UIs work. The core premise is that the framework is built from the ground up to deliver HTML with minimal JavaScript.
Qwik uses a fine-grained model to isolate segments of the app that are hydrated on demand. By starting with first principles, Qwik enables otherwise unattainable performance and represents an alternative path for the evolution of front-end JavaScript.
quick state
Qwik is still in its early release, but it has come a long way since we first saw it. StackBlitz now has a full-featured example, a REPL playground, and a command line tool. Qwik has evolved to support a more developer-friendly, React-like syntax. Under the hood, we still have our own advanced reactive engine that defines reactive boundaries along with states, templates, and listeners.
Resumability
Qwik uses a clever combination of server-side and client-side rendering to create a duality that modern frameworks suffer from doing hydration work twice (once on the server and twice on the client). Avoid double taxation.
Qwik creator Misko Hevery writes:
The basic idea behind Qwik is that it is resumable. You can continue where the server left off. Very little code runs on the client.
Or, put another way, the server sets up the HTML page to be as fully functional as possible, allowing the client to do the least amount of work possible to continue or resume the user’s process. increase.
The general flow for reactive frameworks with SSR (Server Side Rendering) is to first generate a version of the app on the server and send it to the client to render the scaffolded app . At that point, the client-side app takes over. Basically I have to bootstrap the same app again to connect working clients.
This process is known as hydration. There are some clever ways to try to make hydration more efficient, but Qwik abandons them for a new process called resumability.
Resumability means that the client can pick up where the server left off without having to rebuild the app on the client.
interactive time
The metric Qwik is looking to enhance is Time to Interaction (TTI). This refers to the time between when a user sends a request to her web page and when the page becomes responsive to user interaction.
Load Time (TTL) tracks how long it takes for the client to finish receiving all the data it needs (so it’s a metric primarily determined by file size and network speed), TTI is the modern JS It takes into account the salient facts of the framework. Once the data is downloaded, the client must unpack and execute the necessary JavaScript code to make the page interactive.
A reactive engine needs a lot of work. The engine has to interpret/parse all the markup (JSX, etc.) with variables and expressions that change what is displayed based on changing state and how it behaves based on the code. there is.
At the other end of the spectrum is a simple HTML page. When the browser holds it, the page is ready to lock. This is why Google’s PageSpeed Insights gives pages like Reddit.com a score of 32 out of 100, while raw HTML gives a score of 100.
closures and listeners
Hevery describes the technical hurdle to speeding up TTI as “death by closure.” Simply put, the fact that every closure must maintain the universe of information that surrounds it means that the runtime his app is a layer of eagerly loaded code his cake.
The solution adopted by Qwik is to use global event listeners that interact with serialized listeners. In other words, instead of downloading listeners and wrapping them in closures, universal event listeners are used to coordinate listeners that are fulfilled on demand (regardless of whether the listener actually runs or not).
Qwik aims to provide reactivity along with HTML and make everything serializable. Based on information encapsulated in markup, all you need is a small executable to reveal reactivity at runtime.
Code splitting, tweaking
Another way to look at this is Qwik’s fine-tuned code splitting. Load interactive code on demand, when the user requests it. Bundlers can package these chunks into larger bits if it makes sense.
Qwik is built from the ground up with three separate functions for creating states, templates, and listeners. This allows the framework to load only what is needed for the task at hand. You can read more about this chunking aspect here.
The three boundaries of states, templates, and listeners were coded directly by the developer. You get pretty familiar DX thanks to a new optimizer tool that converts React-like syntax to these bounds in the background. The optimizer then does the work of turning the actual code into a series of tiny stubs that can restart the app in smaller chunks as needed.
In the optimizer, templates and listeners are denoted by dollar signs, and states are useStore
needle. This syntax is self-explanatory.
The final output of the Qwik code is different from the output of other frameworks, but when Qwik is used with the optimizer it is on par with other frameworks. Qwik also introduced QwikCity, a set of higher-order features such as routing that make building full-fledged apps easier.
Hands-on with Qwik
Now that you understand the concepts behind Qwik, let’s get a feel for coding with it. Listing 1 shows a simple component created in Qwik. (This example is from the Qwik FAQ.)
Listing 1. A simple Qwik component
import { component$ } from '@builder.io/qwik';
export const App = component$(() => {
console.log('render');
return <p onClick$={() => console.log('hello')}>Hello Qwik</p>;
});
Listing 1 shows a Qwik component defined as an anonymous function, component$
A function in the Qwik library.Whenever you see a dollar sign $
Qwik is telling the optimizer that it needs to do some work. The dollar sign portion of the app is where Qwik measures fine-grained lazy loading boundaries.
of onClick$
Listing 1 is another example of Qwik’s special syntax. Qwik uses some tricks to only load the JavaScript needed to support functionality when it’s actually needed.
The code in Listing 1 is split into several segments by the optimizer (see Listing 2).
Listing 2. Compiled Qwik components
// The app.js file itself
import { componentQrl, qrl } from "@builder.io/qwik";
const App = /*#__PURE__*/
componentQrl(qrl(()=>import('./app_component_akbu84a8zes.js'), "App_component_AkbU84a8zes"));
export { App };// app_component_akbu84a8zes.js
import { jsx as _jsx } from "@builder.io/qwik/jsx-runtime";
import { qrl } from "@builder.io/qwik";
export const App_component_AkbU84a8zes = ()=>{
console.log('render');
return /*#__PURE__*/ _jsx("p", {
onClick$: qrl(()=>import("./app_component_p_onclick_01pegc10cpw"), "App_component_p_onClick_01pEgC10cpw"),
children: "Hello Qwik"
});
};// app_component_p_onclick_01pegc10cpw.js
export const App_component_p_onClick_01pEgC10cpw = ()=>console.log('hello');
As you can see in Listing 2, instead of including the actual component functionality, Qwik uses componentQrl()
functions from the library.this function is qrl()
A function that imports a component file generated using an anonymous function. All this association between components is managed internally by the optimizer. Developers don’t have to think directly.
QRL stands for Qwik URL and is how Qwik refers to things that are lazy loaded. Basically, whenever the framework needs to defer loading something, it inserts a QRL wrapped by a QRL-specific consumer (like a component, state, or template function).
for example, componentQRL
The parent can display its layout quickly, but load the code found in the child component at the appropriate time.similarly onClick
handler: can be evaluated when a click occurs.
Qwik CLI
The command line tools are available from npm and have the basic functionality you would expect, such as authoring, development mode, production builds, etc. Qwik CLI uses Vite as its build tool.You can start a new app with npm create qwik@latest
to launch an interactive prompt.
When I create a simple app and run a production build, dist
In this directory you can see all the individual lazy-loadable chunks of the aforementioned app.
quick adjustment
An interesting place to learn about Qwik syntax is the Qwik Cheat Sheet where you can compare Qwik and React code side by side. All in all, we find the transition not too difficult. Some areas are very similar and some require a major mindset shift. More importantly, Qwik’s reactive system is fundamentally different from frameworks like React, despite the syntactic similarities achieved in Optimizer.
Qwik’s innovative approach to code-splitting and lazy loading offers a new way of front-end JavaScript. It will be interesting to see where things go from here.
Copyright © 2022 IDG Communications, Inc.