Type at least 3 letters to search

·17 min read

Why Is My Website Slow? What to Fix First for Core Web Vitals

A hot-air balloon over a city dropping numbered sandbags, the largest with a red number 1 first, cover of a Peretz article on what to fix first on a slow website

The site feels slow, the PageSpeed circle is red, and everyone in the room has a different culprit. Here is the order we work in: what real visitors experience, then images, fonts, third-party scripts, layout shifts and server time. Along the way: what a score means, what each fix takes, and what we changed on our own site.

IN SHORT

What to fix first

Start with what real visitors experience on phones: open the Core Web Vitals report in Search Console and see which of the three metrics fails. On most pages the element that decides loading is a picture, so the first job is the largest image on the first screen, then fonts, third-party scripts and layout shifts. Server time comes last on this list unless it eats most of the wait by itself; then it goes to the top.

The order follows the data. In HTTP Archive's Web Almanac (July 2025 data), 48% of mobile sites and 56% of desktop sites were good on all three Core Web Vitals. The weakest on phones is loading: 62% of mobile sites have a good Largest Contentful Paint (LCP), against 77% for Interaction to Next Paint (INP) and 81% for Cumulative Layout Shift (CLS). And on 76% of mobile pages the element LCP measures is an image.

Fix what real visitors feel, not what a test run prints.

The figures will age; the method will not. Find the failing metric on the templates that earn money, find its cause, fix the cheapest large cause, and measure again.

REAL VISITORS

Read field data first

Field data is what real Chrome users experienced over the previous 28 days, collected in the Chrome UX Report (CrUX). The Core Web Vitals report in Search Console and the top block of PageSpeed Insights both read from it. How it differs from a lab test is told in 3D on a Live Site: Our three.js Experiment and What Google Saw. For deciding what to fix, three details matter most.

The report judges groups, by their worst metric. Search Console puts URLs with a similar experience into one group, and the group takes the status of its poorest metric: good INP with poor CLS reads as poor. That points at a template: when 4,000 product pages fail together, one fix repairs them together.

The number describes your slower visitors. Google reports the 75th percentile, separately for mobile and desktop: three visits in four were at least this fast. Making the page faster for people on new phones and office Wi-Fi may not move it.

The data has blind spots. CrUX collects from Chrome on desktop and on Android. Chrome on iOS, Android apps using WebView and other Chromium browsers such as Edge are excluded (Chrome for Developers, checked November 2026), and Safari is a separate browser. In October 2026 iOS held about 52% of the US mobile market (StatCounter), so for an American business this report may not see half of the phones. Sites below an undisclosed popularity threshold have no CrUX data at all.

Both gaps have one remedy: measure your own visitors. Since Safari 26.2 (December 2025), Safari exposes the APIs for LCP and INP (WebKit). Google's open-source web-vitals library, about 3 KB, can send those numbers from real sessions to your analytics; CLS remains Chromium-only.

Then match what you see with what to suspect:

What the visitor feelsMetricGood isFirst suspects
The main picture or headline comes lateLCP2.5 s or lessSize and priority of the first image, late fonts, a slow server
A tap does nothing for a momentINP200 ms or lessThird-party scripts, the tag manager, heavy click handlers
Text jumps under the fingerCLS0.1 or lessImages without dimensions, injected banners, blocks that scripts build late
Nothing at all happens at firstTTFB, a supporting metric0.8 s or lessServer, database, redirects, distance to the visitor

Thresholds are from web.dev (checked November 2026). One decision no tool makes for you is which templates come first. For a store that means product, category and checkout; for a business that sells through requests, the service page and the form. We read the business before the report: a slow page that brings no orders can wait, a slightly better one that carries the revenue cannot.

THE SCORE

What a score means

The number in the circle is a Lighthouse score from one simulated load on a mid-tier phone with a fixed network. Its current weights, as Chrome documents them, are Total Blocking Time 30%, LCP 25%, CLS 25%, First Contentful Paint 10% and Speed Index 10%. INP is absent, because nobody taps during a lab run. Total Blocking Time stands in for it, and web.dev says plainly that it is a reasonable proxy and no substitute.

