Third-party scripts are a necessity in the modern web. They allow website owners to embed videos and social sharing buttons, analyze their website’s performance, and much more.
Often, these scripts are crucial for one’s website functionality and revenue streams. However, third-party resources come with many hidden risks that may hinder your site’s overall performance.
That’s why it’s important to minimize their negative impact while still utilizing their valuable features.
And in the following lines, you’ll learn how to do that.
Let’s dive in!
Nowadays, running a website without a single third-party script seems not only impossible but rather impractical.
Regardless of your site’s type, there are certain functionalities that you and your visitors need to have access to.
For instance, you run a personal blog and want your content to reach as many people as possible. One solution is to add social sharing buttons.
Furthermore, you want to analyze your visitors’ behavior on your website in depth. For that, you’ll need tools like Hotjar and Google Analytics. At some point, you’d like to monetize your work, and a great way to do that is by adding advertising iframes.
In short:
To get the most out of your site, you need to rely on 3rd party scripts. And there’s nothing wrong with that, at least in most cases.
Unfortunately, embedding third-party resources means you rely on them to be fast in order to avoid slowing down your site. Hence, it’s normal for them to be the predominant cause of performance slowdowns as they’re outside your control.
Here are some of the issues that you might face when integrating third-party scripts into your website:
Sending too many network requests to multiple servers causes slowdowns. That time is even longer for secure connections, which may involve DNS lookups, redirects, and several round trips to the final server that handles the user's request.
The Main Thread is where the browser does most of the work needed to display a page. That’s why it’s crucial to minimize Main Thread work as much as possible.
JavaScript runs on the Main Thread by default. When the Main Thread is busy with JavaScript, it can't perform vital tasks like rendering the page or responding to user input. That's why JavaScript is a render-blocking resource. As a result, you’ll end up with a slow loading, non-interactive website - the best formula to lose customers immediately.
Having insufficient HTTP caching forces resources to be fetched from the network more often. And this is both slow and expensive (in both speed and server resources), especially when those network requests are sent to multiple servers.
As a consequence, your page will load slowly. Even worse, when visitors access your site with a limited mobile data plan, every unnecessary network request is a waste of their money.
Loading third-party scripts asynchronously is one of the solutions when it comes to optimizing their work. However, some scripts cannot be loaded asynchronously because they use document.write().
The bigger issue, however, is the use of document.write() inside pages, specifically those uses that inject scripts. If the script dynamically injects another script, the parser is forced to wait even longer for the resource to download, which can incur one or more network round trips and delay the time to first render of the page:
document.write() can delay the display of page content by tens of seconds and is particularly problematic for users on slow connections (e.g., 2G). While 2G has reached its sunset date in many countries, there are still users around the world that heavily rely on it to browse the web.
That’s why Chrome intervenes against document.write(), meaning you can't rely on it.
The window.onload event says to fire a function only once the window and all its HTML tags, fonts, and images are loaded. Basically, it’s a way for the browser to notify the code that it has completed loading the initial resources of a page.
Oftentimes, the interactive elements on a page become interactive after this event. If it gets delayed, the page will take more time to respond to user input.
And in some cases, third-party scripts use techniques that can block the window.onload event if their server responds slowly. Resulting in a bad user experience.
The truth is that context is important when it comes to optimizing the work of third-party scripts. It all depends on your site and your ability to identify the resources that cause the problems and then configure them to load more efficiently.
Thankfully, there are a number of free resources that you can use to identify and measure costly third-party scripts.
Let’s take a look at some of them.
The first step to solving the third-party resource problem is to identify and measure the most impactful ones.
Tools like Google’s PageSpeed Insights, WebPageTest, and Chrome DevTools will highlight all third-party scripts that your website is loading and show which ones take the most time.
Google’s PageSpeed Insights is the easiest way to identify and measure third-party scripts on your website. The “Reduce the impact of third-party code” audit is a good starting point:
It lets you instantly see how impactful the third-party scripts on your site are. In the example above, you can see that they blocked the Main Thread for 2,490 ms.
You can dig deeper by going through the list of all third-party code that is executed on your site. The great thing is that PSI sorts it by Main-Thread Blocking Time. This evaluation allows you to focus on the most impactful ones and start working on them.
Another audit you might benefit from is the Treemap:
It shows all JavaScript files executed on your website, sorted by their size:
And next to the Resource Bytes column, you have the Unused Bytes one, showing what % of the JS remains unused.
WebPageTest’s content breakdown by domain is another valuable tool for debugging third-party issues. Going to the Domain section, you will see a thorough breakdown by the number of requests and bytes for each domain:
WebPageTest also has a waterfall chart where you can see all the render-blocking resources and allocate all third-party scripts and their execution time:
Once you find third-party resources that might be causing issues, it’s time to test if they are really the culprit. Go back to WebPageTest’s home page, open the Advanced settings, and click on the Block feature:
Then you can specify the domains you would like to block by entering them in the forms below. Test again and see if there is any improvement.
Another great way to analyze possible issues even deeper is using Chrome’s DevTools. Just open a web page, right-click and select “Inspect”. Then, capture the page load and go to the “Performance” panel.
Clicking the record button and re-loading your page presents you with a waterfall (similar to the one in WebPageTest):
At the bottom of the Performance panel, you will see the “Bottom-up” tab:
Click on the drop-down menu and select “Group by Domain.” In the example above, we can see how moatads.com contributes 22.7% of the work that happens when loading the page.
Using this knowledge, you can more accurately pinpoint problem areas and begin investigating with some evidence behind you. Once you’re done identifying the culprit, you can block the specific third-party script to see how impactful it really is.
Go to the “Network” panel, right-click on the resource and select “Block request URL”:
This is a great way to see what the absence of a particular asset would have on the current page.
Now, let’s see how to deal with third-party resources.
There are several optimization techniques that you might want to try when working with third-party scripts:
Let’s take a closer look at each of them.
A single web page is constructed of different resources. However, not all of them are critical for providing the best user experience right from the start.
Users want to see content being painted quickly and experience a website that becomes interactive immediately. That’s why it’s good to keep an eye on these several metrics:
In short:
Your site needs to be fast and interactive to retain your visitors longer —or at least give that impression.
This is where lazy loading comes into play. Typically used in the context of images, you can lazy load (defer) third-party resources as well, making them load only when necessary. This way, you can focus on serving the most critical content (above the fold) first and load everything else once the visitor scrolls down.
Going back to our example of a person running their own blog, they might be serving an ad in their website’s footer. If they lazy load it, it will be served only when a visitor scrolls down to it.
NitroPack offers a JavaScript lazy loading feature that works based on user interaction and it is enabled by default with our Ludicrous mode. It prioritizes HTML and CSS files, while deferring JS files, resulting in faster content painting and a better user experience.
On top of that, you can fine-tune the JavaScript feature by listing scripts that you want to exclude from optimizations and scripts that must be delayed:
Synchronously loaded scripts delay DOM construction and block rendering. That’s why you should load third-party scripts asynchronously (unless the script has to run before the page is rendered).
The async and defer attributes allow the browser to parse the HTML while loading the render-blocking scripts in the background. This way, script downloads don't block DOM construction and page rendering, resulting in faster loading and happier visitors.
While both attributes make scripts non-blocking, they also have some differences:
Put simply, scripts that need the DOM or whose order is important should use the defer attribute. Conversely, ad, analytics, and other independent scripts should generally use async.
Speaking of the async attribute, some third-party resources can’t be loaded asynchronously because they use document.write().
document.write() is particularly used for older services that haven’t been updated recently. However, third-party scripts using it can delay the page rendering by seconds, which is particularly problematic for users on slow connections (e.g., 2G).
In fact, it has such a negative impact on performance that Chrome decided to intervene:
The fix for document.write() is to simply not inject scripts using it. As of Chrome 53, Chrome DevTools logs warnings to the console for problematic use of document.write():
We started this article by saying that 3rd party scripts are resources outside of your control which makes them harder to manage.
Well, self-hosting them is an option that will give you more control over a scripts’ loading process. Furthermore, it also lets you:
Although it might sound like it, self-hosting isn’t the perfect solution and there are some caveats you need to consider:
An alternative to self-hosting scripts, where you still have more control, would be using Service Workers. We won’t dig deeper into the topic right now, but if you’re interested, check Matt Gaunt’s article on Service Workers.
Apart from heavy JavaScript files, you might want to self-host third-party fonts as well. According to Ilya Grigorik:
As opposed to many third-party scripts, font resources are typically static and not updated frequently. Put simply, they offer easier maintenance compared to self-hosted third-party scripts.
However, you should make sure that the font’s license allows self-hosting. Otherwise, you might be breaking the law. A popular service that allows self-hosting their fonts is Google Fonts.
Browsers go through three stages to establish a connection with a server - turning the domain name into an IP address, setting up a connection to the server, encrypting the connection for maximum security.
In each of these steps, the browser sends a piece of data, and the server sends back a response. This is called a round trip.
Depending on the network conditions, a single round trip might take a significant amount of time. That’s why implementing resource hints like
and
can optimize the browser's work, making your website/application load faster.
It’s far easier to remove a script than to optimize it. Or is it?
You should regularly check for unused third-party scripts and remove them entirely.
You can check if you have unused JavaScript in Chrome’s DevTools. Use the “Coverage” tab to find these code snippets:
This is a really good practice for CMS websites, where third-party code is regularly inserted via plugins and might be left over after the plugin is no longer used. Running a simple audit like the one shown above can lead to an easy performance boost. Or you can check out our guide on removing inactive plugins.
We covered a lot of ground with this article, so let’s end with a quick recap of the most important points:
After every optimization, don’t forget to test your website in the real world. Focus on real-user metrics (like the Core Web Vitals’ field values) to make sure your work has a positive impact on your visitors.
Niko has 5+ years of experience turning those “it’s too technical for me” topics into “I can’t believe I get it” content pieces. He specializes in dissecting nuanced topics like Core Web Vitals, web performance metrics, and site speed optimization techniques. When he’s taking a breather from researching his next content piece, you’ll find him deep into the latest performance news.