Skip to content

Commit ba8250b

Browse files
committed
chore: more accuracy
1 parent cab8417 commit ba8250b

File tree

1 file changed

+12
-14
lines changed
  • packages/docs/src/routes/(blog)/blog/(articles)/qwik-1-14-preloader

1 file changed

+12
-14
lines changed

packages/docs/src/routes/(blog)/blog/(articles)/qwik-1-14-preloader/index.mdx

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ In comparison, the other frameworks need to execute at least all of the visible
4545

4646
In effect, this means that TTI on Qwik apps can often be as fast as ~5s on a slow 3G network connection, even for very complex applications. With hydration on the other hand, TTI often reaches ~20s on slow 3G on simple websites and 60s or more on more complex applications as it increases proportionally to the amount of components that need to hydrate.
4747

48-
### A long standing “Buffering” issue
48+
### A long standing “buffering” issue
4949

5050
In Qwik 1.11.0 and 1.13.0, we fixed some long lasting bugs that were leading to “under-prefetching” and “over-prefetching under certain conditions. With those fixes, we made sure that all and only the bundles required for the user interactions available on a page are prefetched, therefore preventing any sort of network delays.
5151

@@ -60,7 +60,7 @@ Thankfully, using a service worker isn’t the only way we can prefetch and cach
6060

6161
In Qwik 1.14, we've transitioned away from using a service worker in favor of a solution leveraging [`<link rel="modulepreload">`](<https://devdocs.io/html/attributes/rel/modulepreload>) as the new default.
6262

63-
The solution consists of a small script called the “Qwik Preloader”. Once it is downloaded on the client, it adds the `<link rel="modulepreload" href=”my-bundle.js#segment123456”>` to the html `<head>`, which tells the browser to preload and buffer the corresponding JavaScript bundles.
63+
The solution consists of a small script called the “Qwik Preloader”. Once it is downloaded on the client, it adds the `<link rel="modulepreload" href=”my-bundle.js#segment123456”>` to the html `<head>`, which tells the browser to preload and buffer the corresponding JavaScript bundles.
6464

6565
By doing so, we not only get rid of any startup penalty, but also make any interaction on Qwik components absolutely instant once the bundles for it have been preloaded, even on devices with poor CPUs 🚀
6666

@@ -80,11 +80,11 @@ On our tests on a pretty used up Xiaomi note 7 pro, the delays only reached ~100
8080
</figure>
8181
</div>
8282

83-
If you look closely at the two screen recordings above, you will notice that the text is first marked with an underline when focused, and then the Accordion opens the selected item. But the difference is that with the service worker, the first interaction on the Accordion component is a little delayed. With modulepreload, all interactions are instant. (You might want to set the video to 0.5x speed to better see the difference.)
83+
It is hard to feel on a screen recording, but if you look closely at the two recordings above, you will notice that with the service worker, the first interaction on the Accordion component is a little slower. With modulepreload, all interactions are instant. (You might want to set the video to 0.5x speed to better see the difference.)
8484

85-
The reason why there is such a delay with the service worker on devices where the CPU is slow is because retrieving a chunk from the CacheControl with the Service Worker doesn't always take 1ms, but sometimes 10ms or more. So for example to retrieve 15 bundles on click, an old device can in total take 150ms or more instead of 15ms.
85+
The reason why there is such a delay with the service worker on devices where the CPU is slow is because retrieving a chunk from the CacheControl with the Service Worker doesn't always take 1ms, but sometimes 10ms or more. So for example to retrieve 15 bundles on a first click, an old device can in total take 150ms or more instead of 15ms. Once the bundles have been executed and live in the browser memory or disk cache, the interactions are instant.
8686

87-
In contrast, modulepreloaded bundles are downloaded and compiled by the browser. They live in memory and are ready to be served instantly on request. So if all the bundles required for an interaction have been preloaded, the interaction will be instant. There is no network request, no service worker interception, no retrieving of bundles from the CacheStorage.
87+
In contrast, modulepreloaded bundles are downloaded and compiled by the browser. They live in memory and are ready to be executed instantly on request. So if all the bundles required for an interaction have been preloaded, the interaction will be instant. There is no network request, no service worker interception, no retrieving of bundles from the CacheStorage.
8888

8989
Here’s a small Excalidraw to illustrate the difference:
9090

