- Date
- Author
- georges-gomes
Optimizing Swyx's personal site
On January 31th 2023, 15 days ago, Swyx updated his personal website for 2023.
Following Swyx mantra: Pick Up What They Put Down, I decided to see if I
can improve the performance of his website using jampack
π
Who is Swyx?
Shawn Wang (aka @swyx) is a Writer, Speaker and Developer Advocate.
He is best known for his essay about learning in public that includes βPick Up What They Put Downβ.
You can learn more about him in his bio.
If you donβt follow him yet, you should π
Swyxβs Personal site
The 2022 version of the website was a rewrite in SvelteKit and TailwindCSS.
This 2023 millesime is an upgrade to SvelteKit 1.0 released in Mid-December 2022.
Letβs build our own copy
Iβm gonna build my own copy of the Swyxβs site and host it on Netlify. This way Iβm not impacted by any of what could be going on in production.
- Clone here: https://github.com/divriots/swyxdotio
- Hosted here: https://swyxdotio-original.netlify.app
Checking performance
Original on https://swyx.io
SpeedIndex: 4.603ms
LCP: 5.108s
CLS: 0
TBT: 1.315s
76 requests
Download: 2.575MB
My copy on https://swyxdotio-original.netlify.app
SpeedIndex: 4.308s
LCP: 4.897s
CLS: 0
TBT: 1.263s
76 requests
Download: 2.575MB
Looks close enough.
Request waterfall
Observations
- LCP is bad at 4.8s. Should be below 2.5s for βGOODβ score.
- CLS is at 0. Perfect.
- TBT is at a woping 1.2s - It should be below 0.2s I think π€
- The HMTL page is a massive 4MB uncompressed (1.3MB compressed). This looks way to big. Why?
- It take a full 3 seconds for the assets (
CSS
andJS
) to start downloading⦠Why?
Okay! Letβs go optimizing!
- Optimized branch will be here: https://github.com/divriots/swyxdotio/tree/jampack
- Optimized branch will be deployed here: https://swyxdotio-jampack.netlify.app
First surprise
There is no .html
files on the output build π. jampack
is not going to do much without HTML files π« .
jampack
can minify the 60 images present in the output build but thatβs about it.
There is no .html
because SvelteKit is configured to use the
Netlify adapter to render in functions.
This is actually not a static siteβ¦ π€¦ββοΈ
I will not give up so easily!
Letβs turn it into a static site!
Apparently, I can swap @sveltejs/adapter-netlify
with @sveltejs/adapter-static
and have a static site
on the output.
Not an easy task - some things are specifically dynamic routes.
After a long battle with SvelteKit, I focused by efforts on rendering just the home page.
Performance result
SpeedIndex: 1.224s
LCP: 2.508s
CLS: 0
TBT: 1.123s
76 requests
Download: 2.575MB
Observations
- LCP is very close to 2.5s.
- CLS is at 0. Perfect.
- TBT is unchanged.
I guess this had to be expected. Without browser cache (as used here in benchmarks), the original site had to generate the HTML page by functions. Kickstarting the function and generating a 4MB HTML is not a blazing fast task.
The new static version of the page shows tremendous performance benefits.
Letβs run jampack
out-of-the-box
Install jampack v0.9.1
npm i -D @divriots/jampack
Add to build
"build": "vite build && jampack ./build",
jampack
output
PASS 1 - Optimizing
βΆ index.html
β <img> [1/1]
Done: 90.38ms
PASS 2 - Compressing the rest
β 69 files | 15.30 MB β 14.66 MB | -647.94 KB
Done: 1.123s
Summary
ββββββββββββββββ€βββββββββββββ€ββββββββββββ€βββββββββββββ€βββββββββββββ
β Action β Compressed β Original β Compressed β Gain β
ββββββββββββββββΌβββββββββββββΌββββββββββββΌβββββββββββββΌβββββββββββββ’
β jpg->jpg β 1 / 1 β 24.98 KB β 21.69 KB β -3.30 KB β
β .js β 29 / 32 β 228.31 KB β 226.59 KB β -1.72 KB β
β .css β 3 / 3 β 45.04 KB β 42.96 KB β -2.08 KB β
β .png β 8 / 13 β 1.85 MB β 1.84 MB β -10.61 KB β
β .jpeg β 5 / 5 β 587.34 KB β 444.34 KB β -143.00 KB β
β .jpg β 5 / 5 β 3.06 MB β 2.58 MB β -486.99 KB β
β .html β 1 / 1 β 3.93 MB β 3.93 MB β -242.00 B β
β .xml β 0 / 1 β 246.00 B β 246.00 B β β
β .ico β 0 / 1 β 14.73 KB β 14.73 KB β β
β .txt β 0 / 1 β 191.00 B β 191.00 B β β
β .webmanifest β 0 / 1 β 426.00 B β 426.00 B β β
β .json β 0 / 2 β 3.77 MB β 3.77 MB β β
β .md β 0 / 1 β 89.00 B β 89.00 B β β
β .gif β 0 / 1 β 1.81 MB β 1.81 MB β β
ββββββββββββββββΌβββββββββββββΌββββββββββββΌβββββββββββββΌβββββββββββββ’
β Total β 52 / 69 β 15.30 MB β 14.66 MB β -647.94 KB β
ββββββββββββββββ§βββββββββββββ§ββββββββββββ§βββββββββββββ§βββββββββββββ
Only one index.html
processed and a few assets minified.
Not much to do on this page. The avatar image of Shawn has been transformed to progressive JPEG to optimise CLS - shaving 3.3KB in the process. The rest is in situe compression and minification.
Performance result
SpeedIndex: 1.321s
LCP: 2.449s
CLS: 0
TBT: 1.150s
77 requests
Download: 2.592MB
Observations
- Not a tremendous improvement over pure static.
- But we manage to get LCP below 2.5s :)
- Mobile phone users with low bandwidth will benefit most from the progressive JPEG.
- There are way too many
youtube.com
requests from 4 embed after the fold. We should make them load lazy.
Letβs add lazy <iframe>
to jampack
The Youtube embeds are <iframe>
s. They are located way below the fold. There is no point in
loading them eagerly. Letβs free some resources by loading them lazy.
Jampack
release v0.9.3
now adds loading="lazy"
to iframes below the fold.
Performance results
π€―π€―π€―π€― Absolutely no impact at all.
<iframe>
s are still loaded eagerly.
But Why?!
Because SvelteKit re-hydrate the whole page that has been pre-rendered and replaces ALL content.
<iframe>
are no longer lazy when Javascript is loaded.
Everything that jampack
setup to load in lazy is reverted immediately to load eagerly.
But I donβt need Javascript for this page!
Letβs try to turn hydration off for this page.
New Performance results
SpeedIndex: 1.321s
LCP: 0.677s
CLS: 0
TBT: 1.204s
56 requests
Download: 1.250MB
WOW now we are talking!
Observations
- By removing Javascript, the light/dark mode switch is broken.
- Otherwise the entire page is as the original.
- The browser keep loading YouTube data because it has nothing else to do!
- The HTML page is reduced from 4MB uncompressed to 20KB uncompressed (6KB compressed).
- Interesting to see how SvelteKit hydration is taxing the HTML page.
Close thoughts
Thatβs enough for today π
Try yourself:
Reminder: Only the homepage works properly
- Official website: https://swyx.io
- Copy of the official website: https://swyxdotio-original.netlify.app
- Jampacked website: https://swyxdotio-jampack.netlify.app
Iβm sad I couldnβt work with more pages. There are very good performance improvements
in the blog post pages. Specially with images. Indeed, the blog uses GitHub issues as a CMS.
Itβs very clever but images are very large and slow. jampack
would have done miracles here.
I will probably come back to it later when Iβm able to build more static pages with SvelteKit.
Jampacked website code branch: https://github.com/divriots/swyxdotio/tree/jampack
Released
jampack 0.9.2
jampack 0.9.3