Map dependencies before choosing an attribute

How to defer JavaScript safely

Use async for independent code, defer for an ordered chain, and event-driven loading for an optional heavy feature. Decide per script after confirming its purpose.

Decision flow between defer, async and event-driven JavaScript loading
Applying one attribute to every tag can break initialization order.

The safest route

Message for support or a developer

“Find synchronous external JavaScript in head, map dependencies, and propose defer, async or event-driven loading per file. Back up first, do not delay critical code blindly, and test menus, forms, cart, checkout, analytics, Console and waterfall on desktop/mobile.”

Back up templates and build configuration, enable asset versioning and record working journeys. Change one group at a time so a regression remains attributable.

Implementation steps

  1. Filter JS in DevTools → Network and find synchronous external tags in source HTML.
  2. Record each file's owner, purpose, dependencies and expected DOM elements.
  3. Keep code synchronous only when a test proves it is critical.
  4. For library → plugin → initialization chains, add defer to every external participant in the required order.
  5. Use async for independent analytics or integrations only when order is irrelevant.
  6. Load an optional below-the-fold widget near its viewport entry or deliberate interaction, with a visible trigger and error state.
  7. Clear caches and repeat waterfall and functional journeys on desktop/mobile with a throttled network.

Technical reference

Ordered dependencies

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

defer preserves order for external classic scripts and runs them after HTML parsing.

Independent script

<script async src="https://vendor.example/analytics.js"></script>

async runs when downloaded and does not guarantee order against neighboring tags.

type="module" is deferred by default; confirm the project's legacy-browser and nomodule strategy. defer has no effect on a classic inline script without src.

Risks, rollback and verification

Common execution-order failures
SymptomCauseAction
… is not definedConsumer ran before its dependencyRestore order and use defer for the chain
Button responds only on a second attemptHandler attached too lateInitialize a light handler earlier
Analytics events disappearEvent queue was not created earlyRestore the vendor's supported bootstrap
Render improves but INP worsensHeavy work moved onto interactionSplit it or prepare it during idle time

To roll back, restore the previous tags and build, clear caches and repeat critical actions. Then perform the independent audit. Minification, code removal and logic repair are separate work.