Qwik with Misko Hevery - JSJ 549
Today we talk with Misko Hevery about solving the loading speed issue for websites constructed using JavaScript frameworks. Such websites are often slow to load, which is detrimental to their ability so succeed. After 16 years at Google, where he created Angular, he now works on the Qwik framework at Builder.io, a headless visual CMS. We learn how Qwik dramatically improves page speed metrics through an innovative architecture that enables resumability instead of hydration. We talk about how this is implemented, and about how you can get started with it.
Special Guests:
Misko Hevery
Show Notes
Today we talk with Misko Hevery about solving the loading speed issue for websites constructed using JavaScript frameworks. Such websites are often slow to load, which is detrimental to their ability so succeed. After 16 years at Google, where he created Angular, he now works on the Qwik framework at Builder.io, a headless visual CMS. We learn how Qwik dramatically improves page speed metrics through an innovative architecture that enables resumability instead of hydration. We talk about how this is implemented, and about how you can get started with it.
On YouTube
Sponsors
Links
- ng-conf 2022
- Builder.io and Qwik - JSJ 540
- Core Web Vitals and Whatnot - JSJ 537
- JSJ 476: Understanding Search Engines and SEO (for devs) - Part
- Resumable Frameworks: | Miško Hevery | ng-conf 2022 Webinar
- Framework reimagined for the edge!
- Twitter: Miško Hevery
Picks
- AJ- JULIAN SMITH - Malk
- AJ- webinstall.dev
- AJ- Watch The Sandman | Netflix Official Site
- Charles- JavaScript Remote Conference 2022
- Charles- Home
- Dan- Gentleman Bastard Series
- Dan - War in Ukraine
- Misko- Thinking, Fast and Slow
- Steve - Dad Jokes
Transcript
Charles_Wood:
Hey everybody and welcome back to another episode of JavaScript Jabber. This week on our panel we have Dan Shapir.
Dan_Shappir:
Hey from Tel Aviv, where it's still very warm and very sunny.
Charles_Wood:
Steve Edwards.
Steve:
Hello from Portland, where it's also very warm and very sunny, shocking in August, I know.
Charles_Wood:
AJ O'Neil?
Aj:
Yo, yo, yo, coming at you live from the mechanic shop.
Charles_Wood:
I'm Charles Maxwood from Top End Devs, and this week we have a special guest. It's Mishko Hevery. Mishko, it's been a while.
Misko Hevery:
Yes, thanks for having me again.
Charles_Wood:
Now
Misko Hevery:
Ahem.
Charles_Wood:
you're actually out here in AJ in my neck of the woods for EngieConf.
Misko Hevery:
That's right. I'm visiting ng-conf right now. I'm actually in Salt Lake City in the Grand
Charles_Wood:
Nice.
Dan_Shappir:
Oh, you
Misko Hevery:
America
Dan_Shappir:
have
Misko Hevery:
Hotel.
Dan_Shappir:
something to do with Angular?
Steve:
Yeah, I was gonna
Charles_Wood:
Yeah.
Steve:
say, do you know anything about Angular?
Dan_Shappir:
Ha ha!
Misko Hevery:
Nope.
Charles_Wood:
I was telling him about it last week, it's pretty awesome. But no, I'm just kidding. So Mishko, yeah, obviously, you're one of the main forces behind Angular. Do you want to just give us an introduction though as to what you're working on now?
Misko Hevery:
Yeah, so I did this thing called Angular, which became pretty popular, and I've been at Google for 16 years, and so I think after that long time, it was time to try something new. So I went off and I tried it as a startup. I've joined Builder.io, and Builder.io is a headless
Charles_Wood:
Mm-hmm.
Misko Hevery:
visual CMS. And one of the things that Builder is trying to do is make sure that our websites, that our customer's website are as fast as possible. And so Builder is investing heavily in open source projects make web fast. And so for that, we have a couple of things. We have this thing called Quick, which is a front-end framework specifically designed for startup performance. And then we have this other thing called Party Town, which is designed for dealing with third-party scripts.
Charles_Wood:
Nice.
Dan_Shappir:
We actually had Steve on the show. This is our,
Steve:
Yes.
Dan_Shappir:
we are on our way to have like,
Charles_Wood:
cutting out
Dan_Shappir:
what
Charles_Wood:
even
Dan_Shappir:
can
Charles_Wood:
though
Dan_Shappir:
I call
Charles_Wood:
I paused
Dan_Shappir:
it? A
Charles_Wood:
him.
Dan_Shappir:
Builder.io series
Charles_Wood:
Yeah, we did,
Dan_Shappir:
here
Charles_Wood:
we had Steve
Dan_Shappir:
on
Charles_Wood:
on.
Dan_Shappir:
JavaScript Jabber where we had Steve talking about Builder itself. We have you to talk about Quick and then we'll have Adam to talk about Party Town in another episode. So, you know, we're getting all the good stuff.
Steve:
I guess for reference that was episode 540
Misko Hevery:
What?
Steve:
of JavaScript Jabber from July.
Charles_Wood:
Yep.
Misko Hevery:
We just want the web to be fast and win, man.
Charles_Wood:
Yep,
Dan_Shappir:
Yes.
Charles_Wood:
absolutely.
Misko Hevery:
That's the goal.
Charles_Wood:
I'm gonna put a link in to the chat for the show notes, but yeah, it was fun kinda talking about it and what goes into it, so yeah. But let's dive in and talk a little bit about QUIC. Do you wanna just give us the 10,000 foot view? I have a bunch of other questions that I wanna ask, but I think we need to give people kind of a baseline of what we're talking about, and then we can kinda move from there.
Misko Hevery:
Yeah, I think the best way to kind of get to 10,000 view is to kind of look at the history of how we got here. And we got here, first HTML became a thing. And so we had a whole bunch of server side rendered content using PHP or insert your favorite backend rendering technology you want. And then because it was server side rendered, we had static output, right? And so we needed to make the static output somehow interactive. And so we had something like jQuery or MoodTools or anything like that. That setup kind of worked. The problem was that you kind of had to write the thing twice. Once on a server using the server end technologies, and then again on a client using JavaScript. And so over time, frameworks such as Angular, React, Vue SDK, et cetera, took over. And the value for these frameworks is that they have both the server side and the client side, right? So a single mental model on
Charles_Wood:
Hmm.
Misko Hevery:
both ends. But they were really designed as frameworks And what that means is that really the way originally these frameworks were designed is for the app to start up in the client and basically everything happens in the client. But as we discovered, everything happening at the client meant that you would navigate to a page and you would see a blank page for a while before the JavaScript kicks in. And that would be slow, especially on mobile devices or slow devices, slow networks. And so server-side rendering became a thing, right? became a thing. And that improved the situation, because now the user could see the content before they interact with it. But it kind of is a trickery. Actually, recently I read a Twitter that somebody did it, a nice tweet that, you know, service-side rendering is kind of like, you come up to a site, you see a cake, and you're like, oh, I'll have some of that cake. And then the computer says, that's actually just a picture, but I have all the ingredients. Let me bake you a cake if you just wait a little bit. And so that's kind of what's happening right now. kind of slow on startup performance.
Dan_Shappir:
No,
Misko Hevery:
And so
Dan_Shappir:
cool,
Misko Hevery:
quick,
Dan_Shappir:
I
Misko Hevery:
yeah.
Dan_Shappir:
think it's a great explanation. You
Charles_Wood:
Mm-hmm.
Dan_Shappir:
delivered a lot of information in a really short period of time, like the history of the web as it were.
Misko Hevery:
Ha ha.
Dan_Shappir:
Yeah, we actually had several episodes about this in the past. I think that, yeah, this introduction of server-side rendering or SSR as a means to address a performance creating another or a different performance problem. Like the original problem
Misko Hevery:
Yeah.
Charles_Wood:
Right
Dan_Shappir:
was that you would wait a long time for the content to actually see anything. But once you saw something, it was immediately interactive. Because the JavaScript rendered the
Misko Hevery:
Mm-hmm.
Dan_Shappir:
UI on the client side. And the instant that the UI was rendered invisible, the JavaScript was there to handle all the interactivity for the stuff that it created. Like you said, you had to wait for the empty HTML to arrive to make the request for the JavaScript, for the JavaScript
Misko Hevery:
Mm-hmm.
Dan_Shappir:
to arrive, quite a lot of JavaScript usually, then for that JavaScript to be downloaded, parsed, compiled, actually make Ajax requests to get the relevant data. So you had to wait for that as well. And then for the JavaScript to run and actually dynamically generate the HTML around it, and And this was kind of viable on desktop devices, but totally inappropriate for mobile devices. Because for mobile devices with mobile connections and mobile processing speeds, especially of the lower end Angular, sorry, the lower end Android device, I was thinking A's, the lower end Android devices and the connections that you have in various countries around the world, it basically just user experience which was wholly unacceptable. And I remember at that time I was working at Wix, and Wix originally, that's exactly how it worked. That everything was done client side. And like I said, it kind of worked fine where all the customers were in the US, and most of the visitors were coming from desktop devices. But once the company kind of started reaching out global markets, and once the company, and once like the
Misko Hevery:
Thanks for watching!
Dan_Shappir:
majority of sessions mobile device-based sessions, it was just wholly inadequate. And then like you said, we moved over to server-side rendering where you run the same code. We used to call it isomorphic code, but I don't think I've heard the term in a long time now. You essentially run the exact same React code or view code or whatever on the server side. You generate the initial HTML, the initial view on the server side. You can even cache it either on the server itself deliver it really quickly, but like you said, what you get is the HTML without the JavaScript that creates the interactivity. So then you really quickly get something, and the assumption is that by the time that the user figures out what they're seeing and understands what they want to do, then hopefully by that point in time, you would have already downloaded the JavaScript, downloaded the everything up so that interactions could be handled. But it turned out that way too often, this was not actually the case. And then in effect, what you're getting is something that's potentially worse than slow, it's something that's broken. It's a UI that the visitor tries to click on or interact with, and literally nothing happens. So, and that's kind of like from my perspective, the worst experience possible.
Charles_Wood:
I want to add two
Dan_Shappir:
Yeah,
Charles_Wood:
things
Dan_Shappir:
go
Misko Hevery:
Yep.
Charles_Wood:
to
Dan_Shappir:
for
Charles_Wood:
that.
Dan_Shappir:
it.
Charles_Wood:
One is that one of the solutions that people had to some of this was that you would make your website work without the JavaScript. But then you had to do all this extra work and think through all the scenarios that weren't natural to what you were doing. The other issue was that occasionally you would run into stuff where isomorphic didn't actually mean isomorphic, where you would do something and for whatever reason you'd do it on the server-side rendering and it would do something different from what it would do on the client-side. limbo until everything kind of straightened itself out.
Misko Hevery:
Yep, that's pretty much it. So that's the problem space. And this is the problem space that Quick wants
Charles_Wood:
Oh good,
Misko Hevery:
to
Charles_Wood:
because I was
Misko Hevery:
address.
Charles_Wood:
about to quit.
Misko Hevery:
Yeah, so the problem space that is described here by Dan very well is that the site's startup performance is not very good. And there's a lot of metrics that basically tie startup performance to your business
Charles_Wood:
Mm-hmm.
Misko Hevery:
performance. That basically says, you know, like if your website is slow, people leave, people don't buy, people don't put things in the shopping cart, you know, your revenue goes down and Google's trying hard and the Chrome team is trying hard to quantify this. that Google has, they actually talk about like, this company has seen increase this much if they improve the performance, so on and so forth. And so to kind of spur the industry, Google has created this thing called Page Speed Metrics. And the idea behind Page Speed Metrics is that like, hey, let's start by measuring, right? Like things don't get better unless we measure things. And so Page Speed Metrics and Core Web Vitals are ways of measuring the performance And then the idea is that, you know, use that information to kind of get, make the web a better place. And so Google is saying that as leverage, they basically will use the performance information in their ranking, in the SEO ranking that hopefully more incentivizes people to kind of, the companies
Dan_Shappir:
Yeah,
Misko Hevery:
to
Dan_Shappir:
we had
Misko Hevery:
improve
Dan_Shappir:
some
Misko Hevery:
this.
Dan_Shappir:
episodes on this as well. So we actually even had Annie Sullivan, who was the tech lead for this team at Google, who works on Core Vykl here on the show explaining the history. And it was an excellent episode and I highly recommend it. And we also had Martin Splitt talking exactly about how they use this information as a ranking signal Google search engine. And I agree that this was a prod or even a whip that Google kind of used to push the industry in the right direction. But like you said, I think the more important aspect, even than the Google rank, is the fact that performance has been shown to have a significant impact on engagement. Like I said before, if somebody visits your site and then tries to click buttons on your site, and your site just doesn't respond clicks, that user will leave. They will not stay there hoping that, who knows,
Misko Hevery:
Yep.
Dan_Shappir:
maybe in four, five, six seconds, the site will fix itself. This is not how people behave. People expect, especially in today's, with the immediacy of mobile devices, people expect the user interface to respond very quickly and very instantaneously, almost essentially instantaneously interactions.
Misko Hevery:
You know, people also use speed as a proxy for quality. You know, people will say like, oh, this website must be really good website because it's really snappy, fast versus they're like, you know what? I don't like this website. I don't necessarily might not be able to verbalize as to why they have the feeling of not liking, but like, this is one of those things that humans do. They do this kind of substitution trick where like they need to decide whether they trust something or like something and they don't have sufficient other information such as speed for it.
Dan_Shappir:
I totally agree.
Misko Hevery:
Anyway, so we kind of described the problem space, and I really want to point out here is that on the end of the day, the
Charles_Wood:
Mm-hmm.
Misko Hevery:
users win, right? Like this isn't like Google trying to trick somebody, whatever, like on the end of the day, like the aim is to make sure that we have fast websites because people enjoy using fast websites, right? So like this is a correct thing to do. It's the right thing to do to figure this out. Now, the next problem though is that Everybody agrees on this. Everybody wants to do this. Everybody understands that there is economical value in improving your website performance. But it turns out we don't actually know how to do this. Because if you look at top 50 e-commerce websites, vast majority, like 90% or something like that, fail Google Web Vitals in terms of performance. And very few actually pass. First of all, nobody really passes. Most of them are in the red. are in the yellow like Amazon and I think IKEA and I think Staples out of all of them, I actually have good scores, comparatively good, they're kind of in the yellow. But I've never seen a real production website that actually has green scores on page speed in production and yet there is so much incentive to get there,
Steve:
That seems
Misko Hevery:
right?
Steve:
like contradictory.
Misko Hevery:
And so
Steve:
I mean, basically
Misko Hevery:
to
Steve:
you're
Misko Hevery:
me,
Steve:
saying, okay, we need to go to these core web vitals, but all the top websites don't have good core web vitals. So how do you resolve that?
Misko Hevery:
Yeah, I think the problem is that the approach we have is not right. Like we're solving the problem in a wrong way. Like again, if you go back in time and how we got here, we'd recognize that we needed frameworks. And so we started
Dan_Shappir:
Thanks for watching!
Misko Hevery:
working on frameworks and these frameworks were essentially lifted from what was available in desktop. And in desktop, you don't think about things like lazy loading your code or executing stuff or like, because the constraints are different. And so it's perfectly fine to execute the app from the very And so I think the problem is that the frameworks we have today aren't really thinking or not really designed with these constraints in mind. And this is where QUIC comes in. QUIC is really rethinking the whole stack of how a website is built so that the end result
Aj:
So
Dan_Shappir:
So
Misko Hevery:
is what we call
Aj:
I
Misko Hevery:
resumable.
Aj:
missed something.
Dan_Shappir:
before you
Aj:
We're
Dan_Shappir:
go
Aj:
not.
Dan_Shappir:
there, AJ, if I can interrupt you for one second just to put some data behind what Mishko just said, I took a quick look at the data that Google provides in their Crux report website where you can actually look at the performance of various technologies like CMSs and also various frameworks. websites worldwide that have good core web vitals? Like what percentage out of all React websites?
Misko Hevery:
Well, I want to clarify websites
Dan_Shappir:
Yes,
Misko Hevery:
that are in production,
Dan_Shappir:
exactly,
Misko Hevery:
real websites,
Dan_Shappir:
real
Misko Hevery:
not toy
Dan_Shappir:
websites.
Misko Hevery:
websites, right?
Dan_Shappir:
This is Google collecting data off of actual Chrome sessions. So whenever we actually had Rick Viscome also on the show talking about that, Google actually instrumented their Chrome browser to collect performance data anonymously, of course, from every website that you visit, unless you explicitly opt out. And they collect all this data into a database, it based on technologies using a website etc. So based on the real data from real live websites out there based on actual visitors visiting those websites, what percentage of let's say react and view websites in your opinion have good core web vitals? Can anybody guess? Yes, you can get you
Misko Hevery:
Am I
Dan_Shappir:
go
Misko Hevery:
allowed to
Dan_Shappir:
for
Misko Hevery:
guess?
Dan_Shappir:
it. Well,
Misko Hevery:
I think
Dan_Shappir:
no,
Misko Hevery:
it's pretty
Dan_Shappir:
you're
Misko Hevery:
close
Dan_Shappir:
too
Misko Hevery:
to zero.
Dan_Shappir:
harsh. So,
Charles_Wood:
Yeah,
Dan_Shappir:
approximately...
Charles_Wood:
way too harsh. There are at least
Misko Hevery:
Thanks for watching!
Charles_Wood:
six websites that use React that
Dan_Shappir:
Yeah,
Aj:
Even
Charles_Wood:
perform
Aj:
I was gonna
Charles_Wood:
well.
Aj:
give it 1%.
Dan_Shappir:
no. No, so, so no, no. So the reality, no, no, you need to consider that a lot of websites out there are actually fairly lightweight and don't necessarily do that much.
Misko Hevery:
Yeah, so this is what I meant by real production e-commerce websites. When you go real production e-commerce websites, I'm going to say it's pretty close to zero. When you go toy websites or blog posts,
Dan_Shappir:
Yeah,
Misko Hevery:
et cetera,
Dan_Shappir:
so I was
Aj:
think
Dan_Shappir:
lo-
Aj:
the number
Misko Hevery:
that number
Aj:
goes
Misko Hevery:
goes
Aj:
down?
Misko Hevery:
up.
Aj:
Have you have you looked at people's react blogs?
Dan_Shappir:
By the way, in the case of React, I have to say, and take a bit of credit, Wix is actually pulling React up because Wix websites are actually built using React on the inside, and Wix has invested a lot of effort into the infrastructure in order to provide good performance. So Wix websites actually have higher good core vital ratios than React websites in general and are actually pulling React up. But the answer is that in the case of React, 30% of React websites have good core vitals data. In other words, 70% do not, which is the vast majority. And in the case of Vue, Steve, by the way, it gets even worse. In the case of Vue, only 26% of Vue websites actually have good core vitals. So only about a quarter of Vue websites out there have good core vitals. It's quite obvious that the frameworks aren't doing anybody any favors Especially when you compare to the average across all websites, which is closer to 40% So in fact using a framework actually pretty much guarantees that you will have worse performance Than not using a website. Maybe I'm giving you stuff for your talk
Misko Hevery:
No, this is good stuff, actually. I will probably use some of it
Aj:
So
Misko Hevery:
in my talk.
Aj:
I wanted to back up for just a second.
Misko Hevery:
Yeah.
Aj:
So you've been using the term quick and you may have explained it, but when I first heard it, I just assumed you were talking about quick as an HTTP three, but it sounds like that's not what you're talking about.
Misko Hevery:
Yeah, no, no, no. I'm talking about a new kind of framework for rendering your websites. Framework that basically is designed around this idea of the first thing we want to aim at is make sure that the performance is absolute best we can get. And then everything else follows from that goal. And this is actually not how the rest of the frameworks are designed. Many other frameworks are basically aren't really designed with thinking problems from day one and as a result they end up in kind of accidentally end up in places which make performance kind of hard
Charles_Wood:
I do want
Misko Hevery:
to
Charles_Wood:
to
Misko Hevery:
achieve.
Charles_Wood:
point one thing out, just to give them some credit. A lot of these frameworks do make web development quite a bit easier, right? Or they give you a lot of tools that let you build
Misko Hevery:
Yes.
Charles_Wood:
it. And so it's not like this clear trade-off where it's like, you must be an idiot if you're not doing this. It's, right?
Misko Hevery:
Oh no, the DX
Charles_Wood:
Right.
Misko Hevery:
is amazing
Charles_Wood:
So
Misko Hevery:
on
Charles_Wood:
my
Misko Hevery:
these
Charles_Wood:
point
Misko Hevery:
frameworks.
Charles_Wood:
is, I guess, mostly that... you know, we just need to be paying attention to, you know, what do you care about? What matters in your circumstance here to make sure that, you know, you're getting out of your framework what you want.
Misko Hevery:
Yeah, I actually want to take this a little more nuance, which is that when I think a lot of times when you have a slow performing website, people are quick to blame either the developer or the situation or something like that, right? And if that would be the case, then there should be websites out there that are good performance. It should be e-commerce website that are
Charles_Wood:
Mm-hmm.
Misko Hevery:
good performance, right? Because not all of us are equally bad. Some of us are a little better than others. But the point is that no good e-commerce websites. Even the ones like Amazon that clearly have the resources and money, et cetera, to spend on it, they only get kind of yellow score on the performance metrics. And so because nobody seems to be able to get this right, I think the fault does not lie with individuals as with developers, but rather I think the fault is systemic and not in a sense that it lies in our approach. is the problem, right? We need to rethink the way the websites are built, the way frameworks are built, the way these solutions happen so that we can get good performance. Because doing it what we're doing today, we have plenty of empirical evidence that basically says we suck at this, right? We just cannot get, consistently get good performing website that is in real production, right?
Dan_Shappir:
So what is it that
Misko Hevery:
Go on.
Dan_Shappir:
most existing or almost all current frameworks are doing wrong that you think that QUIC is doing right? How is QUIC different? Well, you said that your initial intent was different and that was kind of the catalyst or the driver for
Misko Hevery:
Mm-hmm.
Dan_Shappir:
all your technical decisions, but at the end of the day, what does this translate to?
Misko Hevery:
Yeah, so that's an excellent question. So existing frameworks, I think they fall into this category that I call replayable. And what I mean by replayable is that they replay the application on the client in order to rebuild it, right? So the server sends HTML over, and we're pretty good at server-side rendering. We know how to make it fast. We know how to send HTML to the client, and the clients are super fast at turning that HTML into pixels on a screen, right? the page to render quickly. The problem is that at this point, we don't know how to make the page interactive. Instead, what we do is we replay everything the server just did in order to rebuild the framework, rebuild the application so that we
Dan_Shappir:
I
Misko Hevery:
can
Dan_Shappir:
think
Misko Hevery:
make it
Dan_Shappir:
it's
Misko Hevery:
interactive.
Dan_Shappir:
worthwhile
Misko Hevery:
All
Dan_Shappir:
to expand
Misko Hevery:
right.
Dan_Shappir:
on this point a little bit because originally this problem did not kind of exist. You kind of alluded to that when you mentioned the old days where you had PHP and jQuery
Misko Hevery:
Yeah.
Dan_Shappir:
because the jQuery did not need to... jQuery could add interactivity and could do it fairly quickly. This problem did not exist. The key difference is that with modern frameworks, I think, and you tell me if you agree with this interpretation or not, the code, the JavaScript running on the client needs to assume total control over what happens with the application from that point going forward. Because like you said, it's a single page application, so all interactions with the user interface needs to happen on the client side, which means that the JavaScript on the client side needs to have an applicative state that describes the entire user interface and also any state transition that might happen with it. And that essentially
Misko Hevery:
That's
Dan_Shappir:
requires
Misko Hevery:
right.
Dan_Shappir:
recreating that application state that existed on the server was created. And that's something that jQuery didn't even try to do. jQuery was just about, yeah, we have this button.
Misko Hevery:
That's right.
Dan_Shappir:
You click it. I'll handle it. But it didn't try to go from there to generate the next page on the client side. You still did that round trip back to the server if that's what you wanted to do. And
Charles_Wood:
Now is that because of the
Misko Hevery:
That's
Charles_Wood:
Shadow
Misko Hevery:
right.
Charles_Wood:
DOM and the way
Dan_Shappir:
No,
Charles_Wood:
that it
Dan_Shappir:
it
Charles_Wood:
manages
Dan_Shappir:
has nothing
Charles_Wood:
changes
Dan_Shappir:
to do with
Charles_Wood:
or something
Dan_Shappir:
a shadow.
Charles_Wood:
else? Okay.
Dan_Shappir:
No, no, no. Shadow DOM is totally different topic. This has to do with the virtual DOM. I think that's the term you're looking
Charles_Wood:
The virtual
Dan_Shappir:
for.
Charles_Wood:
DOM, that's, yeah.
Dan_Shappir:
Yeah.
Charles_Wood:
Yeah.
Misko Hevery:
I wouldn't even say it has to do with virtual DOM. I would do it more broadly, which is that application has really two states, right? One is the application state. And as a developer, this is kind of innate to you. Like you know what it is because you use it, you move it around, you data bind to it. So you totally understand this concept of application state, right? This is the data that you're showing to the user in some form. But there's a second state that is not necessarily obvious, which is the framework state. And frameworks really tried very hard to hide it from you, right? don't think about what is framework doing underneath in order to render the page. But framework has state, too. Framework needs to understand
Charles_Wood:
Mm-hmm.
Misko Hevery:
where are all the buttons, where are all the components, what are the relationship within components. If I click on this button, what function do I call? If this function gets executed and I modify the state, which component do I need to re-render? So there's a huge amount of state that the framework also has in addition to what the application has. And people don't normally think about that particular information as state. state nevertheless. And so the problem is when the framework first wakes up, like when jQuery wakes up, it's not a framework, and so it has no state, and so it just does whatever you ask it to do. But when a framework wakes up, it's like, great. I have amnesia. I don't know anything. And I need to recover this state somehow. And the way the framework to recover this state is they fully execute the application from the root of the component all the way through. And as the application is executing, the framework slowly builds up information about the relationship between components, where the listeners are, what should happen when you click on the listener, what is the state, which other component has the state, and so on and so forth. And it's the rebuilding of this state, the rebuilding of the framework state that people don't usually think about that's actually causing all of these delay or this wake
Dan_Shappir:
And this
Misko Hevery:
up,
Dan_Shappir:
step is
Misko Hevery:
startup
Dan_Shappir:
usually
Misko Hevery:
delay basically.
Dan_Shappir:
called either hydration or rehydration or stuff like that because
Charles_Wood:
Mm-hmm.
Dan_Shappir:
you essentially had like
Misko Hevery:
That's right.
Dan_Shappir:
the dried data as it were embedded in the HTML maybe like Next.js does where it sticks a big JSON in the HTML which describes the initial
Misko Hevery:
Mm-hmm.
Dan_Shappir:
startup data but it's not state. It's the initial. Exactly.
Misko Hevery:
But that's the application data. That's the application
Dan_Shappir:
Yes.
Misko Hevery:
data, not the framework data.
Dan_Shappir:
and runs everything that it needs to do in order to recover its internal framework state from that initialization data as it were. And that's again, that's the hydration or rehydration or that's the usual term that I hear for.
Misko Hevery:
Yeah, and that's really the problem, the root of the problem, right? Your application, when you navigate to a particular page, takes long time to wake up, to become interactive, whatever you wanna call it, because in order for the framework to make it interactive, in order for the framework to be like, oh, there's a click listener at this location, the framework has to execute the application fully. But in order to execute the application fully, the framework has to download the application fully, right? And so it's this cascade of things, like on the end of the day, button that I have to click and I want to know the listener. But in order to get the button, I have to run the component. In order to run the component, I have to download the code. And it just cascades all the way down. And so even a simple website that's relatively static, the moment it has any sort of interactivity, forces you to re-execute the application fully. And this is where the slowdown comes from. And this is why the wake-up performance of these applications is low. And this is basically the thing that trying to solve, right? And this is why we're talking about this idea of replayability. Because you know, frameworks call it hydration or rehydration or whatever you want. What's actually happening in there is that the framework is replaying, it's redoing all the work the server just did so that it can recover the information that's missing.
Dan_Shappir:
I really like this explanation. I think that a lot of developers aren't really aware of this process. They just know that at startup time, if they've ever looked at the performance tab in the Chrome DevTools, they see that they have this lengthy execution time. But they don't necessarily know
Misko Hevery:
That's right.
Dan_Shappir:
what that stuff is or where it comes from. So I think it's really important. And there are various attempts and various approaches either reduce this time or at least mitigate its impact, like react suspense
Misko Hevery:
Yeah.
Dan_Shappir:
or concurrent mode to an extent is an attempt, remix with their approach of falling back to the built-in HTML functionality and other approaches, the islands approach. So there are various other approaches. I would call, is the one that takes the problem the most head on is what I would say.
Misko Hevery:
Yes. Yeah. So most approaches, I would say, fall into the category of like, we have to do this work and now we can just debate when the work gets done. Right? And this is kind of what most existing approaches fall into. And so the work can be subdivided into smaller chunks. We can prioritize the order of things. We can delay order. We can subdivide it into islands. But on another day, about when the work happens and how much of the work happens eagerly and which one is later. So, Resumable Systems are very different. They basically, as you say, it takes head on, they basically say, actually, instead of wasting all this time trying to recreate this information that was lost on a server, we had the information at the server. Why can't we just have a framework that can serialize all this information in such a way that when you get to the client and the framework wakes up And there is nothing to do because the framework state is serialized inside of it. And if you think about it, it's kind of what Next.js is doing with the next data attribute that they put inside of the script tag, inside of your page. But it's doing it for the application. When the application wakes up, the application also says, I need to get data. And so the application will start making XHR requests or something like that. And so Next.js is basically saying, no need to do the XHR. So when you wake up, you have the data ready and you can save yourself whole bunch of round trips, right? So it's the same exact idea. We're just taking it all the way through and saying, yes, but let's do it for the framework as well. So when the framework works up, it doesn't have to be like, where are the component boundaries? Where are my listeners? If I change this data, where is the subscription for it? None of this information needs to be recovered because it's just serialized
Charles_Wood:
Okay,
Misko Hevery:
inside
Charles_Wood:
so
Misko Hevery:
of the HTML.
Charles_Wood:
my question then is, I mean, you know, you spent how many years working on Angular? Why couldn't you just make Angular do this?
Misko Hevery:
So it's kind of funny that I'm in Utah
Charles_Wood:
Right?
Misko Hevery:
right now, in Angular conference, because in 2019, I was on a stage of ng-conf, and I gave a talk about replayable versus resumable applications.
Charles_Wood:
Mm-hmm,
Misko Hevery:
I'll have a link
Charles_Wood:
right.
Misko Hevery:
for you so you can share with your, it's on YouTube. And I basically laid all this thing out for it. hard in the sense that there are very subtle design decisions that you have to make in order to make things reasonable. And these design decisions, unless they're kind of baked in from the very beginning, are really hard to bring back
Charles_Wood:
Hmm?
Misko Hevery:
after the fact, right? Because these design decisions turned out to be breaking changes for the existing ecosystem, right? And so, is it possible for existing frameworks to become reasonable? Absolutely. But it's hard because doing so will introduce breaking changes into the system. And these breaking changes are not subtle. They're pretty big. And these breaking changes basically means that the framework has to say to the community, you know what? We're making such a big breaking change that all of your existing third party software essentially
Dan_Shappir:
I think
Charles_Wood:
Yeah,
Dan_Shappir:
a
Charles_Wood:
everybody
Dan_Shappir:
great
Misko Hevery:
won't work.
Charles_Wood:
loved that when Angular went from one to two.
Dan_Shappir:
Ya, Enat
Misko Hevery:
Yes, and I don't think
Dan_Shappir:
And look
Charles_Wood:
Yeah.
Misko Hevery:
anybody's
Dan_Shappir:
at how long
Misko Hevery:
willing
Dan_Shappir:
it's
Misko Hevery:
to do
Dan_Shappir:
taking
Misko Hevery:
that.
Dan_Shappir:
for the React team to come up with React 18, where they're arguably making a much smaller change about just being able to break up the hydration process into sub-steps that can be paused and resumed. And
Misko Hevery:
Yes.
Dan_Shappir:
I really don't think that people understand this potential scope of the challenge,
Misko Hevery:
No. Yes.
Dan_Shappir:
you have a JavaScript application, forget about browser and server. Let's say I have a JavaScript based application or maybe not even JavaScript, any type of application running on one computer. And I want to somehow transfer the entire state of dynamic state of that application off to another computer so that it can keep running immediately from wherever it was. You know, all the closures, the objects in memory, like serializing all this stuff is really complicated and potentially also really heavy. One of the examples that I like to give that is kind of similar to that is that, you know, in JavaScript, in the browser for a long time, we've had web workers as a way to kind of offload work off of the main thread into like sub threads Unfortunately,
Misko Hevery:
Mm-hmm.
Dan_Shappir:
it hasn't caught on to the extent that we would have hoped. And one of the big reasons is that serializing data and sending it from one worker to another and then serializing the data back is often so complicated and so heavy that it takes more time than actually doing whatever computation that you want it to do. So it's really challenging to do this thing effectively. Well, how you did it.
Misko Hevery:
First of all, a little plug for party town, right? Party town is the thing that allows you to run your stuff in web workers. So people should check it out. But yeah, how exactly do you do that? So the whole problem, as you pointed out, really comes down to serialization, right? You need to be able to serialize the state of the system. And what's kind of hard about it is that a lot of time the state of the system lives in like weird places you don't think about. When you have a listener, for example, when I have a counter, and the counter has a button, and the button has a listener, and you click on that listener, the handling function for the counter is pretty simple. It just increments some number. The hard part is, well, what is the number you want to increment? If you just lazy load that function, it has amnesia. It has no idea what the current state is. And so, yeah, the code is easy. Sure, increment what number is it currently at? And that's the hard part. And the hard part is that usually these functions close over other variables, right? So if you look at React function, if you could say the React component count, it will have things like, you know, state equals use state, right? And then the click listener closes over the use state. And so if you try to lazy load a listener, now the problem is, yeah, state function, the setter function, right? Like how exactly do you do that? And so the whole thing really comes down to this, to this problem of serialization. But there's a second problem as well. And that is not only do you need to serialize everything, you also need to be able to break up the system so that you have multiple entry points into your application. If you think about an existing app, like again, let's do a very simple counter example. In the case of a counter, the only thing that you really have to export is some kind of a main method, right? Like an entrance to the system and everything else can be in a single bundle with no other exports, right? But if you wanna be resumable and you now click on the plus one button, you don't
Charles_Wood:
Thanks for watching!
Misko Hevery:
wanna enter the system by the main method, right? By re-entering and re-rendering the whole thing, you wanna just enter it by going directly to the listener. And that listener is a closure It's not a thing that I can lazy load. And so the problem comes down to serialization. And two, how do you rearrange the source code in such a way so that you can enter the system in places other than the main method? Basically, every single listener is a potential place of entry.
Dan_Shappir:
And I also assume that you want to slice and dice the code, ideally in such a way that code that, so for example, if I have two buttons on the page, maybe I, if when, when you. I want to need the code to handle, but one button, you don't necessarily want the code to handle the other button, especially, you know, if it's really complicated
Misko Hevery:
Mm-hmm.
Dan_Shappir:
code, it does a whole lot, bunch of computations and requires a lot of, of stuff that's associate state that's associated with it. I don't necessarily want to download that state if I don't, if I don't need it yet.
Misko Hevery:
That's right. So if you look at a typical e-commerce website, you might have a button for ads to the shopping cart and people will probably click on that. And you also might have a button
Dan_Shappir:
Thanks for watching!
Misko Hevery:
for like logout or something like that, which like how many of us actually ever click on the logout button? Like almost never, right? So
Dan_Shappir:
Thanks
Misko Hevery:
it's
Dan_Shappir:
for watching!
Misko Hevery:
unfair to basically treat the two callbacks as of equal importance in terms of loading, right? You wanna be able to say like, well, this button is more important so I want its code to be loaded first
Dan_Shappir:
you
Misko Hevery:
And this button over here is kind of less important. And so it's not as, you know, you can load it later or basically even skip loading it. So one of the things we kind of talk about with QUIC is that it has two important properties that other frameworks don't have. One is this idea of reasonability, right? Where you just continue where the server left off. And the other idea is partiality, which is that you partially execute stuff only as needed. Right? The idea of partial is that download and execute code that is actually needed. And so when you combine these two properties together, you end up in a world where no matter the complexity of the application, doesn't matter how complicated the website is, you essentially start with zero JavaScript. And you don't have to recover any state because you're resumable, so you skip that part. And then the partiality allows you to basically download the code as the user interacts
Dan_Shappir:
But that
Misko Hevery:
with the page.
Dan_Shappir:
brings up an interesting point from my perspective, because what you're saying that the code that handles the button click only actually gets downloaded potentially and initialized or resumed rather than initialized on the client after the person clicks the button. So where does the event go? I mean...
Misko Hevery:
Yeah, so you have to have a framework that is asynchronous in the sense that it has to, you know, the way normal frameworks work is that if you want to set up a click listener, you have to have a closure for the listener ready ahead of time. Whereas in, in the resumable world, it's kind of the other way around. Like, you know, there is a listener, but you don't know what's handling the listener until the listener actually gets triggered. And There's some lazy loading that's involved. And of course, there is, you need to be able to handle these events in a asynchronous manner. And oh, by the way, most existing frameworks cannot handle things asynchronously. Most existing frameworks really want
Aj:
Yeah,
Misko Hevery:
everything
Aj:
that's
Misko Hevery:
to be
Aj:
something
Misko Hevery:
fully synchronous.
Aj:
that's been really frustrating looking at the front end landscape is that the, you'd think that because it's JavaScript, I guess, I guess, because promises have only been around for what five years in the language itself, but yeah,
Misko Hevery:
Yeah.
Aj:
everything that the error handling is terrible. The routing is terrible. It's really, really difficult to design well on the front end with the existing frameworks due to that lack of, I mean, that's, that's, that's a primitive of is its async nature.
Misko Hevery:
Yeah, it's funny because I used to talk about how Quick is also asynchronous. But it didn't really resonate with people, so I kind of stopped mentioning it. But yes, one of the key property of Quick is that it is fully asynchronous so that you can stop, you can pause rendering at any point with a promise. And we actually take advantage of that with streaming. And you can also, of course, your click handlers are also fully asynchronous. And so you don't need to necessarily process the event immediately. But all of that kind of has to be built into the framework. And the framework has to be happy with the fact that when a parent component wants to go and instantiate a child component, it might not exist. The child component might have to be fetched from somewhere in order to do the instantiation.
Charles_Wood:
Eww.
Misko Hevery:
And most
Dan_Shappir:
So
Misko Hevery:
frameworks
Dan_Shappir:
all events
Misko Hevery:
are not very good at
Dan_Shappir:
and
Misko Hevery:
dealing
Dan_Shappir:
all communication
Misko Hevery:
with that.
Dan_Shappir:
between components or let's call it all communication between the various subsystems that say in quick are essentially asynchronous based on what you're saying. That
Misko Hevery:
Yes,
Dan_Shappir:
cool.
Misko Hevery:
it has to be. Otherwise, you can't insert lazy loading
Dan_Shappir:
Cool,
Misko Hevery:
everywhere,
Dan_Shappir:
interesting.
Misko Hevery:
right?
Charles_Wood:
you
Misko Hevery:
Because lazy loading is asynchronous, right? If you do a dynamic import, it's a promise. And therefore, you can call a synchronous function from an async function. But the other way around, it doesn't really work. You can't call a synchronous function from a synchronous function.
Dan_Shappir:
But I can see it still causing potential issues. Like for example, if I want to cancel the default browser processing of an event, I have to do that synchronously. I can't do that asynchronously, because by that point in time, the built-in functionality would have executed.
Misko Hevery:
Yeah, so there are ways we have for kind of doing this. So certain things you write have to be done fully synchronously. There's no choice. It's just the way the browser API is. But actually, it's pretty rare. It's not as common as you think. And usually, just telling the framework that, oh, by the way, I need to cancel the default. It gets complicated when you conditionally want to cancel the default. But as long as it's something you know ahead of time and be like, oh, yeah, all these defaults I want to cancel for
Dan_Shappir:
You
Misko Hevery:
this
Dan_Shappir:
know
Misko Hevery:
event,
Dan_Shappir:
what you remind me?
Misko Hevery:
that's
Dan_Shappir:
I
Misko Hevery:
easy
Dan_Shappir:
once
Misko Hevery:
to do.
Dan_Shappir:
told the Brendan Icke that maybe he should have created JavaScript
Misko Hevery:
Mm-hmm.
Dan_Shappir:
so that all functions would have been asynchronous by default. And, uh, you know what he said in response? One word, no.
Misko Hevery:
What? Ha ha ha ha!
Dan_Shappir:
Anyway.
Aj:
So it's somebody asked me, well, a couple of times people asked me on the live streams, what if there was a language where the default behavior was a weight? So it's kind of similar question. And that is essentially what go is. And I think that that's kind of the way that Kotlin is as well.
Misko Hevery:
Mm-hmm.
Aj:
Right. So when everything is a weight by default, everything's in the event loop, but everything's essentially a weight by default. a little bit more subtle than that because it's actually just using an event loop to do multiple synchronous things. But still, and if you want something to be quote unquote async, then you you type go and then the function name and then that runs in the background and there's a channel called channels is the mechanism for being able to essentially get the callback for it. But it's a it's more of a job queue type pattern than a tofty bofty goes everywhere kind of pattern. But I think that that I think it could have worked if if it took the kind of go ish slash Kotlin ish approach.
Misko Hevery:
Mm-hmm. Yeah, I totally agree with that. But I mean, JavaScript is what it is, right? Like, this is what we have, so let's
Dan_Shappir:
Thanks for watching!
Misko Hevery:
make it
Aj:
You
Misko Hevery:
work
Aj:
know,
Misko Hevery:
with
Aj:
that's
Misko Hevery:
what we have.
Aj:
a really cute mentality. It's too bad. No one in the JavaScript community believes that.
Charles_Wood:
Ha ha ha
Misko Hevery:
You know, I went through the phase of where, like, I wanted to replace JavaScript with other things. And if you look at the history of it, it all failed,
Aj:
Oh
Misko Hevery:
right?
Aj:
no,
Misko Hevery:
Like,
Aj:
it's
Misko Hevery:
TypeScript
Aj:
been exceptionally
Misko Hevery:
being an exception, because
Aj:
successful.
Misko Hevery:
TypeScript...
Aj:
We now have half of TypeScript as the language and so on and so forth, et cetera, et cetera.
Misko Hevery:
Yeah, but TypeScript is not trying to replace JavaScript. TypeScript basically is a design time only, I disappear
Aj:
Well,
Misko Hevery:
at runtime thing.
Aj:
no, because
Misko Hevery:
And this is why
Aj:
it's gotten
Misko Hevery:
TypeScript
Aj:
into
Misko Hevery:
is successful.
Aj:
the standard. So for example, a lot of the TypeScript stuff, the classes and yada yada, a lot of that C Sharpie type stuff has gotten into the language. And a lot of the Ruby type stuff got into language and so on and so forth.
Misko Hevery:
Sure, but it's
Dan_Shappir:
Yeah,
Misko Hevery:
not
Dan_Shappir:
but
Misko Hevery:
changing
Aj:
Whooooop!
Misko Hevery:
the semantics of
Dan_Shappir:
I'm
Misko Hevery:
the
Dan_Shappir:
going
Misko Hevery:
language,
Dan_Shappir:
to pull
Misko Hevery:
right?
Dan_Shappir:
us out of that rabbit hole
Aj:
Yeah, yeah,
Dan_Shappir:
because
Charles_Wood:
Hahaha!
Aj:
yeah. I don't-
Misko Hevery:
Hahaha!
Dan_Shappir:
I really want to talk more about quick.
Aj:
Right, right,
Dan_Shappir:
So
Aj:
right.
Dan_Shappir:
what
Aj:
I'm just,
Charles_Wood:
Rabbit
Aj:
yeah.
Charles_Wood:
hole or tail spin.
Dan_Shappir:
Yeah.
Misko Hevery:
Thank you. Thank you, thank you. I appreciate that. Yeah,
Dan_Shappir:
So
Misko Hevery:
let's
Dan_Shappir:
talking about
Misko Hevery:
talk about
Dan_Shappir:
quick,
Misko Hevery:
Quik.
Dan_Shappir:
this slicing and dicing of the code that you write, how does that happen? How do you chop this? I assume I write, we didn't even get to the point of how I start a quick project and whatnot, and what's involved in setting that up. And maybe we should discuss this as
Misko Hevery:
Yeah.
Dan_Shappir:
well. But I assume you have a code base that's kind of similar in a lot of ways to a React application or a Vue application or whatever. needs to somehow get
Misko Hevery:
Yeah.
Dan_Shappir:
slice and dice to support this smart delivery that you were describing. So, you know, let's backtrack. Let's say so far I'm really interested in what I'm hearing so far. I want to give Qwik a try. I'm familiar with React maybe. I'm familiar with Vue maybe. How do I go about getting Qwik on my system and how similar or strange is it going to as compared to the framework that I'm familiar with.
Charles_Wood:
I really
Misko Hevery:
Yeah,
Charles_Wood:
want to
Misko Hevery:
so,
Charles_Wood:
talk
Misko Hevery:
yeah.
Charles_Wood:
about the slicing and dicing a little bit here too, because I'm imagining, right, that I click something and the system goes, hold on, I got to figure out what to do, right? And so, yeah,
Misko Hevery:
Hahaha.
Charles_Wood:
so I mean, some of it's going to look, I'm assuming pretty similar to something I'm familiar with, but under the table, it's doing some other work. And yeah, so yeah,
Misko Hevery:
Yes.
Charles_Wood:
kind of both, right?
Misko Hevery:
OK, so let me try to answer all these questions. Let me try to answer all those questions. First of all, quick DX-wise or syntactically-wise, if you look at it and you don't even have to squint very hard, it's going to look just like React. And this is not a coincidence. This is kind of intentional. This is what we're going for. So if you know React, you should have an extremely easy time
Charles_Wood:
but you're
Misko Hevery:
with
Charles_Wood:
the
Aj:
So
Charles_Wood:
angular guy.
Misko Hevery:
quick.
Aj:
when, when you say it looks like
Misko Hevery:
Now,
Aj:
react,
Misko Hevery:
when I
Aj:
you
Misko Hevery:
say
Aj:
mean
Misko Hevery:
sql-
Aj:
that there's no distinction between
Misko Hevery:
Yes.
Aj:
HTML and JavaScript and CSS. It's all just one. Oh.
Misko Hevery:
Yeah, it's JSX and, you know, components are functions and I don't get too depressed.
Charles_Wood:
Ha ha ha!
Aj:
What happened to Web Components?
Dan_Shappir:
Yeah, let's bring Alex
Misko Hevery:
Oh, don't
Dan_Shappir:
Russell
Misko Hevery:
get me started
Dan_Shappir:
on
Misko Hevery:
on
Dan_Shappir:
the
Misko Hevery:
that.
Dan_Shappir:
show to argue about it again.
Charles_Wood:
No, we're talking about quick. We can have the yeah.
Misko Hevery:
Web components are not reasonable.
Charles_Wood:
OK, fair.
Misko Hevery:
That's
Charles_Wood:
Go.
Misko Hevery:
all I'm gonna say. Yes. Okay, so DX-wise, you're gonna find something that's very React-like, but this is where the similarities kind of end. Like your mental model and the way you build applications is gonna kind of be the same, but when I say about squinting, what I mean is you're gonna see a whole bunch of dollar signs at the end of functions. Like in React, you just say, component, function foo, and now foo is a component. It's the same thing, except you have to wrap the function in an additional function called component dollar sign. And the reason for that is because the dollar sign has a special meaning to our optimizer, the piece of code that goes and then moves things around. The optimizer is the thing that breaks up our code base into tiny, tiny pieces. And the nice thing about the way it is designed is that the optimizer is completely clueless about quick. And this is actually a good thing. that it follows and basically says, oh, whenever you see a dollar sign at the end of a function, then take the first argument and make it pull it out into a top level importable thing that is that has an export and, you know, leave behind kind of a reference as to how to how the framework needs to get a hold of this thing. And so the optimizer goes through and basically breaks up your app into teeny tiny pieces. The more the better.
Dan_Shappir:
So
Misko Hevery:
Because, you know, we can talk about prefetching
Dan_Shappir:
just
Misko Hevery:
and
Dan_Shappir:
to
Misko Hevery:
preloading
Dan_Shappir:
verify
Misko Hevery:
later.
Dan_Shappir:
that I understand,
Misko Hevery:
Yeah.
Dan_Shappir:
so essentially the optimizer, what you call the optimizer, is essentially a form of transpilation. That you're taking what happens to be JavaScript code written in a certain way and you're transpiling it into JavaScript code that's written in a somewhat different way.
Misko Hevery:
I think the word yes, but I think the word transpilation is a strong word because transpiler implies that you're modifying the kind of the structure of the functions or the content. Like transpiler from Java to from Dart to Java. That's a transpiler, right? Because the two languages are completely different. But in our case, it's more like a refactoring. Like we go through and we refactor the code by hoisting different functions into top level importable things, right? find a closure such as a click listener and we hoist it into a top level export component foo underscore click equals blah blah blah.
Charles_Wood:
Real quick.
Dan_Shappir:
So effectively, every component
Misko Hevery:
So that's.
Charles_Wood:
Five minutes.
Dan_Shappir:
becomes its own module, as it were.
Misko Hevery:
Sure, but it's even more than that, right? It's a component becomes its own module. Every use client effect becomes its module. Every click listener becomes its module, right? It really gets decomposed into almost like every single function is a separate thing that you can download.
Dan_Shappir:
Interesting.
Misko Hevery:
So that's the hard part. The hard part is breaking the code base into pieces. Once you have too many pieces, then you have to have a problem of like prefetching and making sure that things come together. You know, like you don't wanna download thousand things, right, you wanna download fewer things. And so now the problem of bundling comes in, which is like putting things that are related together. But turns out the bundling problem is relatively easy because that's just essentially, you know, fancy concatenation of strings. The hard part is breaking all this stuff down.
Dan_Shappir:
What do you mean by breaking all this stuff down?
Misko Hevery:
basically creating entry points, creating things that I can dynamically import, that the framework can dynamically import. In other words, QUIC is in the business of creating dynamic modules without the developer having to do anything. Today, if you wanna lazy load something, as a developer, you have to do stuff. You have to put things in a separate file, you have to leave behind a dynamic import, you have to execute some code, Quick wants to do all of that for you without you having to think about it. And it should just naturally, as you write your application,
Dan_Shappir:
By the way, what
Misko Hevery:
Quick
Dan_Shappir:
do you
Misko Hevery:
does
Dan_Shappir:
use
Misko Hevery:
all the
Dan_Shappir:
for
Misko Hevery:
breaking
Dan_Shappir:
the bundling?
Misko Hevery:
up for you. I think we use rollup right now,
Dan_Shappir:
you
Misko Hevery:
but like it's independent. I mean, you could use something else. I think rollup and VEET is what's being used. But that in itself is not a hard requirement.
Aj:
I question on that. What do you, do you happen to know if you want some code that has a, say a slightly different branch between node and browser, so in node it's going to use the crypto module and browser is going to use web crypto and you need to specify which file is there, is there a standard for that that is common? Because what I'm used to is package.json.browser. And I think that web web pack predominantly use that. I thought a few of the other ones used it. Do you know anything about that? Okay.
Misko Hevery:
I do not, but this is a general problem that you want to run different code on a server than on a client. One of the interesting bits about QUIC is that if you look at a lifecycle of a component, the component is instantiated on a server and then continues running on the client and maybe gets destroyed on the client. The lifecycle kind of spans different VMs. And when it gets instantiated on a server, the component can't, for example, talk directly to the database. So there are trickeries inside of QUIC that allow us to do these kinds of things a component, when it's on a server, can have access to other kinds of code that clearly cannot move to the client. So talking to a MongoDB is only a thing on a server. It is not a thing when you're inside of the browser. On the browser, you have to talk through some kind of a REST API that internally then eventually
Dan_Shappir:
And our
Misko Hevery:
talks
Dan_Shappir:
source
Misko Hevery:
to the
Dan_Shappir:
maps
Misko Hevery:
MongoDB.
Dan_Shappir:
good enough to handle all the slicing and dicing that goes about because you really seem to be moving code around
Misko Hevery:
Yes. Yes, they are because, and again, I'm going to come down to, people are afraid of source map because you have a transpiler. And a transpiler not only moves the code around, but also rearranges your variable names and order of things and does all, inserts all kinds of other stuff, right? And so your code, after you're done with the transpiler, is kind of unrecognizable. Whereas if you look at quick, you are just doing a refactoring. We're literally just moving a closure from this location to this other location. And because of that, because you're not creating extra things. There are no extra variables that you didn't see before. There are no names. Within the function, the code doesn't get modified. It just
Dan_Shappir:
So
Misko Hevery:
gets
Dan_Shappir:
you
Misko Hevery:
moved
Dan_Shappir:
said
Misko Hevery:
somewhere
Dan_Shappir:
that
Misko Hevery:
else.
Dan_Shappir:
the framework is kind of similar to react in that you use Components and that the output of the components is described as JSX So I assume it's kind of like the similar model that if I ignore the fact that it's wrapped inside Component dollar it's effectively a function that takes parameters like you said that and and then returns Like actually update the user interface. Uh, what kind of approach do you
Misko Hevery:
Mm-hmm.
Dan_Shappir:
take with that? Is that kind of like a V DOM approach similar to what react does, or maybe a reactive approach similar to what solid does. So how does the JSX become actual DOM manipulations?
Misko Hevery:
Yeah, it's somewhere in between. The quick has to be reactive because otherwise you'll be forced to wake up all the components and then you would be forced to download all the components and so on and so forth. So quick is reactive unlike react, but it's not as fine-grained reactive as solid. So the answer
Dan_Shappir:
It's
Misko Hevery:
is
Dan_Shappir:
funny
Misko Hevery:
somewhere in between.
Dan_Shappir:
when you're saying like it's reactive unlike react
Charles_Wood:
Shots fired!
Misko Hevery:
React is not reactive, right? I still do. But I don't think that's the thing that, it's not shooting shots here. I'm just saying like, you know, reactivity is not part of React,
Dan_Shappir:
And
Misko Hevery:
even
Dan_Shappir:
how
Misko Hevery:
though it's
Dan_Shappir:
do
Misko Hevery:
in
Dan_Shappir:
you
Misko Hevery:
the kind
Dan_Shappir:
handle
Misko Hevery:
of in the name.
Dan_Shappir:
the applicative state? Like, do you have?
Misko Hevery:
Neither is
Dan_Shappir:
Well,
Misko Hevery:
Angular. Angular's
Dan_Shappir:
it depends.
Misko Hevery:
not reactive
Dan_Shappir:
You
Misko Hevery:
either,
Dan_Shappir:
know,
Misko Hevery:
right?
Dan_Shappir:
at the company where I worked at Next, some of our applications are actually written using React and using NXJS. So. Yeah, that's
Misko Hevery:
Yeah, but
Dan_Shappir:
true.
Misko Hevery:
it's not part of the framework, right?
Dan_Shappir:
Yeah.
Misko Hevery:
It's
Dan_Shappir:
Like kind
Misko Hevery:
a library
Dan_Shappir:
of like
Misko Hevery:
you
Dan_Shappir:
more
Misko Hevery:
add
Dan_Shappir:
bigs.
Misko Hevery:
afterwards.
Dan_Shappir:
Yeah.
Misko Hevery:
Like you can make
Dan_Shappir:
Yeah,
Misko Hevery:
React
Dan_Shappir:
exactly.
Misko Hevery:
kind of reactive
Dan_Shappir:
So,
Misko Hevery:
through
Dan_Shappir:
so
Misko Hevery:
MobX,
Dan_Shappir:
what do you do?
Misko Hevery:
right?
Dan_Shappir:
So talking about that.
Charles_Wood:
I'm gonna stop us real quick and let Steve do his picks so he can take
Dan_Shappir:
Ah,
Charles_Wood:
off
Dan_Shappir:
cool.
Charles_Wood:
and then we'll let AJ do his picks. I have a hard stop at noon, so
Dan_Shappir:
I could go
Charles_Wood:
noon
Dan_Shappir:
on forever.
Charles_Wood:
mountain time.
Dan_Shappir:
I'm having the time of
Charles_Wood:
Oh,
Dan_Shappir:
my
Charles_Wood:
I
Dan_Shappir:
life.
Charles_Wood:
know.
Steve:
We
Charles_Wood:
Well,
Steve:
know.
Charles_Wood:
and there's so much good stuff here. Anyway, go ahead, Steve.
Steve:
Okay, so let's see, pick dad jokes of the week. Gotta go back in through my daily archive here. Sorry, delay, delay, delay, delay. So, you know, we've heard this, people say this when they get older, say when I was young, I was poor and I struggled. And after years of struggle, I can say I'm no longer young. Right.
Misko Hevery:
You know, when is a dad joke, when is a joke a dad
Steve:
I know
Misko Hevery:
joke?
Steve:
this and I can't remember the answer. Pat parent,
Misko Hevery:
when the
Steve:
yes,
Misko Hevery:
punchline is
Steve:
there
Misko Hevery:
apparent.
Steve:
we go. Thank you, thank you. So Dan, you've mentioned a few times that you're going to Australia soon for a conference.
Dan_Shappir:
Not so soon,
Steve:
So,
Dan_Shappir:
but yeah.
Steve:
in a few months, sometime, anyway. So do you know why Australians laugh at flightless birds?
Dan_Shappir:
I have no idea.
Steve:
they find them emusing.
Dan_Shappir:
Okay...
Steve:
And
Misko Hevery:
Ha ha ha
Steve:
then finally,
Dan_Shappir:
Thanks for watching!
Steve:
did you hear about the family that died of random head injuries?
Dan_Shappir:
you
Steve:
I grew up just a stone's throw away from them where they lived, crazy.
Charles_Wood:
me.
Dan_Shappir:
That was a bit dark.
Misko Hevery:
I'm your
Dan_Shappir:
That's
Misko Hevery:
best
Dan_Shappir:
all
Misko Hevery:
audience
Dan_Shappir:
I have to
Misko Hevery:
here.
Dan_Shappir:
say.
Steve:
Yes, yes, that was rather dark. But yes, usually the guests are the panelists just like, okay, here we go again. So anyway.
Dan_Shappir:
Ha ha ha ha!
Charles_Wood:
I need to get some sound effects that are awwwwww
Steve:
Oh, I know. We'll see, there's a, the nice thing about Riverside is you can upload custom sound effects, you just need to find them.
Charles_Wood:
Yes you can.
Steve:
So yeah, there's a few that I want to upload. That would be fun for sure.
Charles_Wood:
Send him to Michaelis, she'll get
Misko Hevery:
I
Charles_Wood:
him
Misko Hevery:
have
Charles_Wood:
uploaded.
Misko Hevery:
a question.
Charles_Wood:
Anyway.
Steve:
Okay.
Misko Hevery:
How do you measure functions?
Steve:
heard it.
Aj:
By their dot...
Misko Hevery:
in parameters.
Steve:
Very good. I just...
Aj:
That's that that's true.
Steve:
I gotta tell you.
Charles_Wood:
Don't encourage him. Mischko, don't.
Steve:
I love it when the guests bring the dad jokes.
Misko Hevery:
Hahaha
Steve:
It happens more and more. It's so fun. So thank you, Mishko, for that.
Charles_Wood:
All right. Any other
Misko Hevery:
anytime.
Charles_Wood:
picks or should we throw it to AJ?
Steve:
I am done.
Charles_Wood:
Okay. AJ.
Aj:
All right, I got a short list today. So first I'm gonna pick an oldie but a goodie, Julian Smith's Malk. It's a little comedy skit. Feels almost like a throwback to E-Bomb's world, but the point of it is that they can't figure out how to pronounce milk correctly. And secretly, or not so secretly, that milk is called moque and so I asked them if they want moque and whenever they say milk I correct them and tell them that it's moque but we still do milkshake is milkshake
Dan_Shappir:
Isn't it so great being a parent that you can create all sorts of funny hangups with your kids? Like, you know, you're scarring them for life, but it's so funny.
Aj:
Yeah, I'm just, I'm really hoping this becomes a conversation at someone's house that's around my age and they get the joke and, you know, really think I'm a clever dad, but, uh, also along those lines, I have a bottle of maple syrup that's in a glass jar and we just refill it, but it's dad's special maple syrup. And no one's allowed to have any only dad, but it's just the regular maple syrup that everybody has. Uh, and then, uh, also. I'm picking web installed.dev again. I mean, I should pick that every week, but
Dan_Shappir:
Yes you should.
Aj:
we have updated it so that now there is webby.sh and webby.ms. And the neat thing about that is that now with the introduction of those, we've paved a way for non-dynamic script distribution. So one, your URL is a little bit short, when you do curl HTTPS colon slash slash webby dot SH slash node pipe SH. Oh, that's the other thing is that it's now post six compliant shells. So it should work in all of the Docker environments and we should soon have BSD support, but the, so, so now it's not dynamic anymore. So webby dot SH will always give you the post six script and webby dot So you've got a little bit less to type. The the Microsoft version no longer needs a little bit of extra flag for the Microsoft user agent string. And I just think that this is a pretty awesome update and a shout out to my my co author on this Ryan Burnett for having he kept on pressing me. We need to get Webby SH. We need to get Webby SH. And we did. Now we've got it and it's, it's up and running. And for those that don't know it web installed, I dev is basically the quickest, fastest, most secure way to install your developer tools. That's guaranteed to work every time in your face. The end.
Charles_Wood:
Awesome. All right, well, I'm gonna derail us back onto the episode and we'll have the editor just move things around. I think we really only have time for one more thing and I'd like to kind of dive into this and then if we do have time, we can go back to what we were talking about before. But how do people get started with QUIC?
Misko Hevery:
It's very easy. We have a command line tool. So it's npm create quick at latest. Just follow the prompts. It will set up a nice Quick City application. Quick City is our meta framework. So you can have routing and fetching data and all the other stuff that comes with it. And I think they're kind of a big difference. I was talking to people, and I'm trying to explain how quick is different. And I think it's kind of like the difference normal companies and then highly vertically integrated companies like SpaceX, Apple, and so on and Tesla, right? And because these highly integrated companies, they can make sure that all the pieces work together seamlessly. And so QUIC is the same kind of a thing, right? QUIC's job is to worry everything from server-side rendering, bundling, optimization, prefetching, styling, and of course rendering on the client. own the whole thing end to end, we can basically do a better job than like if you try to glue bunch of independent tools
Dan_Shappir:
Thanks for watching!
Misko Hevery:
together. Because there's always something somewhere that is just doing things just slightly off that's preventing
Dan_Shappir:
So question
Misko Hevery:
you from
Dan_Shappir:
about that, you
Misko Hevery:
getting
Dan_Shappir:
mentioned
Misko Hevery:
it just
Dan_Shappir:
routing.
Misko Hevery:
right.
Dan_Shappir:
I should have asked before, is quick and effectively an SPA and MPA both, is it a developer choice? Is it your choice? Like, how does it work?
Misko Hevery:
Yeah, so it's funny because once you become resumable, this whole MPa SPA difference kind of sort of disappears. So we have examples, like for example, if you don't have JavaScript running, then obviously it's just like MPa, you're navigating within static pages. But if you have JavaScript running, we have a link component that we can intercept all the Ahrefs and automatically turn them into client-side routing essentially. you become an SPA in that particular case. So you can have a both of best of both worlds. And so it's even hard to kind of even discuss like, is it an MPI or is an SPA because the MPI-SPA distinction in a lot of ways is because of how we got here. And once you have, you know, server-side, once you have reasonability, it's even hard to even talk about like, well, is it, which
Dan_Shappir:
Well,
Misko Hevery:
one is it?
Dan_Shappir:
there were motivations for SPAs in a sense, putting aside the technological or DX motivations. There were UX motivations around things like doing some sophisticated transitions when moving between pages or retaining parts of the UI,
Misko Hevery:
Yeah.
Dan_Shappir:
what Remix, I think, called, they have a term for that, like inner, like partial. I forget the term they use. That when you're moving between pages, you don't need to replace the entire page. You can just replace portions of the page.
Charles_Wood:
Mm-hmm.
Dan_Shappir:
But.
Misko Hevery:
So what if you could make the decision on per link? What if you could say like, this link should be an MPA and this one should be an SPA? Like that would open up a whole new set of worlds, right? Right now, when you have an MPA
Dan_Shappir:
Mm-hmm.
Misko Hevery:
app, you can't have an SPA app and verse versa, right? But if you do it kind of on per link, or maybe even on like, oh, well, initial navigation is gonna be MPA here, but then later on it becomes like, all of these things become a developer's choice depending on what you need best in this particular situation, rather than an architectural decision
Dan_Shappir:
Just so I remember
Misko Hevery:
do
Dan_Shappir:
the term I
Misko Hevery:
at
Dan_Shappir:
think
Misko Hevery:
the very,
Dan_Shappir:
that
Misko Hevery:
very
Dan_Shappir:
they
Misko Hevery:
beginning.
Dan_Shappir:
use is nested routes or something like that but basically what you're saying is that Well,
Misko Hevery:
Yeah.
Dan_Shappir:
you know in many cases It actually does make sense to do much of the navigation service side because you get the benefit of delivering Pre-created static HTML really which can be done really quickly these days Thanks to content delivery networks. So so yeah, if and and then again you're you're avoiding replacing the built-in browser router, which is, you know, kind of the best router out there if you can use it. Yeah, interesting. I need to think about that. And another thing. I actually kind of know the answer to that, but I'll ask it of you nonetheless. How do you JavaScript is delivered quickly. I mean, if whenever I click a button, I need to do a round trip to the server, then that potentially introduces like a 300 millisecond delay just to fetch the data, even if the data is really small, just because of the round trip. How do you work around that?
Misko Hevery:
Mm-hmm. Yeah, the answer
Charles_Wood:
Mm-hmm.
Misko Hevery:
is prefetching. And it's a topic we could
Charles_Wood:
Yeah.
Misko Hevery:
go into. It's a pretty deep topic. But the short answer is, the short of it is that QUIC downloads the code that it might need. But it's very good at saying, yeah, but I don't need all the static
Dan_Shappir:
Thanks
Misko Hevery:
components,
Dan_Shappir:
for watching!
Misko Hevery:
et cetera. So in the worst, worst situation, the QUIC will prefetch all the same application code But that was a situation essentially almost non-existent in real life. So in real life, the Quick will prefetch a tiny fraction of the overall app. And then the second advantage is that even if the code is prefetched, it's not actually executed, right? So the existing frameworks need to fetch the code and execute it in order to recover the state. Quick doesn't have to do the execution
Dan_Shappir:
Thanks for watching!
Misko Hevery:
bit until you actually interact with it. And so there's a huge savings
Dan_Shappir:
I did
Misko Hevery:
even
Dan_Shappir:
ask
Misko Hevery:
though
Dan_Shappir:
it as
Misko Hevery:
if
Dan_Shappir:
kind
Misko Hevery:
you
Dan_Shappir:
of
Charles_Wood:
All
Dan_Shappir:
a
Charles_Wood:
right.
Dan_Shappir:
lead.
Misko Hevery:
have to prefetch that.
Dan_Shappir:
One, one thing, Chuck, I promise really short, just to mention, uh,
Charles_Wood:
Thanks for watching!
Dan_Shappir:
that, uh, I
Misko Hevery:
Ha ha
Dan_Shappir:
actually
Misko Hevery:
ha!
Dan_Shappir:
asked that as kind of a leading question because not in the context of this episode, as we've likely run out of time, but one day, maybe some other context, I need to have this argument with you, it should be preload rather than prefetch you should be using preload rather than prefetch.
Misko Hevery:
And you're probably right because prefetch is broken in the browsers, but that's a separate discussion.
Charles_Wood:
All right, I've got to push us to PIX because I have a hard stop in five minutes. Dan, do you want to start us with PIX?
Dan_Shappir:
Sure, why not? Okay, so my first pick is I just finished watching The Sandman on Netflix. And unlike many others, I've never read the comics. I'm not a big comics person, you know. I never got to, I never understood why all the supposed nerds and geeks on the Big Bang Theory TV show on. But be that as it may, I watched it on Netflix. And on the one hand, I liked it. It was enjoyable. But on the other hand, there was a problem for me with it is that I didn't really identify with any of the characters there. And that kind of, it's a problem, you know, a series doesn't really suck you in if you don't kind of identify at least with some of the characters on the show. that at least for me, but be that as it may, watched it all the way through and it was a nice distraction nonetheless. So that would be my first pick. My second pick is, you know, we were picking, so like I said I'm not so big on comics but I do like fantasy and science fiction books and novels and we were doing, we were picking some of those in recent episodes and I don't think I don't think this one was actually ever mentioned. So I would like to give a big shout out to the Gentleman Bastard series by Scott Lynch. It's an excellent series for people who are into these types of stories of books. They are often considered some of the best fantasy books ever written. They're really different in that their setting is kind of different in most fantasy books, they're more like oriented towards, you know, like what happens in cities and the heroes of the books are actually kind of thieves. So it's really interesting and I highly recommend it. So that would be my second pick. And my third and final pick is that same pick I pick each and every time. You've probably gotten used to it, but I refuse to stop. And that's the ongoing war in Ukraine, which really is so depressing. never-ending and you know, it doesn't seem like it's getting better. It's only seems to be getting worse and We just need to to have it, you know Forefront of our thoughts and anything that anybody can do to help well They should and those would be my my picks for today
Charles_Wood:
Awesome, I'm going to go rather quickly. First of all, we are doing a JS remote conf in October. So if you're looking for a conference that you can attend remotely, we are trying to bring in some of the hallway track and things like that. So, you know, we'll have tables that you can kind of log on to and do a video chat and what have you. And we're going to try and have our speakers around some of the time so you can chat with them. There's also a networking session every day and remoteconf.com. And then I'm gonna do some shout outs about some other stuff. So one of the things that I look at are for tools for things that I need is AppSumo. And so in the past I've used an app called Bonjoro to kind of send video messages to people and they had a lifetime subscription to a service the same thing and it was like 60 bucks. And so, you know, instead of paying the monthly fee, which was, I think, around 60 bucks, I paid once and now I get to use it as much as I need to. So I'm really digging that and then... Yeah, I think that's kind of it. I'm gonna skip the board game pick this week just because I didn't prepare and I need to get us off the call. So yeah, Mishko, what are your picks?
Misko Hevery:
You know, we were talking about how people behave, etc. and so I kind of like human psychology. And David Kahneman, I believe the guy's name is, he's Israeli, he got a Nobel Prize actually for his work. He did some amazing work, and especially the book, Thinking
Charles_Wood:
Mm-hmm.
Misko Hevery:
Fast and Slow. It's like, I consider it your user's manual to your own brain. And a lot of fascinating stuff is in that book. So if you ever have a chance to read it, it's a very thick book, very big book, some amazing stuff is in there. You should definitely, everybody should read it.
Charles_Wood:
Awesome. Yeah, that one's been on my list for a while. I
Dan_Shappir:
Thanks
Charles_Wood:
just
Dan_Shappir:
for watching!
Charles_Wood:
haven't quite gotten around to it. Mishko, if people want to check you out or check out quick, learn a little bit more about what we've talked about today. Where do they find all that stuff?
Misko Hevery:
So to check out QUIC, just go to quick.builder.io. From there,
Dan_Shappir:
you
Misko Hevery:
you can find links to our community where you can join our Discord and so on. And of course, I'm on Twitter as mhevery. And yeah, reach out. And I would love to talk to you about
Charles_Wood:
Awesome.
Misko Hevery:
it.
Charles_Wood:
Well, thanks for coming. This was awesome. Sorry to make you do it from the hotel, but
Misko Hevery:
Thanks for having
Charles_Wood:
yeah.
Misko Hevery:
me. That's
Charles_Wood:
All right, well, I'll
Misko Hevery:
fine.
Charles_Wood:
probably send you an email, see if we can get together while you're in town. And until next time, folks, Max out.
Dan_Shappir:
Bye!
Misko Hevery:
See you.
Qwik with Misko Hevery - JSJ 549
0:00
Playback Speed: