DEV Community

Cover image for A first look at Qwik - the HTML first framework
Miško Hevery for Builder.io

Posted on • Updated on • Originally published at builder.io

A first look at Qwik - the HTML first framework

At Builder.io, we empower non-developers to build and edit blazing fast sites with a powerful visual editor. One of the cool things about our visual editor is that we can generate the same sites in different technologies—everything from Angular to WebComponents and every framework in between. The code we output is optimized for speed, and our sites are faster than the vast majority of hand-crafted sites. We are very proud of that. Our product focuses on eCommerce, and eCommerce loves speed!

Getting good time-to-interactive is hard

Even with the most optimized code, it is hard for eCommerce sites to reach a 100 out of 100 score on PageSpeed Insights unless they serve only static HTML. This is why most eCommerce sites are around 20 and in the red. Only the very best, who can afford to focus on speed, can get their site to the 50s to 60s and into the yellow. Using Builder.io will also get your sites into the yellow 50s to 60s. But we want to do better!

one

Pure HTML is fast

Well, we can do better if we serve static HTML. That will almost certainly give us a 100 out of 100 score. After all, PageSpeed Insights shows a score measured based on the amount of code the browser must execute before the page becomes interactive. By removing all of the JavaScript execution we can get a perfect score of 100 and pass with flying green colors! But, therein lies the problem. These pages are static. We need our pages to deliver content dynamically, full of interaction and life. How can we serve static HTML to receive high scores, but at the same time provide rich interaction?

speed

Introducing Qwik - the HTML first framework

Introducing Qwik, an open-source DOM-centric, resumable web-app framework designed for best possible time-to-interactive, by focusing on resumability of server-side-rendering of HTML and fine-grained lazy-loading of code. OK, that is a lot to unpack and a lot more than we could possibly cover in this blog post. So, we will break this up into a series of blog posts, which we will post over the next few weeks. But, the basic goal of Qwik is to focus on the time-to-interactive metric by delaying JavaScript as much as possible to take advantage of the browser’s lazy loading capabilities. This is in stark contrast to existing frameworks that treat server-side-rendering and time-to-interactive more as an afterthought rather than a primary goal, which drives all other design decisions. Qwik’s goal is to crush time-to-interactive to a blink of an eye on the slowest mobile device. We want to serve static pages to the user so that they are fast, but retain all of their interactivity. We want to have our cake and eat it too!

graphic

Replayable frameworks do too much work

There is a reason why virtually no eCommerce site scores 100 on PageSpeed Insights. The reason is that all existing frameworks are not designed with time-to-interactive in mind. They have complex bootstrap processes which require a lot of code to be downloaded and executed before the page can become interactive. Yes, most support server-side-rendering to get a quick flash of initial content, but the first thing they need to do is to download all of the templates on the page and execute them to rehydrate the page and make it interactive. This download and execute is what keeps existing real-world sites from scoring 100. The current set of frameworks are replayable, as they need to replay all of the work of server-side-rendering on the client to get the site interactive. And, as your site becomes more complicated, so will the replayability cost.

two

Resumability to the rescue

The basic idea behind Qwik is that it is resumable. It can continue where the server left off. There is but the tiniest amount of code to execute on the client. The qwikloader, which takes the static HTML generated from server-side-rendering and resumes it, is less than 1kb and will execute in under 1ms. I think you may want to go and re-read the last sentence. Yes, the amount of code that we need to execute is amazingly small, and it executes in less than a blink of an eye. The best part is that this code will stay constant no matter how big your application becomes. All the other interactivity of your website is downloaded lazily as you interact with the site in the smallest possible chunks.

stuff

Find out more

Our primary focus is to develop this technology for our customers. But the technology will be developed in open-source and can be used by anyone for any purpose. While it will be designed as a general-purpose web framework, we will be prioritizing what we need for our customers first.

I am sure you are dying to find out more. We invite you to play with a StackBlitz web-container demo. (How cool from StackBlitz folks that they were able to run node.js in the browser and allow us to demonstrate the server-side-rendering, which is a key part of the framework. Hats off to them!) You can also find the open-source repo here. To set expectations, the repo is very much in the proof of concept stage and is not ready for general consumption, as we expect many things to change over time. Nevertheless, we want to know what you think. So, please join us for a chat on our Discord server.

Over the next few weeks, we will be diving into many of the unique ideas behind Qwik to explain how it ticks and what makes it unique. Stay tuned!

final

Top comments (19)

Collapse
 
john_papa profile image
John Papa

Thanks for sharing this! I love the concept!

So many questions, and I look forward to the answers in your future posts.

If I follow you, it renders server side, and you're saying it delivers that same HTML to the client. Then the javascript lazy loads after the TTI. Is that right?

