🧵 Two of my most- and first-used checks when doing a performance audit are surprisingly old school: 1) Validate HTML 2) Disable JS.
Validate HTML? Yep. We haven’t really cared about ‘valid HTML’ for valid HTML’s sake for about a decade, but certain errors can actually be pretty significant. What’s wrong with this picture?
It’s this lil’ fella right here. <span> isn’t allowed in the <head>, so when the browser encounters the <span>, it assumes the <head> should have been closed already.
This is a feature. This is what allows us to omit certain closing tags like </p>, </li>, </tbody>, and—you guessed it!—</head>. The appearance of certain opening tags implies the closing of certain preceding ones.
The practical upshot of which is that non-<head> elements early-terminate the <head> tags, pushing all of your important <head> resources into the <body>. Oops!
Disable JavaScript? I think building sites for people who’ve turned JS off is an expensive waste of time: they’ve turned it off! Leave them to it. But! I do feel it’s vital that we can fail reasonably elegantly when JS fails (and it will).
I strongly hold @adactio and @jaffathecake’s respective (and paraphrased) opinions about JS: ‘How well does it fail?’ and ‘All your users are non-JS until your JS is downloaded and run’.
From a performance perspective, I don’t want to see your core content buried away in JS. JS is slower than HTML. If you need JS to display core content, you’re on the slow path. The quickest way for me to ascertain whether content is coming out of JS? Disable it!
Do I care that CNN doesn’t work with JS disabled? Not necessarily. But immediately I can see that their content is reliant on the successful download and execution of JS. This is always going to be slower than having it in the HTML—the first (and successful) response.
</🧵>
• • •
Missing some Tweet in this thread? You can try to
force a refresh
🖼 If you’re building hero-style content with background images—maybe even through a CMS—you can hugely improve rendering times (LCP) with one additional line of HTML.
With the before, the browser won’t request the image until it knows it needs it—when the Render Tree is built. The problem is that the Render Tree can’t be built until the CSSOM is built, which means the browser needs to download and (re)calculate all applicable stylesheets.
Your Render Tree is only as fast as your slowest stylesheet.
📊 I took the csswizardry.com homepage and tested it over a 3G connection. I then ‘improved’ bandwidth or latency by 10% until 2× change, then I did 4× and 8× changes.
📈 For every 10% improvement in bandwidth, we see an average 0.21% *increase* in FCP.
📉 An 8× improvement in bandwidth only yields a 1.64% improvement in FCP.
📉 For every 10% improvement in latency, we see an average 2.1% improvement in FCP.
📉 An 8× improvement in latency yields a 94% improvement in FCP.
You WILL need a cast iron pan[1], a quick-read meat thermometer, and a high smoke point cooking oil[2]. Do not attempt this until you have all of these items. It will not work and you will be disappointed.
1. Cast iron can be heated up to crazy-high temps, and holds/spreads heat well. Mine was dirt cheap and I absolutely adore it. nisbets.co.uk/vogue-round-ca… 2. Do NOT attempt this with olive oil. It will burn before you can even get started. Avocado oil, beef fat, or clarified butter.
Making your own clarified butter is easy. Slowly melt butter in a heavy pan; discard the white bits that sink and keep the clear liquid. Done.
Want to view a single image on @imgur (literally its only job)? Good luck! You gotta successfully download (354KB) and run (1.21MB) of client-side React in order to get your image requested as resource 110 of 553. What should have been an IMG element became… this.
• Total page weight: 5,961KB
• Image I wanted to view: 37.5KB
Put another way, this page was 158.96× heavier than it needed to be.
What’s even more even more disgusting is that THIS IS THEIR M-DOT SITE. This was a deliberate strategy for serving mobile devices. This industry needs some sort of regulatory body.
This is the first time I’ve knowingly seen the Battery Status API used for fingerprinting. Inevitable, really, but this is the first time I’ve spotted it in the wild.
Any developers not familiar with browser/device fingerprinting, I encourage you to please read up on it: en.wikipedia.org/wiki/Device_fi…
One very common and completely gross fingerprinting vector is to check which fonts you have installed. As the page loads, the script fires a 72px string of text into the page, iterates over a series of font-families, and sees what you’ve got.