{"id":7198,"date":"2023-11-27T21:20:39","date_gmt":"2023-11-27T20:20:39","guid":{"rendered":"http:\/\/blog.bart.sk\/en\/?p=7198"},"modified":"2024-01-29T10:53:05","modified_gmt":"2024-01-29T09:53:05","slug":"qwik-the-first-html-framework-as-fast-as-a-lightning","status":"publish","type":"post","link":"https:\/\/blog.bart.sk\/en\/qwik-the-first-html-framework-as-fast-as-a-lightning\/","title":{"rendered":"Qwik &#8211; the First HTML Framework as Fast as a Lightning"},"content":{"rendered":"\n<p><b>If you&#8217;ve read my last<\/b><a href=\"https:\/\/blog.bart.sk\/en\/will-bun-1-0-defeat-unthreatened-nodejs\/\"><b> article about Bun<\/b><\/a><b>, 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&#8217;ve been testing, researching, comparing and trying to understand it properly. And while I&#8217;m still waiting for further improvements, I think I can bring this new HTML framework closer to you. Let\u2019s do it.<\/b><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><b>Why does the creator of Angular use React?<\/b><\/h2>\n\n\n\n<p><span style=\"font-weight: 400;\">The subtitle is intentionally a bit sensational, but it doesn&#8217;t mislead. The <\/span><b>co-founder of Qwik is none other than the father of Angular, Slovak Mi\u0161ko Hevery<\/b><span style=\"font-weight: 400;\">. I, as an angularist, like it, however, I&#8217;m less impressed that Qwik itself uses the syntax and methods of React.&nbsp;<\/span><\/p>\n\n\n\n<p><span style=\"font-weight: 400;\">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 <\/span><b>if you know React, you know Qwik.<\/b><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><b>What is revolutionary about Qwik?<\/b><\/h2>\n\n\n\n<p><span style=\"font-weight: 400;\">Basically, everything we know about frontend frameworks. <\/span><b>The main goal of Qwik is to be fast.<\/b><span style=\"font-weight: 400;\"> I mean really fast &#8211; it ranges somewhere on the level of pure HTML without JavaScript, without performing complex component rendering and meaningless loading of everything that&#8217;ll be used later. And it\u2019s successful at that.<\/span><\/p>\n\n\n\n<p><span style=\"font-weight: 400;\">Just go to the <\/span><a href=\"https:\/\/qwik.builder.io\/\"><span style=\"font-weight: 400;\">main page of Qwik<\/span><\/a><span style=\"font-weight: 400;\">, where you&#8217;ll find demonstrations of sites where the framework is already implemented. Average ratings of their speed are 97% <\/span><a href=\"https:\/\/pagespeed.web.dev\/\"><span style=\"font-weight: 400;\">according to Google metrics<\/span><\/a><span style=\"font-weight: 400;\">.<\/span><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><b>How is it possible that Qwik is so fast?<\/b><\/h2>\n\n\n\n<p><b>Qwik combines some of the basic principles<\/b><span style=\"font-weight: 400;\"> we already know from various other frameworks <\/span><b>and some of its own revolutionary ideas<\/b><span style=\"font-weight: 400;\"> put into practice.<\/span><\/p>\n\n\n\n<ol>\n<li><b>SSR &#8211; Server Side Rendering: <\/b><span style=\"font-weight: 400;\">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.<\/span><\/li>\n\n\n\n<li><b>The framework itself isn&#8217;t transmitted to clients:<\/b><span style=\"font-weight: 400;\"> only Qwik Loader, which has less than 1-2 kb, is transmitted.<\/span><\/li>\n\n\n\n<li><b>Qwik is compatible with <\/b><b>B<\/b><a href=\"https:\/\/bun.sh\/\"><b>un<\/b><\/a><b>, <\/b><a href=\"https:\/\/deno.com\/\"><b>Deno<\/b><\/a><b>, <\/b><a href=\"https:\/\/www.netlify.com\/\"><b>Netlify<\/b><\/a><b> and <\/b><a href=\"https:\/\/nodejs.org\/en\"><b>Node.js<\/b><\/a><b> and works with <\/b><a href=\"https:\/\/vitejs.dev\/\"><b>Vite<\/b><\/a><b> and <\/b><a href=\"https:\/\/esbuild.github.io\/\"><b>esbuild<\/b><\/a><b> in the background<\/b><\/li>\n<\/ol>\n\n\n\n<p><span style=\"font-weight: 400;\">These principles are well known and, if well covered, can help any framework. But what is Qwik really the best at? Let&#8217;s compare it.<\/span><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><b>How a regular website works<\/b><\/h2>\n\n\n\n<p><b>A regular modern site downloads basic HTML and a bunch of JavaScript on the first load.<\/b><span style=\"font-weight: 400;\"> 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.&nbsp;<\/span><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><b>How Qwik works<\/b><\/h2>\n\n\n\n<p><b>Qwik, on the other hand, doesn&#8217;t know hydration in the true sense of the word.<\/b><span style=\"font-weight: 400;\"> 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.&nbsp;<\/span><\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"https:\/\/blog.bart.sk\/wp-content\/uploads\/2023\/11\/Hydrat\u00e1cia.jpg\"><img decoding=\"async\" src=\"https:\/\/blog.bart.sk\/wp-content\/uploads\/2023\/11\/Hydrat\u00e1cia.jpg\" alt=\"\" class=\"wp-image-11282\"\/><\/a><figcaption class=\"wp-element-caption\"><i><span style=\"font-weight: 400;\">Hydration in a normal application and in Qwik<\/span><\/i><\/figcaption><\/figure><\/div>\n\n\n<p><b>But we wouldn&#8217;t do much with pure HTML. We need to run events, interact with actions, store statuses and solve renderings.<\/b><span style=\"font-weight: 400;\"> How does Qwik do it? Like this:<\/span><\/p>\n\n\n\n<ol>\n<li><b>All variables, component states or temporary values are recorded as an attribute in HTML<\/b><span style=\"font-weight: 400;\"> on the elements.<\/span><\/li>\n\n\n\n<li><b>Events and actions are also recorded, in the form of text in an attribute.<\/b><\/li>\n\n\n\n<li><b>Qwik serializes everything using JSON.stringify &#8211;<\/b><span style=\"font-weight: 400;\"> it solves errors such as cyclic references, serialization of built-in objects (date, maps), DOM references, promise as well as functions.<\/span><\/li>\n\n\n\n<li><b>Only one global listener <\/b><span style=\"font-weight: 400;\">is used.<\/span><\/li>\n\n\n\n<li><b>Thanks to querySelectorAll, all events are globally captured<\/b><span style=\"font-weight: 400;\"> and then compared and evaluated on the basis of selectors.<\/span><\/li>\n\n\n\n<li><b>Qwik uses built-in state management<\/b><span style=\"font-weight: 400;\"> &#8211; 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 \u00e0 la Angular is necessary.<\/span><\/li>\n\n\n\n<li><b>Each component that is visible renders only HTML.<\/b><span style=\"font-weight: 400;\"> The other components, the code itself and the actions are delayed as long as possible.<\/span><\/li>\n<\/ol>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"https:\/\/blog.bart.sk\/wp-content\/uploads\/2023\/11\/Textov\u00e9-atrib\u00faty.png\"><img decoding=\"async\" src=\"https:\/\/blog.bart.sk\/wp-content\/uploads\/2023\/11\/Textov\u00e9-atrib\u00faty.png\" alt=\"\" class=\"wp-image-11284\"\/><\/a><figcaption class=\"wp-element-caption\"><em><i><span style=\"font-weight: 400;\">This is what HTML looks like when everything is recorded as an HTML text attribute.<\/span><\/i><\/em><\/figcaption><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\"><b>In short &#8211; everything is lazy-loaded<\/b><\/h2>\n\n\n\n<p><b>In Qwik, therefore, everything that&#8217;s possible to lazy-load, is lazy-loaded.<\/b><span style=\"font-weight: 400;\"> Each component is loaded only when it&#8217;s really necessary to render it. The same applies to actions &#8211; when initializing the signal on the SSR, text HTML button is returned, but it isn&#8217;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.<\/span><\/p>\n\n\n\n<p><b>How does Qwik do it? Thanks to division.<\/b><span style=\"font-weight: 400;\"> 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.&nbsp;<\/span><\/p>\n\n\n\n<p><span style=\"font-weight: 400;\">And when Qwik, at the moment when the user presses the button, finds out that it doesn&#8217;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.&nbsp;<\/span><\/p>\n\n\n\n<p><span style=\"font-weight: 400;\">So a HTML code for the button looks like this:<\/span><\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"https:\/\/blog.bart.sk\/wp-content\/uploads\/2023\/11\/Ako-vyzer\u00e1-button-v-Qwik.png\"><img decoding=\"async\" src=\"https:\/\/blog.bart.sk\/wp-content\/uploads\/2023\/11\/Ako-vyzer\u00e1-button-v-Qwik.png\" alt=\"\" class=\"wp-image-11280\"\/><\/a><\/figure><\/div>\n\n\n<p><span style=\"font-weight: 400;\">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.<\/span><\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"https:\/\/blog.bart.sk\/wp-content\/uploads\/2023\/11\/Glob\u00e1lny-posluch\u00e1\u010d.png\"><img decoding=\"async\" src=\"https:\/\/blog.bart.sk\/wp-content\/uploads\/2023\/11\/Glob\u00e1lny-posluch\u00e1\u010d.png\" alt=\"\" class=\"wp-image-11281\"\/><\/a><\/figure><\/div>\n\n\n<p><span style=\"font-weight: 400;\">And to make it even easier, Qwik determines, in addition to the division of components, their life cycle. It divides it into three states:<\/span><\/p>\n\n\n\n<ol>\n<li><b>Task: <\/b><span style=\"font-weight: 400;\">Performs a task before rendering or after a status change &#8211; executable on both SSR and client.<\/span><\/li>\n\n\n\n<li><b>Render: <\/b><span style=\"font-weight: 400;\">Renders the component after Task and before VisibleTask.<\/span><\/li>\n\n\n\n<li><b>VisibleTask: <\/b><span style=\"font-weight: 400;\">Performs the task when the component is rendered and visible at the same time &#8211; executable only on the client.<\/span><\/li>\n<\/ol>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"https:\/\/blog.bart.sk\/wp-content\/uploads\/2023\/11\/Stavy.png\"><img decoding=\"async\" src=\"https:\/\/blog.bart.sk\/wp-content\/uploads\/2023\/11\/Stavy.png\" alt=\"\" class=\"wp-image-11283\"\/><\/a><\/figure><\/div>\n\n\n<p><span style=\"font-weight: 400;\">Based on them, it can then quickly determine where individual tasks will be performed.&nbsp;<\/span><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><b>What is the future of Qwik?<\/b><\/h2>\n\n\n\n<p><b>So what exactly is Qwik? It&#8217;s React, Svelte and Angular with SSR in one \ud83d\ude42<\/b><span style=\"font-weight: 400;\"> But it&#8217;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&#8217;s how it should be.<\/span><\/p>\n\n\n\n<p><span style=\"font-weight: 400;\">And what do I think about Qwik after more than 5 months of testing? <\/span><b>Well, it&#8217;s crazy fast, but also crazy simple<\/b><span style=\"font-weight: 400;\">, which I don&#8217;t like so much. But I can imagine that<\/span><b> it can be a great inspiration for other, more mature frameworks<\/b><span style=\"font-weight: 400;\">. SSR with initialized status, only one global listener and as much lazy-loading as possible are ideas really worth addressing.<\/span><\/p>\n\n\n\n<p><i><span style=\"font-weight: 400;\">Sources:<\/span><\/i><\/p>\n\n\n\n<figure class=\"wp-block-embed\"><div class=\"wp-block-embed__wrapper\">\nhttps:\/\/dev.to\/builderio\/a-first-look-at-qwik-the-html-first-framework-af\n<\/div><\/figure>\n\n\n\n<figure class=\"wp-block-embed\"><div class=\"wp-block-embed__wrapper\">\nhttps:\/\/www.builder.io\/blog\/qwik-v1\n<\/div><\/figure>\n\n\n\n<p><i><span style=\"font-weight: 400;\">Cover Image:<\/span><\/i><\/p>\n\n\n\n<figure class=\"wp-block-embed\"><div class=\"wp-block-embed__wrapper\">\nhttps:\/\/www.builder.io\/blog\/why-progressive-hydration-is-harder-than-you-think\n<\/div><\/figure>\n","protected":false},"excerpt":{"rendered":"If you&#8217;ve read my last article about Bun, you know that I like to try programming novelties. If&hellip;","protected":false},"author":17,"featured_media":7278,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","csco_display_header_overlay":false,"csco_singular_sidebar":"","csco_page_header_type":""},"categories":[199,516],"tags":[312,246,505,504],"_links":{"self":[{"href":"https:\/\/blog.bart.sk\/en\/wp-json\/wp\/v2\/posts\/7198"}],"collection":[{"href":"https:\/\/blog.bart.sk\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.bart.sk\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.bart.sk\/en\/wp-json\/wp\/v2\/users\/17"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.bart.sk\/en\/wp-json\/wp\/v2\/comments?post=7198"}],"version-history":[{"count":2,"href":"https:\/\/blog.bart.sk\/en\/wp-json\/wp\/v2\/posts\/7198\/revisions"}],"predecessor-version":[{"id":7410,"href":"https:\/\/blog.bart.sk\/en\/wp-json\/wp\/v2\/posts\/7198\/revisions\/7410"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.bart.sk\/en\/wp-json\/wp\/v2\/media\/7278"}],"wp:attachment":[{"href":"https:\/\/blog.bart.sk\/en\/wp-json\/wp\/v2\/media?parent=7198"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.bart.sk\/en\/wp-json\/wp\/v2\/categories?post=7198"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.bart.sk\/en\/wp-json\/wp\/v2\/tags?post=7198"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}