Shopify Speed FixShopify Speed Fix
Back to Blog
Technical Guide

Defer JavaScript in Shopify: Best Practices

Master JavaScript deferring to improve First Contentful Paint and reduce blocking time.

Why This Matters

JavaScript execution blocks HTML parsing. By deferring non-critical scripts, you allow content to render faster, improving perceived performance and Core Web Vitals.

Understanding defer vs async

Three ways to load JavaScript, each with different behavior:

  • Normal: Blocks HTML parsing until downloaded and executed
  • async: Downloads in parallel, executes immediately when ready (blocks parsing)
  • defer: Downloads in parallel, executes after HTML parsing completes

When to Use defer

Use defer for scripts that:

  • Don't need to run immediately
  • Depend on the DOM being fully parsed
  • Need to execute in order (multiple defer scripts run sequentially)
  • Enhance functionality but aren't critical for initial render

Implementation in Shopify

Add the defer attribute to script tags in your theme:

<!-- In theme.liquid -->
{{ 'application.js' | asset_url | script_tag: defer: "defer" }}

<!-- Or manually -->
<script src="{{ 'theme.js' | asset_url }}" defer></script>

Scripts to Defer in Shopify

These common Shopify scripts are safe to defer:

  • Theme JavaScript (theme.js, application.js)
  • Analytics scripts (Google Analytics, Facebook Pixel)
  • Marketing widgets (email popups, reviews)
  • Social sharing buttons
  • Chat widgets

Scripts to NOT Defer

Some scripts must load synchronously:

  • Scripts that write to the page using document.write()
  • Critical functionality needed for above-fold content
  • Scripts that other deferred scripts depend on

Testing Your Changes

After implementing defer, test thoroughly:

  1. Check PageSpeed Insights for improved scores
  2. Test all interactive features work correctly
  3. Verify no console errors appear
  4. Test on mobile devices
  5. Check that apps still function properly

Common Issues and Fixes

Issue: jQuery undefined error

Scripts depending on jQuery run before jQuery loads

Solution:

// Wrap code in DOMContentLoaded
document.addEventListener('DOMContentLoaded', function() {
  // Your jQuery code here
})

Expected Performance Gains

Performance Improvements

  • • 20-30% faster First Contentful Paint
  • • Reduced blocking time by 1-2 seconds
  • • Better Lighthouse Performance score
  • • Improved mobile experience

Let Us Optimize Your JavaScript Loading

We'll properly defer all scripts and fix any compatibility issues in 48-72 hours.