Dansday

From 31 to 100, and the Globe Nobody Was Watching

From 31 to 100, and the Globe Nobody Was Watching

Published on Oct 4, 2026

My personal site, dansday.com, scores 100 on PageSpeed. The bot's site, dansday.dev, scored 31 on mobile. Same person, same kind of stack, a seventy-point gap. I had always assumed the difference was that the bot's homepage simply has more on it. That turned out to be true, but not in the way I expected.

The first report was almost funny. Total blocking time was 81.8 seconds. The main thread did 169 seconds of work during a test that should have been over in a few, and the page did not count as interactive until the 159-second mark. Nothing on a landing page should take two and a half minutes to settle down. Something was running and never stopping.

It was the globe. The hero has a spinning 3D globe with XP pulses popping up over real countries, built with three.js. It rendered sixty frames a second, forever, with antialiasing on, and on every single frame it measured the position of the hero text so the pulse labels would not overlap it. On a throttled phone that is a job that never ends. The fix was to stop drawing something nobody had looked at yet. The globe now does not load at all until the visitor scrolls, touches the screen, or moves the mouse, and then it fades in. The labels measure the hero once a second instead of sixty times.

Blocking time went from 81.8 seconds to about four. The score went from 31 to 35. That was the first real lesson: the scoring is a curve, not a line. Lighthouse gives zero points for blocking time above about 1.2 seconds, so cutting 78 seconds of it bought four points. A huge win can look like nothing on the scoreboard until you get under the threshold.

The next loop was smaller and sneakier. The smooth scrolling library ran its update on every animation frame, all the time, whether anyone was scrolling or not. It now runs only while a smooth scroll is actually happening, and stops when it settles.

Then the icons. The homepage preloaded a 116 KB icon font so it would arrive early, which meant it was competing for bandwidth with the CSS the page needed to paint at all. A second 110 KB font was being downloaded for exactly one icon: the Discord logo on two buttons. That logo is an inline SVG now. I also told the browser to skip laying out the lower homepage sections until they come near the screen, and moved the card effect styles out of the global stylesheet so only pages that show cards pay for them.

That got the first official run from Google to 84 on mobile and 100 on desktop. The remaining points were all in how long the page took to paint on slow 4G, and the reason was everything the browser started downloading before the hero appeared. SvelteKit preloads every JavaScript file the page will ever need, up front, at high priority. Twenty-five of them. I stopped that, loaded the icon font after the page finished loading, and moved the live statistics stream to open on first interaction — it had been timing out during the test and logging an error, which was the only thing holding best practices below 100. A handful of grey-on-grey labels got darker so accessibility could reach 100 too.

My own machine said that round made things worse. Three local runs came back between 45 and 69. Google's servers said 93. The long tasks in my local runs were Cloudflare's own scripts taking two to three times longer than the round before, which is my laptop being busy, not the page getting slower. I nearly reverted a good change because of it.

Not everything worked. I was sure the hero headline's fade-in was hurting the paint metric, because the browser does not count text that is still invisible. I made it slide instead of fade. The number did not move at all. And the same build, untouched, scored 87 on one run and 93 on the next. Mobile PageSpeed varies by a few points between runs, and it varies more when the page is heavy, because there is more for a slow moment to land on.

So I stopped guessing and lined the two sites up. dansday.com sends 12 KB of HTML and 8.5 KB of CSS. dansday.dev was sending 32 KB of HTML, 30.5 KB of CSS, and a homepage script five times bigger. And dansday.com, it turns out, never loads its icon font on a phone at all — the navbar only adds it on screens 1024 pixels or wider. PageSpeed tests as a phone, so it never sees it. There was no trick I was missing. The bot's homepage was just heavier, and the weight was mostly things nobody had asked for yet.

The CSS was the clearest case. The whole app shares one stylesheet, which means the homepage was downloading the styles for every admin panel screen before it could show a single word. The homepage has its own stylesheet now, built only from the files it actually renders: 119 KB instead of 261, and small enough to go straight into the HTML instead of being a separate request. The modules marquee was the clearest case in the HTML: 106 cards, each one rendered twice so the loop looks seamless, 117 KB of a 265 KB page, for a section that sits well below the fold. It now renders when you scroll near it, and so do the two animated demo players. The text and the full module list stay in the page, so search engines see exactly what they did before.

The next mobile run came back 100, with first paint at 1.2 seconds, the largest paint at 1.3, and 60 milliseconds of blocking time. Desktop is 100 as well, and so are accessibility, best practices and SEO. That puts it level with dansday.com, which was the only comparison I ever cared about.

One honest footnote. I started this because a faster homepage is better for SEO, and in general that is true. But Google ranks on speed data from real Chrome visitors, not on this lab test, and the report says there is not enough real-world data for dansday.dev yet. So the 100 is not a ranking signal today. It will matter when the traffic is there, and in the meantime the page is genuinely faster for everyone who does visit.

It is the same lesson as the last one, really. Not one of these fixes made anything faster. Every one of them was work that did not need to happen during the first few seconds: a globe drawing for nobody, a scroll loop with nothing to scroll, a font downloaded for one logo, the admin panel's styles shipped to the front door, a hundred cards rendered twice before anyone had scrolled to them. The question that keeps paying is not how to make the work faster. It is which of this work should not be happening yet.