A slow website costs money: how we speed sites up
A site that opens in a second on office Wi-Fi can take fifteen on mobile data in Nukus. Nobody waits that long. Here's what we do about speed on every project, and where to start if your site is slow.
Shahzodjon JumakulovFrontend developer
Once I opened the Network tab on a site a client had brought us to fix, and saw the home page weighed 14 megabytes. Eleven of them were photos in the slider. Five pictures, each at the camera's original resolution, 2–3 MB apiece.
On office fibre you don't notice. On 4G in Tashkent it's a couple of seconds. On mobile data somewhere in a district of Khorezm or Surkhandarya, a person stares at a white screen until they close the tab.
Site speed isn't a technical nicety. It's money you pay for ads and lose on the first screen.
How seconds turn into money
Say you're running ads. You pay per click. Someone taps, and the site is loading. Every extra second cuts off some of the people who have already cost you money. Google's own research has said for years that as load time grows from one to three seconds, the chance of a bounce rises noticeably, and it gets worse from there.
There's a second effect. Google uses Core Web Vitals in ranking. Three metrics:
- LCP: when the largest element on the first screen appears (target: under 2.5 s);
- INP: how quickly the page responds to taps (target: under 200 ms);
- CLS: how much the layout jumps while loading (target: under 0.1).
A slow site ranks worse and converts worse. A double hit.
Images: almost always the main problem
In our audits, most slow sites get most of their weight from images. Not JavaScript, not fonts, but photos uploaded "as is".
What we do with images on every project:
- WebP format. At the same quality it's roughly 25–35% lighter than JPEG, and it shrinks PNG screenshots several times over.
- The right size. If a photo is shown 800 pixels wide, there's no need to load 4,000. Phones get an even smaller version.
- Lazy loading. Images below the first screen load only when the person scrolls down to them.
- Dimensions in the markup. Every image has a width and height set, so the page doesn't jump when it arrives. That directly affects CLS.
In Nuxt, the @nuxt/image module handles most of this. Here's how it's configured on the Japanese Garden site, for example:
// nuxt.config.ts
image: {
format: ["webp"],
screens: { sm: 640, md: 768, lg: 1080, xl: 1280 },
},
Then in the template we write <NuxtImg> with loading="lazy" and sizes instead of <img>, and the server generates the variants itself.
Our own site
The cobbler's children have no shoes, and that applies to us too. On idrok.group, images uploaded through the admin were stored exactly as uploaded for a long time. At some point we did what we tell clients to do: on upload, images are now scaled down to the size they're actually displayed at and re-encoded to WebP, and for the old files we wrote a command that ran them through the same pipeline.
No redesign, no new frontend code. Just the images.
Fonts and third-party scripts
The second usual suspect is fonts. A nice Google Font pulled in with @import inside CSS means a chain: load the CSS, parse it, find the @import, load another CSS file, and only then the font itself. On a slow connection that's hundreds of extra milliseconds of invisible text.
What helps:
preconnectto the font servers in<head>;- a direct
<link>instead of@import; font-display: swap, so text shows immediately in a system font;- no more than two families, and only the weights you use. Four weights of Poppins at 40 KB each is already 160 KB.
On MY5 we went exactly this way: fonts load via preconnect and a direct link, and the critical CSS for the first screen is inlined into the HTML so the page can render without waiting for every stylesheet.
Third-party scripts are a story of their own. A chat widget, three analytics counters, a social pixel, a map. Each pulls in its own JavaScript, and each "only weighs a little". Together they can add a second. We ask the client about each one: who uses it, and what happens if we remove it. "No idea, the previous marketer installed it" comes up more often than we'd like.
SSR, SPA, and what a phone in the regions actually sees
A React or Vue site can be built two ways. As an SPA: the browser gets an almost empty page and builds it by running JavaScript. Or with server-side rendering (SSR): the server sends ready HTML straight away, and JavaScript then "brings it to life".
- +Content shows up immediately, even on a weak phone
- +Search engines get ready HTML
- +Better LCP on mobile
- −Needs a Node.js server, not just a folder of files
- −Slightly more complex development and deployment
- −On weak devices the page stays blank for a long time
- −Worse indexing, especially in Yandex
For sites that need to be found in search and open well on cheap Android phones, we almost always go with SSR. MY5 and Japanese Garden, for example, are built on Nuxt 3 with server-side rendering.

With Japanese Garden we went further: the site is a PWA. After the first visit, a service worker caches the pages, and the next visit opens almost instantly, even if the signal in the garden is poor.
CDN and the server
If your audience is in Uzbekistan and your server is in Germany, every request travels thousands of kilometres. A CDN serves static files (images, scripts, styles) from the node closest to the user. For sites with audiences in several countries, that's noticeable. For a purely Tashkent business, it's sometimes more sensible to rent a server in Uzbekistan and skip the CDN.
The backend has its own slowdowns that you can't see in the browser: slow database queries, an API that returns ten times more data than the page needs, no caching. That's backend work, and the first thing Mirodil checks is how many database queries a single page makes.
Where to start if your site is already slow
You don't need to rewrite the site right away. Nine times out of ten, most of the gain comes from simple things:
- Open PageSpeed Insights and test the mobile version of your home page.
- Find the heaviest images and convert them to properly sized WebP.
- Remove third-party scripts nobody uses.
- Check how fonts are loaded.
If it's still slow after that, the problem is probably architectural: an SPA without server rendering, a heavy WordPress theme with dozens of plugins, an overloaded server. That's a conversation with developers, and we're happy to have it. For how speed connects to search, I'd also read our piece on SEO for news websites: media sites feel these problems the hardest.
My personal rule: before handing over any project, I open it on the cheapest Android phone in the office with Wi-Fi turned off. If I find the wait annoying myself, I don't show it to the client.




