Async vs Defer for JavaScript: Which to Use for SEO
Moderate 14 min 2026-03-20

Async vs Defer for JavaScript: Which to Use for SEO

Quick Summary

  • What this covers: Render-blocking JavaScript kills page speed. Use async or defer to load scripts without blocking rendering. This guide shows when to use each.
  • Who it's for: site owners and SEO practitioners
  • Key takeaway: Read the first section for the core framework, then use the specific tactics that match your situation.

JavaScript files block page rendering by default. When the browser encounters a <script> tag, it stops parsing HTML, downloads the script, executes it, then resumes parsing. This delays Largest Contentful Paint (LCP) and hurts Core Web Vitals scores.

The async and defer attributes change how scripts load. Both prevent render-blocking, but they behave differently. Use the wrong one and you break functionality. Use the right one and you shave seconds off load time without touching your code.

This guide explains how async and defer work, when to use each, and how to implement them without breaking your site.

How JavaScript Blocks Rendering (Default Behavior)

Without async or defer, scripts load synchronously:

<script src="analytics.js"></script>

What happens:

  1. Browser parses HTML
  2. Browser encounters <script> tag
  3. Browser stops parsing HTML
  4. Browser downloads analytics.js
  5. Browser executes analytics.js
  6. Browser resumes parsing HTML

During steps 4-5, rendering is blocked. The user sees a blank screen or partial page until the script finishes executing.

Impact on Core Web Vitals

Render-blocking JavaScript delays Largest Contentful Paint (LCP), one of the three Core Web Vitals metrics. If your LCP is above 2.5 seconds, Google penalizes your page speed score, which affects rankings.

What Async Does

The async attribute downloads the script in parallel with HTML parsing, then executes it immediately when the download finishes.

<script src="analytics.js" async></script>

What happens:

  1. Browser parses HTML
  2. Browser encounters <script async> tag
  3. Browser starts downloading analytics.js in the background (parallel)
  4. Browser continues parsing HTML (no blocking)
  5. When download finishes, browser pauses HTML parsing, executes the script, then resumes

Key behavior: The script executes as soon as it downloads, regardless of where the browser is in parsing HTML. Execution order is unpredictable if you have multiple async scripts.

When to Use Async

Use async for independent scripts that don't rely on other scripts or the DOM being fully loaded.

Good use cases:

Bad use cases:

Example: Google Analytics with Async

<script async src="https://www.googletagmanager.com/gtag/js?id=GA_MEASUREMENT_ID"></script>

Google Analytics doesn't depend on other scripts and doesn't need to manipulate the DOM immediately, so async is safe.

What Defer Does

The defer attribute downloads the script in parallel with HTML parsing but waits to execute until after HTML parsing completes.

<script src="main.js" defer></script>

What happens:

  1. Browser parses HTML
  2. Browser encounters <script defer> tag
  3. Browser starts downloading main.js in the background (parallel)
  4. Browser continues parsing HTML (no blocking)
  5. After HTML parsing finishes, browser executes main.js in the order scripts appear in the HTML

Key behavior: Deferred scripts execute in order after the DOM is fully loaded but before the DOMContentLoaded event.

When to Use Defer

Use defer for scripts that depend on the DOM or other scripts.

Good use cases:

Bad use cases:

Example: Deferred jQuery and Plugin

<script src="jquery.min.js" defer></script>
<script src="jquery-plugin.js" defer></script>

Both scripts download in parallel, but jquery-plugin.js won't execute until after jquery.min.js because defer preserves execution order.

Async vs Defer: Side-by-Side Comparison

Attribute Downloads Executes Blocks Rendering Execution Order Use For
None Immediately Immediately Yes Sequential Critical inline scripts only
async In parallel As soon as downloaded No (except during execution) Unpredictable Independent scripts (analytics, ads)
defer In parallel After HTML parsing No Sequential (order preserved) DOM-dependent scripts, dependencies

When to Use Async

Scenario 1: Analytics Scripts

Google Analytics, Facebook Pixel, and similar tracking scripts don't need to execute before page render.

<script async src="https://www.googletagmanager.com/gtag/js?id=YOUR_ID"></script>

Scenario 2: Ad Scripts

Ad networks (Google AdSense, Media.net) load ads independently and don't depend on page content.

<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>

Scenario 3: Third-Party Widgets

Embedded widgets (Twitter embeds, social share buttons) that don't affect core page functionality.

<script async src="https://platform.twitter.com/widgets.js"></script>

When to Use Defer

Scenario 1: Scripts That Manipulate the DOM

JavaScript that changes page elements needs the DOM to be fully parsed.

<script src="carousel.js" defer></script>

Scenario 2: Scripts with Dependencies

If Script B depends on Script A, use defer on both to preserve execution order.

<script src="library.js" defer></script>
<script src="plugin.js" defer></script>

Scenario 3: Framework Bundles (React, Vue)

Single-page application bundles need the DOM to be ready for hydration.

