third-party
Teaches strategies for mitigating third-party script performance impact. Use when third-party scripts like analytics, ads, or widgets are degrading your page load times or Core Web Vitals.
By patternsdev · 1,076 installs
npx skills add patternsdev/skills --skill third-party
Source repository · Upstream listing
Optimize loading third parties
Table of Contents
[When to Use]( when to use)
[Instructions]( instructions)
[Details]( details)
[Source]( source)
When to Use
Use this when third party scripts (analytics, ads, chat widgets, social embeds) are slowing down your site
This is helpful for optimizing Core Web Vitals while retaining essential third party functionality
Instructions
Use async or defer attributes for non critical third party scripts
Establish early connections with preconnect and dns prefetch resource hints
Lazy load below the fold embeds (YouTube, maps, social media) using IntersectionObserver or facades
Consider self hosting critical third party scripts for better caching control
Use the Next.js Script component with appropriate strategy values for framework level optimization
Details
It would be hard to find a modern site that operates in silos. Most sites coexist and depend on several other sources on the web for data, functions, content, and much more. Any resource located on another domain and consumed by your site is a third party (3P) resource for your site. Typical third party resources that are included on sites include:
Embeds for maps, videos, social media, and chat services
Advertisements
Analytics components and tag managers
A/B testing and personalization scripts
Utility libraries that provide ready to use helper functions such as those used for data visualization or animations.
[reCAPTCHA](https://www.google.com/recaptcha/about/) or CAPTCHA for bot detection.
You can use third parties to integrate other features that add value to your content or to reduce some drudgery involved in building a site from scratch. As per the Web Almanac report for 2021, more than [94% of the pages](https://almanac.httparchive.org/en/2021/third parties prevalence) on the web use third parties [images and JavaScript](https://almanac.httparchive.org/en/2020/third parties content types) forming the most significant contributors to third party content.
While third party resources can enrich your site with valuable features, they can also slow it down if:
They cause additional round trips to the third party domain for every required resource.
They make heavy usage of JavaScript (impacting download and execution time) or are bulky in size because of unoptimized images/videos.
Individual site owners cannot influence the implementation, and their behavior can be unpredictable.
They can block the rendering of other critical resources on the page and affect [Core Web Vitals](https://web.dev/vitals/) (CWV).
Despite these issues, third parties may be essential to your business. If you cannot do away with 3P's, the next best thing is to optimize them to reduce performance impact.
Assessing the performance impact of 3P resources
You can use a combination of techniques to find how third party code is affecting your site.
The following Lighthouse audits help identify slow third party scripts that affect CWV:
[Reduce the impact of third party code](https://web.dev/third party summary/) for scripts that block the main thread.
[Reduce JavaScript execution time](https://web.dev/bootup time/) for scripts that take long to execute
[Avoid enormous network payloads](https://web.dev/total byte weight/) for large scripts
Use the WebPageTest (WPT) waterfall chart to identify [third party blocking scripts](https://nooshu.com/blog/2019/10/02/how to read a wpt waterfall chart/ third party blocking javascript) or WPT side by side comparison to [measure the impact of 3rd party tags](https://andydavies.me/blog/2018/02/19/using webpagetest to measure the impact of 3rd party tags/).
Sites like [Bundlephobia](https://bundlephobia.com/) help to assess the cost of adding available npm packages to your bundles. You can also find size and dependencies included in any package using [npm package search](https://www.npmjs.com/package/).
Optimization strategies
Since third party code is not under your control, you cannot optimize the libraries directly. This leaves you with two options.
1. Replace or remove : If the value provided by the third party script is not proportional to its performance cost, consider removing it. You can also evaluate other alternatives that are lightweight but provide similar functionality.
2. Optimize the loading sequence : The loading process involves loading several first party and third party resources in the browser. To design an optimal loading strategy, you would need to consider the browser assigned priority for different resources, their position on the page, and the value of each resource for the web page.
Load 3P scripts efficiently
Following are the time tested best practices that can reduce the performance impact of third party resources when used correctly.
Use async or defer to prevent scripts from blocking other content.
Applicable to: Non critical scripts (tag managers, analytics)
JavaScript download and execution is synchronous by default and can block the HTML parser and DOM construction on the main thread. Use of [async](https://developer.mozilla.org/en US/docs/Web/HTML/Element/script attr async) or [defer](https://developer.mozilla.org/en US/docs/Web/HTML/Element/script attr defer) attributes in the <script element tells the browser to download scripts asynchronously. You can use these to download any script that is not necessary for the critical rendering path (e.g., the main UI component).
defer : the script is fetched in parallel as the parser executes, and script execution is delayed till the parsing is complete. Defer should be the default choice for delaying execution until after DOM construction.
async : the script is fetched in parallel while parsing but executed as soon as it is available when it blocks the parser. For module scripts with dependencies, the script and all its dependencies are executed in the defer queue. Use async for scripts that need to run earlier in the loading process. For example, you may want to execute specific analytics scripts early without missing any early page load data.
One caveat worth mentioning here is that async and defer lower the browser assigned priority of the resources causing it to load significantly later. A new feature for [priority hints](https://web.dev/priority hints/) can help to work around this problem.
Establish early connections to required origins using resource hints
Applicable to: Critical scripts, fonts, CSS, images from third party CDNs
Connecting to third party origins can be slow due to the DNS lookups, redirects, and multiple round trips that may be required for each third party server. Resource hints dns prefetch and preconnect help cut down the time needed for this setup by initiating the connections early in the life cycle.
Including a [dns prefetch](https://developer.mozilla.org/en US/docs/Web/Performance/dns prefetch) resource hint corresponding to a domain will perform the DNS lookup early, thus reducing the latency associated with dns lookups. You can pair this with [preconnect](https://developer.mozilla.org/en US/docs/Web/HTML/Link types/preconnect) for the most critical resources. The preconnect initiates a connection with the third party domain by performing TCP round trips and handling TLS negotiations in addition to the DNS lookup.
Benefits of using resource hints are evident in this case study where Andy Davies discusses how using [preconnect helped reduce the loading time](https://andydavies.me/blog/2019/03/22/improving perceived performance with a link rel equals preconnect http header/) for the main product image by initiating an early connection to the third party image CDN.
Similarly, you may use resource hints to optimize loading time for critical third parties like bot detection (reCaptcha) and consent management.
Lazy load below the fold 3P resources
Applicable to: Embeds such as YouTube, Maps, Advertisements and Social media
Third party embeds like those used for social media feeds, advertisements, YouTube videos, and maps can slow down web pages. However, all such embeds may not be visible to users on page load and may be lazy loaded as the user scrolls down to them. You can use different lazy loading methods depending on desired browser support.
1. The [loading](https://web.dev/iframe lazy loading/) attribute can be used with images and iframes commonly used to load third party embeds like those for YouTube or Google Maps.
2. A custom implementation using the [IntersectionObserver API](https://developers.google.com/web/updates/2016/04/intersectionobserver) allows you to detect when the observed element enters or exits the browser's viewport.
3. [Lazy sizes](https://github.com/aFarkas/lazysizes) a popular JavaScript library that implements lazy loading for you.
A variation of lazy loading embeds uses a static or dynamic facade displayed to users on page loads. Instead of the map embed, you can use a static image of the actual embed. Solutions include the [Map Static API](https://developers.google.com/maps/documentation/maps static/overview) for maps, [Tweetpik](https://tweetpik.com/) for Twitter embeds, [lite youtube embed](https://github.com/paulirish/lite youtube embed) for YouTube, [React live chat loader](https://github.com/calibreapp/react live chat loader) for chat widgets. A comprehensive discussion on these techniques is available [here](https://web.dev/embed best practices/).
A few caveats concerning lazy loading and facades:
The behavior for the YouTube facade is slightly different on iOS and Safari on macOS 11+. Tapping/clicking the first time loads the actual video embed. Users will have to tap again to play the video.
Lazy loading can lead to layout shifts and affect the user experience if the size of the embed is not specified. To prevent layout shifts, you should specify the size for all lazy loaded embeds or their container elements.
Self host 3P scripts to prevent round trips
Applicable to: JavaScript files, fonts
Although preconnect or dns prefetch allows you to initiate connections to third party origins early, the connections are still required. Also, with third party origins, you need to rely on their caching strategy, which may not be optimal.
Self hosting a copy of the scripts on the same origin offers you more control over the loading and caching process used for the scripts. Self hosting reduces the time required for DNS lookup and allows you to improve the caching strategy for the scripts using [HTTP caching](https://developers.google.com/web/fundamentals/performance/optimizing content efficiency/http caching). You can also use [HTTP/2 server push](https://www.smashingmagazine.com/2017/04/guide http2 server push/) to push scripts that you know the user will need. A great example of how self hosting third party scripts is [Casper.com](https://casper.com/) which improved the start render time for its home page by 1.7 seconds by self hosting third party scripts provided by [Optimizely](https://www.optimizely.com/).
With self hosted copies of third party scripts, you have to ensure that you update your copy regularly based on changes to the original. Without updates, the script may become outdated, missing important fixes or changes corresponding to dependencies. Self hosting on a server instead of a CDN will also prevent you from taking advantage of [edge caching](https://www.cloudflare.com/learning/cdn/glossary/edge server/) mechanisms employed by CDNs.
Use service workers to cache scripts where possible
Applicable to: JavaScript files, fonts
Self hosting may not be an option for scripts that change frequently. You can use service workers to improve caching for such third party scripts while also utilizing CDN edge caching. This technique gives you better control over the frequency of re fetches over the network. This technique can be combined with preconnects to further red