Fixing Third-Party Script Bloat on Page Load
Third-party scripts are the code your page loads from other companies: analytics, advertising pixels, video and map embeds, chat widgets, review carousels, font services and testing tools. Each one arrives from another server, often pulls in more files of its own, and competes with your content for bandwidth and processor time.
When the Page Speed Analyzer lists third-party requests among the slowest parts of a page, this guide shows you how to put a real cost on each one, then how to load the ones you keep in a way that stops them holding back the page.
What a third-party script actually costs
The download size of a third-party script is only part of its cost, and often not the biggest part. When you add one line of embed code to a page, the browser may have to do all of this:
- Open new connections. Each new domain needs a DNS lookup, a connection and a TLS handshake before the first byte arrives. On a mobile connection that setup can take longer than the download.
- Download a loader, then more files. Many tags are a small loader that fetches a larger script, which fetches configuration, which fetches further scripts, images, fonts or iframes. The one line you pasted can become dozens of requests.
- Run code on the main thread. Parsing, compiling and running JavaScript happens on the same thread that draws your page and responds to taps. A script that runs for a long time delays both.
- Compete for bandwidth. Requests for third-party files share the connection with your hero image, fonts and stylesheets. On a slow phone connection, a large widget can push back the arrival of your own content.
- Block the page, if loaded carelessly. A third-party script placed in the head without
asyncordeferstops the browser reading the rest of the HTML until it has arrived and run. If that server is slow or down, your page waits with it.
The last point is worth stressing. A third-party script loaded in a blocking way makes your page's speed depend on someone else's server. If their service has a bad day, your page can show nothing for many seconds. This is sometimes called a single point of failure, and it is one of the most important things to rule out.
Putting a number on each third party
Guessing which script is slow is unreliable, because the heaviest file is not always the most expensive one. Use three views together.
Grouped by provider
The Page Speed Analyzer lists third-party requests for the page. Lighthouse and PageSpeed Insights also group third-party code by provider and show the transfer size and main-thread time for each, under a third-party audit or insight depending on the version. Chrome's Performance panel can dim or highlight third-party activity in a recording and summarises time by first party and third party. Together these tell you which providers are worth investigating.
By removal
The most convincing measurement is to load the page without a provider and compare. In Chrome DevTools, open the Network panel, right-click a request from the provider, and choose to block its domain. Reload with a throttled network and CPU profile, and compare the timings with and without it. Blocking a domain also blocks everything that domain would have loaded, so you see the full knock-on cost.
By failure
Lab tools such as WebPageTest can block a domain, or send its requests to a server that never answers, to show what happens if the provider is slow or down. If the page stays blank until the request times out, that script is loaded in a blocking way and must be changed whatever else you decide.
| What you see when the domain is blocked | What it means | Likely action |
|---|---|---|
| Main content appears noticeably sooner | The script is on the critical path or competing heavily for bandwidth | Make it async or deferred, or delay it until after load |
| Content timing unchanged, but long tasks disappear | The cost is main-thread time, affecting responsiveness | Delay until interaction or idle time, or replace with a lighter option |
| Dozens of requests vanish | The tag loads further tags or assets | Check its settings for features you can switch off, or replace it |
| Almost nothing changes | The script is cheap on this page | Leave it and move on |
| The page breaks | Your own code depends on it | Keep it, but check whether it can load later or be self-hosted |
Record the result for each provider in a simple table: domain, what it does, who asked for it, transfer size, main-thread time, and the change in main content timing when blocked. That table is your baseline and makes the conversation about removing a tag much easier.
The fix, step by step
Step 1
List every third-party origin on the page
Run the page through the Page Speed Analyzer and note the third-party requests it lists. Then open the Network panel in a private window, reload with the cache disabled, and sort by domain. Write down every domain that is not your own or your own CDN, including ones loaded indirectly by other scripts. For each, note what service it belongs to and what it is for. Repeat for each key template, because product, article and contact pages often load different tools.
Step 2
Measure each one by blocking it
With a throttled mobile network and CPU profile, record the main content timing and total blocking time for the page as a baseline. Then block one provider's domain in DevTools, reload several times and record the same figures. Repeat for each provider. The difference is that provider's real cost on this page. Also test what happens when a provider never responds, to find any script that can hold the whole page hostage if its server is slow.
Step 3
Replace heavy embeds with facades
For video players, maps and social post embeds, show a lightweight placeholder instead of the real embed: a static image of the video or map with a play button or a link. Load the real iframe only when the visitor clicks. Most visitors never press play on an embedded video, so this saves the player's scripts and connections on almost every page view. Use the privacy-enhanced embed domain where the provider offers one.
Step 4
Load chat and support widgets on demand
Chat, help desk and feedback widgets are often among the most expensive third parties, and most visitors never open them. Replace the auto-loading snippet with your own small button styled like the launcher. When the visitor clicks it, or shows clear intent such as scrolling to the contact section, load the vendor script and open the chat. Check the vendor documentation for an API call that opens the widget once loaded, so the first click is not wasted.
Step 5
Self-host what does not need to be remote
Fonts from a hosted font service and libraries linked from public CDNs, such as jQuery or a carousel, can usually be downloaded and served from your own domain. Browsers now keep a separate cache for each site, so a public CDN no longer gives visitors a head start. Self-hosting removes a connection and puts the files under your compression and caching settings. Do not self-host payment, fraud, advertising or analytics loaders whose providers require or frequently update the hosted version.
Step 6
Connect early only where the first screen needs it
If a third-party origin is genuinely needed for the first screen, such as an image
CDN on another domain or a consent platform, add a preconnect hint for it in the head so
the connection is ready when needed. Add crossorigin for fonts. Keep this to the few origins
that matter, because each unused preconnect wastes a connection. For origins used later in the load,
a cheaper dns-prefetch hint is enough, or no hint at all.
Step 7
Defer or delay everything that remains
Make sure no third-party script sits in the head without async or defer.
Then decide the latest point each one can load: after the page has loaded, when the browser is idle,
when the relevant section scrolls into view, or when the visitor first interacts. Analytics usually needs
to start early to count visits, but review widgets, social feeds, heatmaps and remarketing pixels can
nearly always wait. Tie tracking tags to consent where the law requires it.
Step 8
Re-measure against your baseline
Rerun the Page Speed Analyzer on the same URLs and repeat the throttled DevTools test you used for the baseline. Compare the number of third-party requests, the third-party transfer size, main-thread time and main content timing. Check that analytics still records visits, that forms and chat still work, and that video and maps load when clicked. Share the before and after table with the people who own each tool, so the gains are understood and kept.
Facade patterns you can copy
A facade is a stand-in that looks like the real widget but costs almost nothing until the visitor uses it. Here is a simple video facade. The HTML shows a thumbnail and a button:
<div class="video-facade" data-video-id="VIDEO_ID">
<img src="/images/video-poster-VIDEO_ID.jpg" width="640" height="360"
alt="Product walkthrough video" loading="lazy">
<button type="button" class="video-play">Play video</button>
</div>
A few lines of JavaScript in your own deferred script swap in the real player on click:
document.querySelectorAll('.video-facade').forEach(box => {
box.querySelector('.video-play').addEventListener('click', () => {
const iframe = document.createElement('iframe');
iframe.src = 'https://www.youtube-nocookie.com/embed/' +
box.dataset.videoId + '?autoplay=1';
iframe.width = 640; iframe.height = 360;
iframe.title = 'Product walkthrough video';
iframe.allow = 'autoplay; encrypted-media; picture-in-picture';
iframe.allowFullscreen = true;
box.replaceChildren(iframe);
}, { once: true });
});
Save the poster image on your own site rather than hot-linking the provider's thumbnail, so the facade itself makes no third-party request. Give the facade box the same width and height as the player so nothing moves when it is swapped.
Chat widget on click
const chatButton = document.querySelector('#chat-launcher');
chatButton.addEventListener('click', () => {
chatButton.disabled = true;
chatButton.textContent = 'Opening chat...';
const s = document.createElement('script');
s.src = 'https://widget.example-chat.com/loader.js';
s.async = true;
s.onload = () => { /* call the vendor's documented open method here */ };
document.head.appendChild(s);
}, { once: true });
Maps
For a location map on a contact page, a static map image linking to the full map in a new tab is enough
for most visitors. If you need an interactive map, load it when the map section scrolls near the viewport
using an IntersectionObserver, or behind a "Show interactive map" button.
<button> element with a clear label, visible focus, and
the real widget taking focus once loaded.Choosing when each script loads
Once you know what each third party costs, give each one the latest loading point that still does its job.
| Loading point | How | Suits |
|---|---|---|
| Blocking in the head | A plain script tag in the head | Almost nothing from a third party. Avoid. |
| Async | async attribute; runs as soon as it arrives | Independent scripts that should start early, such as the main analytics loader |
| Defer | defer attribute; runs after the HTML is parsed, in order | Scripts that need the page structure or depend on each other |
| After load or when idle | Injected from the window load event or requestIdleCallback | Heatmaps, session tools, remarketing pixels, review widgets |
| On scroll into view | IntersectionObserver on the section | Maps, social feeds, embedded reviews further down the page |
| On interaction | Click, focus or first input | Chat, video, booking widgets |
| After consent | Consent platform or tag manager rules | Tracking and advertising tags that need consent under UK GDPR and PECR |
There are also tools that try to move third-party scripts off the main thread entirely, running them in a web worker. Partytown is the best known. They can help with some analytics tags, but not every script works in a worker, and debugging becomes harder. Treat them as an option to test on a staging copy, not a default.
Server-side tagging moves some tracking work from the visitor's browser to a server you control. It can reduce the number of vendor scripts on the page, but it needs setup and hosting, and it does not remove the need for consent. It is covered in more depth in the tag bloat guide.
Edge cases
- The consent banner is itself a third party. A cookie consent platform loads early by design and its banner is sometimes the largest element on a phone screen. Choose one that loads asynchronously, reserves its space, and does not block the page while fetching its configuration.
- Anti-flicker snippets. Client-side A/B testing tools often come with a snippet that hides the whole page until the test script arrives, with a timeout as a safety net. On slow connections visitors stare at a blank page until that timeout. Shorten the timeout, limit the snippet to pages running a test, or move testing to the server.
- Tags that load tags. A tag manager or advertising script may load several further vendors you never added directly. Blocking the parent in DevTools reveals the whole chain; the vendor's settings or your contract may let you switch the extras off.
- Your own code depending on a third party. If your menu or basket waits for a library from a public CDN, a slow CDN breaks your site. Self-host anything your own features need to work.
- Removing tracking changes reports. Delaying or removing a tag can change the figures a marketing team relies on. Agree the change with the tag's owner and note the date so a dip in their data is not misread.
- Legal requirements. Consent rules under UK GDPR and PECR, as amended by the Data (Use and Access) Act 2025, affect which tags may load and when. This guide is not legal advice; check the rules that apply to your site with a qualified adviser.
Stopping third-party cost from creeping back
- A cost for every new tool. Before any new widget, pixel or embed goes live, measure it with the blocking test on a staging copy and record the result alongside the reason for adding it.
- A loading point for every tool. Decide at the time of adding whether it loads async, deferred, after load, on scroll or on interaction, rather than pasting the vendor snippet into the head.
- A third-party budget. Set a limit on the number of third-party origins and the third-party transfer size for each key template, and check it when the Page Speed Analyzer runs.
- A review date. Revisit the list every few months. Trials end, campaigns finish and agencies change, but their tags often stay.
1. How do I find out which third-party script is slowing my site?
Measure by removal rather than by file size. In Chrome DevTools, open the Network panel, right-click a request from the provider and block its domain, then reload with network and CPU throttling switched on. Compare the main content timing and total blocking time with and without it. Repeat for each provider. The one whose removal makes the biggest difference is the most expensive, even if its files are not the largest on the list.
2. Is async or defer better for third-party scripts?
It depends on the script. Async lets a script download in parallel and run as soon as it arrives, in any order, which suits independent scripts that should start early, such as an analytics loader. Defer also downloads in parallel but waits until the HTML is parsed and runs scripts in order, which suits scripts that need the page structure or depend on each other. Both are far better than a plain blocking script tag in the head.
3. What is a facade for embeds?
A facade is a lightweight stand-in shown in place of an expensive embed, such as a video player, map or chat widget. It looks like the real thing, usually a static image with a play button or launcher, but loads no third-party code. When the visitor clicks, a small script replaces it with the real embed. Because most visitors never interact with these widgets, the page avoids their scripts and connections on the majority of views.
4. Should I self-host Google Fonts?
Often, yes. Browsers now partition their cache by site, so a font loaded from a shared font service on another site does not help visitors to yours. Serving the WOFF2 files from your own domain removes the extra connections to the font service, lets you control caching and compression, and avoids sending visitor data to a third party. Check the font licence allows self-hosting; most fonts offered by the major free font services do.
5. Do third-party scripts affect Core Web Vitals?
Yes, in several ways. Blocking scripts in the head delay the first paint and the main content, which affects Largest Contentful Paint. Scripts that run long tasks on the main thread delay responses to taps and clicks, which affects Interaction to Next Paint. Widgets and banners that insert themselves above existing content without reserved space cause layout shift. Measuring each provider by blocking it shows which of these effects it has on your pages.
6. Can I delay Google Analytics until after the page loads?
You can, but think about what you lose. Analytics that loads late misses visitors who leave before it starts, so reported visits and bounce figures change. The standard Google tag already loads asynchronously and is usually not the most expensive third party on a page. It is often better to leave the main analytics tag loading early and delay the heavier extras, such as heatmaps, session recording, remarketing pixels and review widgets.
7. Does preconnect help with third-party scripts?
It helps for the few third-party origins needed early in the load, because the DNS lookup, connection and TLS handshake are done before the first request. It does not reduce the size or processing cost of the scripts themselves. Each preconnect holds a connection open, so adding hints for many origins wastes effort and can compete with more important requests. Use preconnect for one to a few critical origins and dns-prefetch for less urgent ones.
The Page Speed Analyzer measures your page with real-user and lab data and names the specific files and scripts holding it back, including third-party requests, so you can start with the change that saves the most time.
Open Page Speed Fixes โ