So a score gives you a repeatable list of problems on one page under harsh conditions, and a fair before and after. It leaves out a lot:

  • What visitors experience. Lab runs start with a cold cache, usually miss shifts on scroll and never see a real tap (web.dev).
  • Ranking. Google recommends good Core Web Vitals for success in Search, says they do not guarantee top positions, and says there is no single page experience signal.
  • Stability. Chrome's documentation names A/B tests, changing ads and internet routing among the reasons a score moves from run to run.

A low score with good field data is the smaller issue, though prospects and partners open PageSpeed too. A green score with poor field data is the dangerous mismatch: the trouble sits where a lab cannot look.

In October 2026 our home page scored 32 on mobile because the test machine has no graphics chip and draws our 3D scene in software; it reached 78 after the changes told in the 3D article. A test browser can even create a problem no visitor has: Lighthouse stretches the window to the page height for its full-page screenshot, and a canvas tied to window height grew to 16,000 pixels until we capped it. Our article pages scored 75 on mobile on October 25, 2026. That is orange, and we report it because for us a score is a working tool.

IMAGES

Start with the pictures

Images are two separate jobs.

Job one is the single picture LCP measures. web.dev splits LCP into four parts: time to first byte, resource load delay, resource load duration and element render delay, with a guideline of about 40%, under 10%, about 40% and under 10%. The two delays should be close to zero, and the LCP breakdown in Chrome's performance tools shows yours. On many pages the picture just starts downloading too late, for one of three reasons:

  • It is lazy-loaded. About 16% to 17% of pages do this to their LCP image (Web Almanac, 2025), and web.dev says never to.
  • The browser finds it late, because it sits in a CSS background or a slider script. Then it needs a preload with high priority.
  • Nothing tells the browser it matters. Only 17.3% of mobile pages use fetchpriority="high" on it.

The fix can be one line: <img src="cover.jpg" alt="..." width="1802" height="873" fetchpriority="high">. That is how the cover on our article pages is printed. Give high priority to one or two images at most; web.dev notes it stops helping beyond that.

The first job is one picture, not all of them.

Job two is everything else. The median mobile home page carries 911 KB of images, its largest single type of content (Web Almanac, July 2025). Ask of each picture whether this visitor needs it now, and at this size.

Our blog taught us both halves. Its rows have hover previews: a picture that appears beside a link when a mouse rests on it. They used to download with the page. On October 17, 2026 we changed that: the picture is requested only when the pointer reaches the link, phones never ask for it, and pictures inside article text got lazy loading. Picture weight at first view fell from 2.9 MB to 0.4 MB on the blog and from about 5 MB to 0.25 MB on one long article.

Then the fix showed its price: previews arrived late and the blog lagged under the mouse. They were originals of 230 to 250 KB for a small window. Now they are 720-pixel copies of about 50 KB (two samples checked on November 2, 2026: 233 KB against 54 KB, 249 KB against 47 KB), and on wide screens with a mouse each loads as its row comes near.

On our site the pictures themselves are never recompressed: that is our rule for a studio's work. Smaller copies for smaller windows saved about 80% and left the originals alone. Heavier compression and newer formats are legitimate tools, and for a large catalogue they can be right; someone who cares about the look should decide.

FONTS

Fonts, cheap and forgotten

87% of mobile pages use a web font (Web Almanac, 2025), and fonts hurt in two ways. On about 24% of mobile pages the LCP element is text, so a late font can hold the main metric. And a font that arrives can move the layout: even invisible text is laid out in the fallback font first, so the swap shifts content (web.dev).

The browser downloads a font only once styling asks for it, so a font declared in an external stylesheet is found late. The usual repair:

  • Serve WOFF2 only.
  • Preload the one or two faces the first screen uses, and no more, because preload takes bandwidth from other resources.
  • Choose font-display on purpose: swap shows text at once and risks a jump, optional avoids the jump and may skip the font when it arrives late.
  • Tune the fallback with size-adjust so the swap moves less, and subset large families if the licence permits.

We preload two faces on every page, SF Pro Regular and Semibold, in WOFF2 with font-display: swap. The best find was smaller. A share popup used the Black weight for its labels, and that alone made the browser fetch a Black font file on every page. Setting those labels in Semibold removed the download. Look at which font files a page really loads.