Are you saying that the HTML that loads is the entire app's HTML or just the single page navigation you are on (I assume the latter, right)?

Once on the browser, is it truly interactive if the javascript is now being lazy loaded? Would some of the javascript possibly be delivered and ready after the HTML is painted?

Thanks again for sharing!

Collapse
 
mhevery profile image
Miško Hevery

Yes, you fallow right. Play with the demo here: stackblitz.com/edit/qwik-todo-demo Notice how little JS gets downloaded, and how JS keeps getting downloaded as you interact with the page.

Collapse
 
john_papa profile image
John Papa

thanks!

Collapse
 
grahamthedev profile image
GrahamTheDev

What I don’t get it as how this would work on mobile 4G connection.

Yes the page would be available quicker but trying to lazy load tiny fragments of JS for each action as they are needed is surely going to hurt performance if you have a 500ms round trip time?

Maybe you have accounted for this so I look forward to the future posts.

Collapse
 
mhevery profile image
Miško Hevery

Great question, a lot of people ask that. The server can keep track of what are common bahaviors users do on site and than can add a pre-fetch command to sart downloading (but not executing) the JS before you need it based on what the user is most likely to interact with.

Collapse
 
grahamthedev profile image
GrahamTheDev

Sounds like an interesting way to account for this, I obviously only grasp the concept at the moment so maybe I haven't quite got it based on just a simple todo list but what happens with a complex application?

If you preload say 50+ tiny JS snippets that is just going to clog even a preload strategy up?

Also look forward to seeing what a server considers "most likely" to be interacted with as that feels like something that is prone to issues.

On that line of thought one last question is if I interact with something and the script hasn't arrived yet for whatever reason, does it remember the command I entered ready for when the script is available or is that action just lost?

Prime example would be a spotty connection, I scroll the page to a contact form, start filling my name in but the validation is still lost in the ether, then I move to the next field and the validation finally loads in, will it suddenly validate the field I have just left? Would the developer have to account for this in the way they develop code (by not using .blur() etc.)

Like I said it is a really interesting concept (and the fact it focuses on HTML first is a big plus in my book) but I am just trying to understand how the "streaming JS" side of it works (for want of a better term for it!).

Collapse
 
snawaz profile image
Sarfaraz Nawaz

That implies, if some users do the uncommon behaviors (something not predicted by the server), then such users would experience the website to be slower. Am I right?

Collapse
 
johnbwoodruff profile image
John Woodruff

Fascinating idea. Really interested to see where this goes. I feel like this is the natural next step in the evolution of web frameworks. Stoked to play around with this.

Collapse
 
livioribeiro profile image
Livio Ribeiro

Sadly it does not support firefox yet

Collapse
 
marcyves profile image
Marc Augier

For me that's a no go for now

Collapse
 
luke_codes profile image
Luke Poirrier

Looks really interesting, can't wait to try it out. If you need beta testers you can put my name on that list 😉

Collapse
 
viorelmocanu profile image
Viorel Mocanu

Svelte (with Elder.js) or Astro (both using pure statically generated files + "islands of content" that only load the JS you need for that specific area) solve that issue in a similar fashion, don't they?

Collapse
 
ryansolid profile image
Ryan Carniato • Edited

Sort of. There it is all about identifying the entry points. The components you want to render and they act as islands. Whereas Qwik simply breaks apart all components and then only ships the ones that you interact with on demand.

This lets you write your whole app like a single continuous app. You aren't thinking islands and it just happens that the code loads as needed. Like in the Todo MVC example. Realistically something like Astro or Elder would ship a Todo widget component. The state is all linked. If someone tried to remove a row you would need the parent to be present. With Qwik you could pull them in separately as needed.

So in practice it probably won't be that big of a difference between the two in what gets shipped and when for low interactivity pages. Unlike libraries that seek to make Islands and manually breaking things up like Elder or Astro, Qwik is more like Marko where the creation of these Islands are basically automated. You get to write your app as if it were a typical full page framework and leave the rest up to machination.

Collapse
 
codewithahsan profile image
Muhammad Ahsan Ayaz

Wow. Played around with the stackblitz example. This is cool.
Looing forward to further posts and exploring it further to see how this seems suited for enterprise apps.

Collapse
 
zwacky profile image
Simon Wicki

This looks very promising. Not only for Qwik itself, but I can also see other frameworks possibly support resumability. I will definitely follow this.

Collapse
 
layzee profile image
Lars Gyrup Brink Nielsen

Hello, Angular Photon

Collapse
 
layzee profile image
Lars Gyrup Brink Nielsen

Would you please explain why markDirty is needed? TSX with side effects?