It is great to be here in London again. I just love the talks so far. Halfstack is just a little bit di erent than most other conferences. There is room for some topics you wouldn’t see anywhere else. And I love that.
But now something serious. Dylan, the creator of HalfStack started a new company and that means he is very very busy. So I decided to help him out and optimise the Halfstack website for him. Free of charge.
So, the first thing I asked myself, is where do I start. So I decided to take the scientic approach and do a comparison.
Of course you need a good large, representative data set to get significant results. But I did not have that much time, so I just picked two. My own website and some random other website. And you can plainly see that that website is clearly a lot slower. 80 times slower. And it has more than a 1000 requests compared to my 11. Lots of trackers and lots of images.
And we can also tell that images require requests to fetch them from the server. No matter how well optimised the size of your images are, they still require a request.
Combine these two premises and we have a conclusion that by inlining images we can make a website faster.
Now back to our website, you’ll notice there is definitely room for improvement.
But nowadays we have high resolution screens. So we need at least a 2x image for the logo to look good. Maybe even 3x, but let’s do fidelity capping, just like Andrea and go for 2x. This logo requires a request. And on every page. So let’s try to inline that image so we avoid that request.
Well, an image is just a raster or grid of coloured pixels.
So, a table with a cell for each pixel. Almost 150 thousand cells. And because we don’t want to mix styles with content we are going to use…..
That is 16.7 million image files x 88 bytes = 1.35 GB. But about 80% along the way of generating these images something in the filesystem broke. Apple claims you can put 2.1 billion files in a directory. But that is not true. Your Mac will crash. It will fail to boot and you need to start it up in rescue mode do disk repair and delete the whole directory from the Terminal before you can use your computer again.
And it works….. The HTML is just 7.1 MB and it “only” took 9 seconds to render. But still 1 request. So we can do better.
Of course that means our HTML will be bigger. And rendering times will go up too. But now we have zero requests…. We are done!
Well… we could just use HTML4 attributes like width and height to replace our spacer image. HTML4 is just better than HTML5 that way.
Problem one. There is no documentation. Not in the spec. Not on MDN. So I headed over to the trusty W3schools and yup. All the info I needed.
An iframe that shows a document with frame sets and 144.000 frames. And HTML documents for each individual color. What can go wrong?
Yeah, lessons learned from spacer images. Let’s just inline those documents.
× 144.000
So let’s try a different approach. CSS. You can even recreate paintings with just CSS, so our logo should be easy.
Absolute positioning. A div with an id for each pixel. And using CSS to set the position and the color.
So let’s try pseudo selectors. First pixel is a single ::after. Second is two times :after. Third pixels is :after:after:after. And so on.
Well, that didn’t work. I actually ran into an issue with generating. The file is 37 GB big. And even though the maximum string length in Javascript is 8192 Terabytes, V8 can’t handle strings that long. The positive thing is, gzipped it is only 62 MB….
After 21 minutes it stopped rendering. Not sure what the problem is with the rendering, but without nth-child and back to Id’s it still took 59 sec but at least it looks correct. If I remember correctly from Andrea’s talk, that is a bad score for Largest Contentful Paint on the Core Web Vitals. Grid is slower than absolute positioning.
But you can add multiple shadows on the same element. And you can position each individually and give each it’s own color…
So this box-shadow CSS property is 3 MB big. It has 139.999 shadows in one declaration. But that is only 380 KB gzipped and rendering took only 0.1 second. So this is. Box Shadows!
But we have a lot of dark blue here. What if we don’t include that in the shadows itself, but just set a background color on its parent.
40 ms!
We’ve gone from 18MB to 604KB and from 13 seconds to 40 ms. A big improvement. Success! And while 604 KB still sounds a lot. It is still less than the average size of a banner ad on the website of the Express. And I kid you not, they spend more time waiting for the server to respond than we spend to render the image.
So what are the key takeaways from this talk. What are the things that you can use in your projects next week.
Use divs for everything except when you can use shadows, of course.
The maximum length of a string is nine quadrillion, seven trillion, one hundred ninety nine billion, two hundred fifty four million, seven hundred forty thousand, nine hundred ninety one bytes.
And w3school is much more complete than mdn. Mdn is good for that fancy new stuff, but if you want the good stuff like frames, blink and marquee, you’ll need w3schools.
And don’t use 144.000 frames in one frameset. Split them up over 144 framesets of a 1000 frames each.
There is just one issue. And I must admit that I am slightly annoyed. Dylan changed the logo on the website, so that means I can completely start over.
But luckily I have plenty more ideas using a modern web image format called B-M-P. And since browsers usually don’t support it, I can decode it using WebAssembly. I found some C source code for that on some website called SourceForge… And then probably use CSS paint worklets. Or maybe WebGL. Depends on which is faster.
And maybe we can optimise the text of the website by using pixel fonts like Jo used but not with LEDs, but using box shadows.
So I hope you learned some useful information here. Learned some new skills. And with that I just want to say thank you and let’s make inlining images a top priority.
It is great to be here in London again. I just love the talks so far. Halfstack is just a little bit di erent than most other conferences. There is room for some topics you wouldn’t see anywhere else. And I love that.