<script src="app.bundle.js" defer></script>

When to Use Neither (Inline Critical Scripts)

Some scripts must execute before rendering. These should be inline in the HTML and placed in the <head>.

Examples:

<head>
  <script>
    // Critical inline script
    if (localStorage.theme === 'dark') {
      document.documentElement.classList.add('dark');
    }
  </script>
</head>

Don't use async or defer for these. They must execute synchronously before the page renders.

How to Implement Async and Defer

WordPress

Manual method: Edit your theme's functions.php and add async or defer to enqueued scripts:

function add_async_defer_attributes($tag, $handle) {
  $async_scripts = array('google-analytics', 'facebook-pixel');
  $defer_scripts = array('main-js', 'jquery-plugin');

  if (in_array($handle, $async_scripts)) {
    return str_replace(' src', ' async src', $tag);
  }

  if (in_array($handle, $defer_scripts)) {
    return str_replace(' src', ' defer src', $tag);
  }

  return $tag;
}
add_filter('script_loader_tag', 'add_async_defer_attributes', 10, 2);

Plugin method: Use Autoptimize or WP Rocket to automatically defer non-critical scripts.

Shopify

Shopify's default theme scripts are already optimized. For custom scripts in theme.liquid:

<script src="{{ 'custom.js' | asset_url }}" defer></script>

HTML (Static Sites)

Add the attribute directly to the <script> tag:

<script src="script.js" defer></script>
<script src="analytics.js" async></script>

React (Next.js)

Use the Script component from next/script:

import Script from 'next/script';

export default function Page() {
  return (
    <>
      <Script src="https://example.com/analytics.js" strategy="afterInteractive" />
      <Script src="https://example.com/widget.js" strategy="lazyOnload" />
    </>
  );
}

Common Mistakes

Mistake 1: Using Async for Dependent Scripts

If Script B depends on Script A, using async on both causes unpredictable execution order.

Bad:

<script src="jquery.js" async></script>
<script src="jquery-plugin.js" async></script>

jquery-plugin.js may execute before jquery.js finishes, causing errors.

Fix: Use defer to preserve execution order:

<script src="jquery.js" defer></script>
<script src="jquery-plugin.js" defer></script>

Mistake 2: Deferring Critical Scripts

Scripts that modify the initial page render (A/B tests, theme toggles) should execute synchronously, not deferred.

Bad:

<script src="ab-test.js" defer></script>

Users see the original page before the A/B test executes, causing flicker.

Fix: Inline the script in the <head> without defer.

Mistake 3: Adding Async/Defer to Inline Scripts

async and defer only work on external scripts (those with a src attribute). They're ignored on inline scripts.

Ignored:

<script defer>
  console.log('This runs immediately despite defer');
</script>

Mistake 4: Using Both Async and Defer

Don't use both attributes on the same script. Browsers prioritize async and ignore defer.

Bad:

<script src="script.js" async defer></script>

Pick one.

Testing Async and Defer Impact

Before: Baseline Test

Run Google PageSpeed Insights or WebPageTest to measure LCP and render-blocking resources.

After: Add Async/Defer

Add async to analytics scripts and defer to DOM-dependent scripts. Re-test.

What to Look For

Async, Defer, and SEO

Direct Impact on Rankings

Async and defer improve Core Web Vitals, which is a ranking factor. Faster LCP correlates with better rankings.

Impact on Crawl Efficiency

Googlebot renders JavaScript, but faster-loading pages are crawled more efficiently. Reducing render-blocking scripts means Googlebot can index your content faster.

Impact on User Experience

Faster pages reduce bounce rate and increase engagement. These user signals indirectly affect rankings.

Frequently Asked Questions

Can I use async and defer together?

No. Browsers prioritize async and ignore defer if both are present. Choose one.

Does defer work for inline scripts?

No. defer only applies to external scripts (those with a src attribute). Inline scripts always execute immediately.

Should I defer jQuery?

Only if you also defer all jQuery plugins and ensure no inline scripts depend on jQuery. Otherwise, inline scripts will fail because jQuery hasn't loaded yet.

What if my script breaks with async or defer?

Switch from async to defer (if execution order matters) or inline the script (if it must run before rendering). Test thoroughly.

Do async scripts execute before DOMContentLoaded?

Maybe. Async scripts execute whenever they finish downloading, which could be before or after DOMContentLoaded. If your script needs the DOM, use defer instead.

Next Steps

Audit your site's JavaScript using Google PageSpeed Insights. Identify render-blocking scripts. Add async to independent scripts (analytics, ads). Add defer to DOM-dependent scripts and scripts with dependencies. Re-test to verify LCP improvement. For related optimization, see Defer JavaScript Without Breaking Your Site, Remove Render-Blocking Resources, and Combine External Scripts for Performance.


When This Fix Isn't Your Priority

Skip this for now if:

This is one piece of the system.

Built by Victor Romo (@b2bvic) — I build AI memory systems for businesses.

← All Fixes