@@ -95,28 +95,26 @@ Here’s a small Excalidraw to illustrate the difference:
9595
The Service Worker had to be registered before any prefetching could happen. Not only did this negatively affect TTI and [TBT (Total Blocking Time)](https://developer.chrome.com/docs/lighthouse/performance/lighthouse-total-blocking-time#:~:text=Blocking%20Time%20audit-,What%20TBT%20measures,Paint%20and%20Time%20to%20Interactive.) a little, but it also prevented Qwik from reprioritizing bundles if the user interacted before the registration.
9696
<Image src={serviceWorkerRegistrationPenalty} alt="Service Worker registration penalty" />
9797

98-
With modulepreload, we can now start preloading bundles **as soon as the browser is idle**. This means [FCP (First Contentful Paint)](https://web.dev/articles/fcp) and [LCP (Largest Contentful Paint)](https://web.dev/articles/optimize-lcp#:~:text=Largest%20Contentful%20Paint%20(LCP)%20is,is%20rendered%20within%20the%20viewport.) remain as fast as possible, and slightly better TTI and TBT scores because we can prioritize buffering the bundles needed for a user interaction as soon as the page is visible to the user.
99-
### Even better prioritization based on heuristics
98+
With modulepreload, we can now start preloading bundles as soon as the html is rendered. The default makes sure that [FCP (First Contentful Paint)](https://web.dev/articles/fcp) and [LCP (Largest Contentful Paint)](https://web.dev/articles/optimize-lcp#:~:text=Largest%20Contentful%20Paint%20(LCP)%20is,is%20rendered%20within%20the%20viewport.) remain as fast as possible, and slightly improves TTI and TBT scores over the service worker.
10099

101-
Reprioritization is a powerful feature - allowing Qwik to change the “buffering” order based on the user’s actions.
100+
### Even better prioritization based on heuristics
102101

103-
But it’s even better if the framework can already know ahead of time what to “buffer” in which order.
102+
A powerful feature that already existed in the Qwik service worker that is also implemented in the Qwik Preloader is the ability to “**reprioritize**” bundles on user interaction. If some bundles are at the bottom of the preload queue, we can tell the browser to start preloading them right away. This means that no matter what, TTI remains constant as it doesn't increase proportionally to the number and size of bundles that need to be loaded.
104103

105-
Qwik can now out of the box have better guesses about bundles that are more likely to be needed with other bundles, as they are “related”.
104+
But it’s even better if the framework can already know ahead of time what to “buffer” in which order. Qwik can now out of the box guess which bundles are more likely to be requested by the user based on what is most likely to be interacted with first.
106105

107-
It is not perfect (for that we have [Qwik Insights]( which requires a database), but it’s quite a bit better than before! Qwik now gives “better scores” to more important things like “user events” or “above the fold” components over things it assumes are less important.
106+
It is not perfect (for that we have [Qwik Insights]( which requires a database)), but it’s quite a bit better than before! Qwik now gives “better scores” to more important things like “user events” or “above the fold” components over things it assumes are less important.
108107

109108
For example, Qwik assumes that the search input on the navbar above the fold is more likely to be used sooner than a Button on a footer far down below the fold, but if the user scrolls and clicks the button on the footer, Qwik will re-prioritize its bundles before the search input.
109+
110110
### Faster CI times
111111

112112
Thanks to the performance improvements above, our full CI tests on [qwik.dev](<http://qwik.dev>) now run in about ~10 minutes instead of ~15, and most of it can be attributed to the E2E tests which do many renders in a browser and were therefore bootstrapping a lot of service workers.
113113
## **How do I get all of this Goodness?** (**Migration steps)**
114114

115115
Migrating to Qwik 1.14.0 with the Qwik Preloader as the new default should not require much effort on your end, but there are a few changes you should know about.
116116

117-
Currently 93% of browsers support “modulepreload”, which wasn't the case when we started using the service worker for “buffering”.
118-
119-
For non-supported devices, the preloader will fallback to `<link rel=preload>`, which doesn't compile the code in advance but still works and brings the support to 100%. In effect, you can rest assured all your users will experience lightning speed regardless of their device.
117+
Currently 93% of browsers support “modulepreload”, which wasn't the case when we started using the service worker for “buffering”. For non-supported devices, the preloader will fallback to `<link rel=preload>`, which doesn't compile the code in advance but still works and brings the support to 100%. In effect, you can rest assured all your users will experience lightning speed regardless of their device.
120118

121119
Here are the Steps you need to follow:
122120

0 commit comments

Comments
 (0)