Speed Guide
Get a 99 or 100 Mobile PageSpeed Score on a Local Business Site
A local business site can score 99 or 100 on mobile PageSpeed when the hero image loads first, every image has a size, fonts do not block text and no script stops the page from painting. Make those fixes in the code that builds your pages, not in the pages.
- Year 1Website
- Year 2Map Listings
- Year 3Booking Tool
- Year 4Front Desk
- Year 5Payments
- Year 6Reports
Same six pieces.
Years of lessons, one read.
Free to read. Most of this guide is open. The finishing pieces at the end come to you when you opt in.
The Short Version
- Find the largest thing on the first screen. That is your LCP element, and it decides most of the score.
- Give every image a width and height, and serve AVIF or WebP at the size the phone needs.
- Preload the hero image and mark it high priority. Lazy load everything below it.
- Use font-display swap and defer every script, so text shows before anything else finishes.
- Fix the generator or template. A fix made by hand in the output is gone on the next build.
Why Mobile Is the Score That Counts
PageSpeed Insights tests your page on a slow phone with a slow connection. That is on purpose. Most people who search for a local shop are on a phone, and plenty of them are on one bar of signal. A page that feels fine on your office wifi can take seconds to show anything to them.
We raised 40 sites in our network to a 99 or 100 mobile score in one day. None of it took special tools. The same few problems showed up on almost every site, and they were fixed the same way each time. This guide walks through them in the order that moves the score most.
Run the test on the mobile tab. Run it three times and look at the middle score, because a single run can swing a few points. Then look past the score at the metrics under it. Largest Contentful Paint, or LCP, should be under 2.5 seconds. Cumulative Layout Shift, or CLS, should be under 0.1. Total Blocking Time should be close to zero.
Find Your LCP Element First
LCP is the time until the largest thing on the first screen is drawn. On a local business site it is almost always the hero photo. Sometimes it is the main heading. PageSpeed names it for you under the LCP metric. Open that and read which element it picked.
Everything you do next is about getting that one element onto the screen sooner. A tiny icon below the fold does not matter much. The hero photo matters more than all the rest put together.
Make sure the hero is a real <img> tag in the HTML. If it is a CSS background or gets added by a script, the browser finds it late. Late discovery is one of the most common reasons for a slow LCP.
Size Every Image and Serve Modern Formats
Give every image a width and height. The browser uses them to hold the right amount of space before the image arrives. Without them, text jumps down the page when the photo loads. That jump is layout shift, and it hurts both the score and the person trying to tap your phone number.
Serve AVIF first, WebP second and JPEG last. AVIF files are often far smaller than the same JPEG. Use srcset so a phone gets a small file and a big screen gets a big one. Here is the hero pattern we use.
<picture>
<source type="image/avif"
srcset="/img/shop-front-640.avif 640w, /img/shop-front-1280.avif 1280w"
sizes="100vw">
<source type="image/webp"
srcset="/img/shop-front-640.webp 640w, /img/shop-front-1280.webp 1280w"
sizes="100vw">
<img src="/img/shop-front-1280.jpg" width="1280" height="720"
alt="Front of the shop with two bays open"
fetchpriority="high" decoding="async">
</picture>Every image below the first screen gets loading="lazy". The browser then skips it until the visitor scrolls near it.
<img src="/img/bay-2-800.webp" width="800" height="533"
alt="Lift with a truck on it" loading="lazy" decoding="async">Never lazy load the hero. That tells the browser to wait on the one image you need first.
Preload the LCP Image
The browser reads the HTML from the top. It may not reach your hero tag until after it has found the CSS and fonts. A preload link in the head tells it about the hero right away. Match the preload to the same files and sizes as the picture tag, or the browser will fetch two copies.
<link rel="preload" as="image" type="image/avif" fetchpriority="high"
imagesrcset="/img/shop-front-640.avif 640w, /img/shop-front-1280.avif 1280w"
imagesizes="100vw">Preload one image, the LCP one. Preloading five things means none of them is first. The fetchpriority="high" hint on both the link and the image tells the browser this file comes before the rest.
Stop Fonts From Blocking Text
Custom fonts are a common hidden cost. By default some browsers hide text until the font file arrives. On a slow phone that can be the longest wait on the page. Add font-display: swap to every font face. The browser then shows the text in a system font at once and swaps in yours when it lands.
@font-face {
font-family: "Body";
src: url("/fonts/body-400.woff2") format("woff2");
font-weight: 400;
font-display: swap;
}Host the font files yourself, as woff2. A font from another host adds a new connection before the first byte can arrive. Use two families at most, and only the weights you really use. Every weight is its own file. Preload the one font that styles your main heading, and no others.
Remove Render Blocking Scripts
A plain script tag in the head stops the browser cold. It must download and run that script before it draws anything. Add defer to every script you write. Deferred scripts run after the page is parsed, in order.
<!-- Blocks the page until it downloads and runs -->
<script src="/js/menu.js"></script>
<!-- Runs after the HTML is parsed, does not block paint -->
<script src="/js/menu.js" defer></script>Third party tools are the usual culprits. A chat widget, a map embed, a review badge and a tag manager can each add more weight than your whole site. Ask what each one is for. Load chat and maps only when someone taps to open them. Remove any tag nobody reads the reports from. The same rule goes for CSS. Put the small bit the first screen needs in a <style> tag in the head, and load the rest without blocking.
Hold Space for Everything That Loads Late
Images are not the only thing that makes a page jump. Anything that shows up after the first paint can push content down. Watch for these on a local business site.
- A promo bar that a script adds to the top of the page.
- A review widget that grows from nothing to a full block.
- An embedded map or video with no set height.
- A web font that is much wider or taller than the fallback.
The fix is the same each time. Tell the browser how big the thing will be before it arrives. Put the promo bar in the HTML. Give widgets and embeds a fixed height or an aspect-ratio. Pick a fallback font close in size to your web font. Then load the page on a phone and watch the first two seconds. If anything moves, you have found your next fix.
Fix the Generator, Not the Output
This is the rule that keeps a fast site fast. Most sites are built by something, whether a static generator, a template or a CMS theme. If you fix an image tag by hand in one built page, the next build writes the old tag back. The score drops and nobody knows why.
Put every fix where the pages come from. Add the width and height in the image helper. Add the preload in the page template. Add defer in the layout. Then build again and test a few pages, not just the home page. A city page or a service page often uses a different template with its own problems.
When the build makes image sizes for you, nobody has to type a width by hand again. That is what the finishing pieces set up.
What the Finishing Pieces Contain
You can reach a top score with what is above. The finishing pieces make it stick. They hold a copy ready head template with the preload, font rules and non blocking CSS in the right order, an image build script that makes AVIF and WebP at two widths and records the sizes for your templates, a click to load pattern for maps and chat, the edge cases that knock a score back down, and the check we run on every template. Enter your email to open them. For how we did this across a whole network, see the speed pass build.
The finishing pieces
Get the Rest of This Guide
You have the method. The finishing pieces are the parts you copy straight into your own work:
- Copy Ready Head Template
- Image Build Script
- Load Maps and Chat on Tap
- Test Every Template in One Run
- Edge Cases and the Final Check
Questions People Ask
Does a 100 PageSpeed score help my Google ranking?
Speed is one small signal. The bigger win is people. A page that shows up fast keeps the visitor long enough to call you.
Why does my score change every time I test?
Each test is one run on a simulated phone, and network timing varies. Run it three times and use the middle score.
Do I need to remove my chat widget to get a good score?
No. Load it only when someone taps to open it. The page then stays fast and the chat still works.
Should I use AVIF or WebP images?
Both. Offer AVIF first and WebP as the fallback inside a picture tag. The browser picks the best one it supports.
We sell time
Get Years of Building Switched On in Hours
A thirty minute call. A written price. Nothing built until you say yes.