THIRD PARTIES

Scripts and slow taps

At least 90% of pages use a third party, and the median page makes 79 third-party requests on mobile (Web Almanac, 2025). In 2025 the median mobile Total Blocking Time rose 58%, from 1,209 to 1,916 milliseconds, where web.dev asks for under 200. Not all of that comes from third parties, but we look there first, since nobody has to rewrite the product to remove a tag.

The mechanism: a browser handles a tap on its main thread, and an interaction has three parts, input delay, processing and presentation delay. A task running over 50 milliseconds counts as long, and a tap that lands during one waits in line. An analytics tag, a chat widget and a heat map may each look small; together they fill that line.

This is more a management problem than a technical one: each tag was added for a reason, and nobody is responsible for taking it out. The order we follow:

  1. List every tag with three answers: who asked for it, which decision it feeds, and when anyone last used its data. Tags with no answers go to the marketing lead.
  2. Pause or remove, do not block. Google's guidance is that a paused or removed tag leaves the container, while a tag blocked by a trigger exception stays in the code.
  3. Fire what is not essential after Window Loaded. When the tag manager itself loads can matter as much.
  4. Look hard at Custom HTML tags. Most tools blame the tag manager for what they do. web.dev reports a correlation between container size and poorer INP; the median container is about 50 KB.
  5. Start widgets on demand. A chat window can load on the first click on its button.

The same applies to your own code. The audio graph for the ambient sound on our home page cost about 0.3 seconds on load; now it is built at the first tap, click or key press.

LAYOUT SHIFTS

Stop the page jumping

CLS is the one metric where desktop does worse: 72% of desktop sites are good against 81% on mobile (Web Almanac, 2025). A lab sees it least: shifts within 500 milliseconds of a tap are excused, but scrolling and hovering earn no such excuse, so a block that jumps during a scroll counts against you and may never appear in a load test.

Most causes are ordinary. 62% of mobile pages have at least one image without dimensions, so the browser gives it zero height and moves everything when it arrives; the fix is width and height attributes or aspect-ratio in CSS. Ads, embeds and iframes need space reserved with min-height or aspect-ratio. Animations should use transform, because moving something with top or left counts as a shift and translate does not (web.dev).

A cause that is easy to miss is a block that a script builds after the first paint. We had two. On phones, a script assembled the contents of each article from its headings and pushed the text down: CLS 0.19 on article pages. The section bar of our blog decided after paint whether its links fit on one line or needed two columns: CLS 0.5.

Both repairs moved the decision earlier. The server now draws the contents straight into the HTML, and the script only picks them up: 0.19 to 0. A few lines of inline script right after the bar decide its layout before the first paint: 0.5 to 0. The first repair has a running cost: the rules for building the contents now live in two places, server and script, and must change together.

Decide the layout before the first paint, not after it.

A fair test: load the page on a slow connection and watch. Anything that appears and pushes something else needs a reserved place or a server render.

SERVER TIME

When the server comes first

Time to First Byte is how long the browser waits for the first byte of HTML. web.dev suggests 0.8 seconds or less and treats anything above 1.8 as poor; in 2025, 44% of mobile sites and 55% of desktop sites were good (Web Almanac). It is no Core Web Vital, but it spends the same budget: with a TTFB of 1.8 seconds, only 0.7 remain for everything else inside a 2.5-second LCP. That is when the server moves to the top of the list.

Take a first reading of your own site from a terminal, a few times in a row, from somewhere near your customers:

curl -s -o /dev/null -w "%{time_starttransfer}\n" https://your-site.example/page

The figure includes the connection and encryption. Test a page people really open, such as a category or a product.

Cheap repairs come first, and configuration often beats hardware. On one of our projects the hosting plan already offered OPcache, the cache for compiled PHP code, and nobody had switched it on; enabling it took the server response from about 55 to about 21 milliseconds. Same-origin redirects are yours to remove. The Server-Timing header shows which backend step takes the time. A CDN deserves high priority if you have none, web.dev says, along with cached pages.

Every speed setting can break things. Before turning on Laravel's config cache we had to move code that read environment settings directly, or those values would have become empty. On a closed test copy of one of our projects, route caching turned every page into a 404 because the language prefixes come from the database. Such changes go through regression testing on a copy.

