Third-party scripts: how to find and fix the slow ones
Chat, ads, analytics, tag managers and embeds run code you did not write. How to list them, measure what each costs, and remove, delay or replace them.
In this guide
What counts as a third party
A third-party script is any script served from a domain other than your own. A Google Analytics tag, a chat widget, a cookie banner, a video player embedded from a video site, an advertising network and a tag manager are all third parties. A tag manager is a special case: it is itself one script, but it loads whatever tags were put in it, so a single line in your page can bring in a dozen more.
They are everywhere. In the 2025 Web Almanac, at least 90% of pages included one or more third parties, and the median page made about 80 third-party requests. Third parties also load other third parties: the median chain of inclusion was three levels deep, which means that a typical third party brings in at least one more. The Almanac adds a caution that its crawler does not scroll or interact, so its numbers are a lower bound on what real visitors load.
What they cost
- Requests and connections. Each new domain needs a lookup, a connection and a secure handshake before the first byte of the script arrives. See connection setup.
- Main-thread time. After download the browser must parse, compile and run the script, on your visitor's phone, and nothing else can run at the same time. This is what drives Total Blocking Time and slow INP.
- Layout shift. Embeds and ads that appear late, or change size, move the page.
- Reliability. A slow vendor can slow your page. A vendor outage can break a feature or, if the script blocks the page, the whole page.
- Privacy and consent. Many collect data, and may need a consent banner, which is another script.
The cost is not related to how important the feature is. A small tracking pixel can be cheap and a chat widget can be heavy, and a free widget is not free.
Step 1: list every third party
You cannot judge what you cannot see. Three views help.
- The report. In PageSpeed Insights, the "3rd parties" insight groups the page's third-party code by company and shows how much data each transferred and how long each used the main thread. Lighthouse recognizes companies from a public dataset, so the names are readable. Older versions of the report flagged a page when third-party code blocked the main thread for 250 milliseconds or more.
- The Network panel. In Chrome DevTools, reload the page, and sort or filter the requests by domain. Everything that is not yours is a third party.
- The tag manager. If you use one, open it and read the list of tags. Old ones for campaigns that ended years ago are common, and they run on every page.
Make a list with four columns: what the script is, who asked for it, what it is for and what it costs.
Step 2: decide what each one deserves
| Question | If yes | If no |
|---|---|---|
| Is anyone still using what it provides? | Keep going | Remove it |
| Is it needed on this page? | Keep going | Remove it from this page |
| Does it have to load before the page is usable? | Load it normally, with async | Load it later |
| Is it used by few visitors? | Put a click-to-load placeholder in front | Keep going |
| Is there a lighter alternative? | Replace it | Keep it and measure |
The most valuable action is the first one: remove. Old analytics tags, abandoned A/B tests, a second chat tool that was replaced, a social share widget nobody clicks. Every removed script is work the browser never does.
Step 3: load what is left without hurting the page
Make sure nothing blocks the page. A third-party script in the head without async or defer stops the page from being read until it has been downloaded and run, and if the vendor is slow, so are you. Use async for independent scripts such as analytics, and defer for scripts that need the page to be ready. See render-blocking resources.
Load it when it is needed. A reviews widget at the bottom of the page does not need to load until the visitor gets near it:
const widget = document.querySelector('#reviews');
new IntersectionObserver((entries, observer) => {
if (entries[0].isIntersecting) {
observer.disconnect();
const script = document.createElement('script');
script.src = 'https://widgets.example.com/reviews.js';
script.async = true;
document.head.append(script);
}
}, { rootMargin: '300px' }).observe(widget);Put a placeholder in front of heavy things. Video players, maps and chat tools are large, and most visitors never use them. Show a picture and a button, and load the real thing when someone clicks. This is called a facade. For a video, the placeholder can be an image with a play button, replaced by the player on a click:
document.querySelectorAll('.video-facade').forEach((box) => {
box.querySelector('button').addEventListener('click', () => {
const frame = document.createElement('iframe');
frame.src = 'https://www.youtube.com/embed/' + box.dataset.id + '?autoplay=1';
frame.allow = 'autoplay; encrypted-media';
frame.allowFullscreen = true;
box.replaceChildren(frame);
});
});Give the box a fixed shape with aspect-ratio: 16 / 9, so that replacing the image with the player does not move the page. Iframes that are below the first screen can also use loading="lazy", which makes the browser wait until they are near.
Warm up only what matters. If a third-party script has to load early, a preconnect hint for its domain starts the connection sooner. Do it for one or two origins, not all of them, because every hint uses a connection.
Be careful with "delay until the first click" options. Many optimization tools offer to hold all scripts until the first interaction. The scripts then all run at once at the first tap, which is when the visitor needs the page to answer. Test the first interaction before you keep it.
Step 4: control the tag manager
A tag manager makes it easy to add a script and easy to forget one. Give it the same rules:
- Remove tags that are no longer used.
- Fire each tag only on the pages and events that need it, not on every page.
- Avoid tags that insert large amounts of HTML or run code on every click.
- Keep a record of who owns each tag.
- Test the page again after you publish a change, because a published tag runs on the live site immediately.
Step 5: keep it from growing back
Third parties arrive one at a time, each with a good reason. Three habits keep the total under control:
- One owner per script. Someone is responsible for it, and for removing it when it is no longer needed.
- A check before adding. Test the page before and after, and compare the main-thread time and the Core Web Vitals.
- A review every quarter. Open the list, and remove what nobody can explain.
How to measure what one script costs
The time a script takes is part of the page's main-thread work. See where main-thread time goes.
In Chrome DevTools you can block a single request, then reload the page and compare. Run the lab test with and without the script, three times each, and look at Total Blocking Time and the main-thread time. A script that adds a couple of hundred milliseconds of blocking for a feature few people use is a candidate for a placeholder or for removal.
Special cases
- Ads. They load more scripts and change size. Reserve a space with the right size, load them after the main content, and accept that they cost.
- Cookie and consent banners. They are required in many places, but they can be implemented lightly. Choose one that loads asynchronously and does not push the page down.
- A/B testing tools. Some hide the page until the test has run, which delays the first paint. Check how yours works.
- Chat. Load it after a delay or on a click, and do not load it on pages where nobody uses it.
- Social embeds. A static link or an image of the post costs almost nothing, and the live embed is heavy.
Check your own page
Run the free audit and open the third-party code in the report. Look at the biggest one or two companies, ask whether anyone still needs what they provide, and start there. Most sites find at least one script they can remove outright.
Sources
- Third Parties chapter of the 2025 Web Almanac: how common third parties are and how deep the chains go.
- Reduce the impact of third-party code in the Lighthouse documentation: what Lighthouse counts as third-party code.
- Efficiently load third-party JavaScript on web.dev: loading strategies.
- Identify slow third-party JavaScript on web.dev: finding the culprits.
Start here
Free website audit
Live Google data for any public page: mobile and desktop.
Mobile + desktop · Lighthouse lab test · Real-user Chrome data when Google has it
Rather have this done for you? Speed optimization · Book a call