What slow rural internet taught me about page speed optimization
Moving to a small acreage outside a regional town in Queensland was supposed to be the quiet life. The fibro cottage sits on a few hectares of scrub, the kids have room to ride their bikes, and the nearest coffee is twenty minutes down a winding road. What I did not factor in was that the same property line that gave us kangaroos at dusk also delivered some of the most patchy broadband I have ever endured. My old blog, hosted on a slick Sydney server and tweaked to near-perfection on fibre, suddenly felt like it was being dragged through wet sand every time I tried to load the homepage.
That frustration turned into the most productive performance audit I have ever run. Most of the speed advice online is written from the comfort of a data centre or a fibre-to-the-premises suburb. Very little of it acknowledges what life looks like when you are juggling a fixed wireless NBN connection that drops out during a summer storm, or queuing behind the rest of the street for a sliver of 4G capacity on a hot arvo. Reoptimising for that reality changed how I think about every kilobyte, every script, and every plugin my blog ships.
From city fibre to bush broadband
For the first six months I made do with what the local tower could spare. The connection claimed to be a fixed wireless NBN service, which on paper should have been fine, but in practice it shared bandwidth with the entire district and slowed to a crawl whenever the cattle farmers next door started streaming tractor videos. When the weather rolled in, the link would fall over completely and I would tether through my phone, praying Telstra had a spare bar in our pocket of the bush.
The readers I had always thought of as second priority were suddenly my primary test subjects. A retiree in western Tasmania on Sky Muster, a couple running a homestead near Broken Hill, a tradie in the Top End checking my affiliate comparison during smoko - they were no longer edge cases. They were the people I needed my blog to work for, and if it crawled on their connection it was not going to convert.
Measuring performance on a connection that gives up halfway
Lab tools were misleading at first. Running GTmetrix from a Sydney test node gave me a comfortable green grade, and I nearly patted myself on the back. Then I forced Chrome's network throttling down to 1.5 Mbps with 300ms of latency, the kind of conditions a user on rural mobile data might face, and the score collapsed. The hero image alone took nine seconds.
I started using WebPageTest with Australian test locations, then deliberately added a throttled profile to mimic what someone on a flaky link would see. The Lighthouse mobile audits became a daily habit, but more importantly I pulled the CrUX data for my own domain. The field numbers, weighted towards real users on real devices and connections, were far worse than what my synthetic runs suggested. That gap became my to-do list.
The image diet that rescued my blog
The first win was embarrassingly obvious. I had been uploading hero photographs straight from the camera, often north of three megabytes each. The blog had been running for years, so there were hundreds of these scattered through old posts. A bulk conversion to WebP, capped at the actual display width, freed up more bandwidth than every other change combined.
Lazy loading below the fold was easy enough with the native attribute, and I made sure to preload only the single LCP image on each page. Working with the AFFINGER5 theme, I disabled a handful of thumbnail sizes it generated automatically that nothing on the site was actually using. On my own link the homepage dropped from around fourteen seconds to roughly six. Bush readers saw a similar curve, which mattered far more than my own numbers.
Trimming render-blocking code without losing functionality
Looking at the waterfall next to my own loading experience was humbling. The theme's stylesheet blocked rendering for over a second on a slow connection, and my custom web font added another half-second of invisible waiting. I inlined the critical CSS for above-the-fold content, deferred the rest, and self-hosted the font with a preload hint for the single weight I actually used.
JavaScript was the bigger mess. I had layered on a chat widget, two analytics scripts, an exit-intent popup, and three social sharing plugins over the years. None of them were pulling their weight against the cost. I removed the chat entirely, queued analytics to fire after the load event, and pushed everything I could into the footer. For AFFINGER5 users specifically, the theme includes options to defer non-essential scripts, and flipping those on gave me back another few hundred milliseconds.
Caching layers that survive a stormy Sky Muster afternoon
Caching had always been set to the defaults from my hosting provider, which turned out to mean almost nothing useful. I added proper browser caching headers and set up a service worker so repeat visitors got pages straight from local storage. Server-side, I moved to a plan that supported full-page caching and used a plugin to generate static HTML files for every post and category.
The biggest jump came from time to first byte dropping from around three seconds on a congested link to roughly two hundred milliseconds once the cache was warm. For visitors further from the origin server, a free Cloudflare tier with the Sydney and Melbourne edge nodes proved worthwhile. The Australian reach of those points of presence is often overlooked, but for a blog whose audience is genuinely distributed across the country it is a noticeable lift.
A lean theme and a ruthless plugin audit
The plugin audit was the most painful afternoon of the whole process. I deactivated everything that was not actively serving the reader or my affiliate links, and then deleted what I could. The blog went from twenty-eight active plugins down to fourteen, and a handful of those fourteen are deliberately dormant unless I need them.
The theme itself, AFFINGER5, is already reasonably trim, but I went through its options and turned off features I had enabled during a more experimental phase. The auto YouTube thumbnail generator went, since I prefer to embed videos with custom posters. Several social widgets that I had never styled properly were quietly switched off. After all of that I ran a database cleanup, trimming old post revisions, expired transients, and a backlog of spam comments that had quietly grown the database past eight hundred megabytes.
Practical fixes for bloggers stuck with patchy service
If your readers include people on regional Australian connections, or if you yourself are blogging from the bush, here are the changes that paid off most clearly.
- Audit every image older than twelve months and convert anything over two hundred kilobytes to WebP at the actual display size.
- Use Chrome DevTools or WebPageTest with a throttled profile that mirrors real rural mobile speeds, not just your office connection.
- Inline critical CSS and preload only the fonts and hero image that genuinely sit above the fold.
- Move analytics and any non-essential scripts to load after the main content, or drop them altogether if they are not earning their keep.
- Enable full-page caching on the server and add a free CDN tier with Australian edge nodes for your local audience.
- Cut inactive plugins without mercy, then run a database cleanup to remove orphaned data and old revisions.
- Re-check field data in CrUX monthly so you are optimising for real visitors, not synthetic scores.