Repeat visits are a separate win, and PageSpeed will not show it. Our CSS and JavaScript are cached for a year (Cache-Control: max-age=31536000), and each file's address carries its modification time, ?v=<time>, so a change reaches everyone at once. Lab tests start with a cold cache, so the score never sees this; a reader on a second page does.

Distance is physics. AWS's documentation says a Region close to most of your users lowers latency. A server in Oregon answers a customer in Seattle sooner than one in New York, so a business selling across the US has a real reason for a CDN.

The expensive repairs are in the code: slow database queries, dozens of plugins, an old framework on an old PHP. If those are the cause, read about hidden technical debt before you budget anything.

COST

What the work costs

The table is our rough estimate of engineering effort on a business site with a handful of templates: a planning guide, no quote.

WorkOur rough estimateWhat changes it
Read field data, choose templates, write the planHalf a day to a dayWhether analytics and Search Console are in order
First image on the main templates2 to 8 hours per templateSliders and images set from scripts or CSS
Fonts2 to 6 hoursNumber of families and alphabets
Tag audit and cleanup1 to 2 daysHow fast marketing decides what can go
Layout shifts1 to 8 hours per blockWhether the block can be drawn on the server
Server settings, caching, redirectsA few hours to 2 daysAccess to the hosting; a test copy
Slow queries, old frameworkDays to weeksSet after an audit

When the last row is the cause, website modernization starts with an audit, from $300 for a small site and from $1,000 for a large one, and the work is priced after it. If you are unsure speed is the problem at all, a usability audit, from $1,500, checks the key journeys including speed. Server work alone is DevOps and cloud at $50 to $70 an hour. Keeping the numbers from sliding back belongs to website maintenance and support, from $1,000 a month, because one new tag or banner can undo the work in an afternoon. A rebuild is the last resort and a different budget: in website development, $20,000 to $40,000 for a corporate site and from $25,000 for a store. All prices are on the pricing page.

Is it worth it? A clean public test is Vodafone's, published on web.dev in 2021: an A/B test on paid traffic with two pages that looked the same, where 31% better LCP came with 8% more sales. That is one company and one page, a reason to run your own comparison and no forecast; we promise no rankings or revenue from speed work. Note a template's conversion rate before the fix and compare it afterwards, with campaigns and seasons in mind.

Allow time for proof. Field data covers 28 days, so a fix shows fully about a month later, and validation in Search Console tracks a 28-day window too. Your own web-vitals script gives a signal within days.

FAQ

Frequently asked questions

Why is my website so slow?

Often because of the first large image: too heavy, loaded late or lazy-loaded by mistake. Behind it come fonts, third-party scripts and a slow server. Check Core Web Vitals in Search Console to see which metric fails before anyone changes anything.

What should I fix first for Core Web Vitals?

Fix the metric that fails on the templates that earn money. For LCP start with the first image and its priority, for INP with third-party scripts and long tasks, for CLS with image dimensions and blocks built late by scripts. If time to first byte is near 1.8 seconds, start with the server.

Does a low PageSpeed score hurt my Google rankings?

The score is lab data from one simulated load. Google speaks about Core Web Vitals from real visitors and says good results do not guarantee top positions. A low score is still worth reading, because it often points at what weak phones feel.

Will a CDN or a bigger server fix a slow site?

Only if the wait is at the server or in the distance to it. Neither helps with a hero image loaded late, a pile of tags or a jumping layout. Look at the LCP breakdown first, and check the settings: on one of our projects OPcache took the response from about 55 to about 21 milliseconds with no new hardware.

How long until Search Console shows the improvement?

About a month, because CrUX covers the previous 28 days and validation tracks a 28-day window. A small script such as web-vitals shows the direction within days, including LCP and INP on Safari.

How much does it cost to speed up a website?

By our rough estimate, the first image, fonts, tags and layout shifts take a few days to two weeks of engineering on a site with a handful of templates. Slow queries or an old framework cost more and are priced after an audit, from $300 for a small site at Peretz Agency.

Sources

Your site feels slow and nobody agrees why? Let's look at what your real visitors experience.

Book a Strategic Session

Website Maintenance & Support