HomeMethod

Knowledge

Web VitalsTechniquesSnippetsAnswersImpactsBottlenecks

Localize External Resources

Download and self-host third-party scripts, stylesheets, and images to eliminate external DNS and connection overhead.

Overview

Many WordPress plugins and themes load scripts, stylesheets, and images from external CDNs and third-party servers — jQuery from code.jquery.com, font files from fonts.gstatic.com, tracking pixels from ad networks, and icon fonts from cdnjs.cloudflare.com. Each new origin requires a fresh DNS lookup, TCP handshake, and TLS negotiation — adding 100–600 ms of latency per origin before any data can be received. Localizing these resources — downloading and serving them from your own server — eliminates this per-origin connection cost and enables full control over caching headers.

Impact grade, A+ to D: how much of the Lighthouse score this technique can move. Unaffected: TBT, CLS, TTFB.

The Problem

The browser’s connection budget for a new origin is expensive: a cold connection to a new domain over HTTPS requires DNS resolution (~50ms), TCP handshake (~100ms), TLS negotiation (~100–200ms), and then the first HTTP request (~100ms) — totaling 350–500ms before a single byte of the resource arrives. A page that loads resources from 6 different external origins pays this overhead 6 separate times, in parallel but all competing for the early connection window. External resources also cannot be controlled for cache headers — a CDN may specify a 1-hour max-age when a 1-year immutable cache would be more appropriate.

Performance Impact

LCP

Indirect

faster CSS and font delivery means the LCP element renders sooner

FCP

100–400ms

eliminating external origins removes connection setup latency for render-blocking resources

SI

Moderate

resources from same origin load faster and with better cache hit rates

Risk: Low

localized files do not auto-update — set calendar reminders for security patch audits

How it works

  1. 01

    Identify external resources loading on every page

    Open DevTools → Network tab, filter by domain (not your own), and note every external origin loading CSS, JS, or fonts. Focus on resources that appear on all pages (navigation, theme assets) rather than page-specific embeds.

  2. 02

    Download and host the files locally

    Download the file at the version currently being loaded. Place it in your theme’s assets directory or a CDN path you control. Update your enqueue calls (wp_enqueue_script, wp_enqueue_style) to point to the local URL.

  3. 03

    Set aggressive cache headers

    Localized files should be served with Cache-Control: public, max-age=31536000, immutable. If the file is versioned (the URL includes a hash or version number), it is safe to cache for a full year — users get the new file when the URL changes at the next update.

  4. 04

    Dequeue the original external enqueue

    In WordPress, use wp_dequeue_script() or wp_deregister_script() to remove the plugin’s or theme’s original external enqueue, then re-enqueue from the local path. The wp_enqueue_scripts hook with a priority higher than the plugin’s original enqueue ensures the replacement fires after the original registration.

Code Example

Before
<!-- jQuery UI from external CDN: new DNS + TCP + TLS per visitor -->
<script src="https://code.jquery.com/ui/1.13.2/jquery-ui.min.js"
        integrity="sha256-..." crossorigin="anonymous"></script>
After
<!-- Local copy: same origin, cached 1 year, no connection overhead -->
<script src="/wp-content/themes/my-theme/js/jquery-ui.1.13.2.min.js"></script>

In WordPress functions.php: wp_deregister_script('jquery-ui-core'); wp_enqueue_script('jquery-ui-core', get_theme_file_uri('js/jquery-ui.1.13.2.min.js'), ['jquery'], '1.13.2', true);

Limitations

  • Locally hosted libraries are not automatically updated. If the external library releases a security patch, you must manually download and replace the local copy — set a calendar reminder for version audits.
  • The shared-cache benefit of CDN-hosted libraries (e.g., many sites using the same jQuery CDN URL sharing a browser cache entry) no longer applies. In practice, browser cache partitioning in modern browsers eliminates this benefit anyway.
  • Some libraries load additional resources from their own CDN (sub-resources). Localizing the entry-point JS does not help if that script then fetches its own dependencies from external origins — inspect each script’s network activity individually.

Common Mistakes

Localizing a library but not dequeuing the original external version

If both the original external enqueue and your local version are active simultaneously, the browser loads the library twice — doubling the cost. Always deregister or dequeue the original before adding your local version.

Localizing libraries with long-running CORS dependencies

Some external scripts (Google Fonts CSS, certain analytics SDKs) are designed to receive authenticated or personalized responses from their origin. Localizing these files caches a static response that may lack the personalization the library expects — test carefully after localizing.

Test this techniqueThird PartyRun the tool

Targeted fixes, not guesswork.

Start an Engagement
Support our family now