Render-blocking JS checker

Find JavaScript files that block page rendering and slow down display

Free
No sign-up
Instant results

Check results

This check only covers render-blocking JS. For a full picture of your page, run a page audit.

For issues across your whole site — duplicate titles, orphan pages, broken internal links — run a site audit.

Want us to fix what we found? Our team can help.

What are render-blocking resources and why they matter

Render-blocking resources are scripts (and stylesheets) that pause the browser's HTML parser until they download and execute. A <script src="..."> tag without async, defer, or type="module" tells the browser: "stop parsing, get this file, run it, then continue." During that pause, nothing further renders. The visible effect is a blank (or half-rendered) page for longer than necessary. Measurable impact: slower First Contentful Paint (FCP) and Largest Contentful Paint (LCP) — both Core Web Vitals metrics that Google uses as ranking signals. Rendering-blocking scripts are one of the top issues flagged by PageSpeed Insights.

What this tool checks

  • External scripts — every <script src="..."> on the page
  • Placement analysis — scripts in <head> are classified as critical (blocks first paint); scripts in the middle of <body> block subsequent content; scripts at the end of <body> are acceptable
  • async / defer / type="module" — these attributes remove the blocking behaviour and get a pass
  • Large inline scripts in <head> — inline code over ~3 KB runs synchronously and blocks parsing just like external scripts

Difference between async and defer

  • No attributes — browser pauses HTML parsing, downloads the script, executes it, then continues
  • async — script downloads in parallel with parsing but executes as soon as it arrives (pauses parsing briefly). Order not guaranteed.
  • defer — script downloads in parallel and executes only after parsing is complete, in document order
  • type="module" — ES modules are deferred by default; no need to add defer explicitly
  • When to use which — defer for DOM-dependent scripts; async for independent ones (analytics, ads, widgets); module for modern JS

Good vs bad examples

Good — defer in head for DOM-aware code:

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

Good — async for independent analytics:

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

Good — classic "at end of body" pattern (rendering is done, blocking effect is minimal):

<body>
  <main>...</main>
  <script src="/app.js"></script>
</body>

Bad — sync script in head blocks the first paint:

<head>
  <script src="/app.js"></script>  <!-- blocks FCP -->
</head>

Bad — sync script mid-body pauses rendering of subsequent content:

<main>
  <h1>Hero</h1>
  <script src="/ad.js"></script>  <!-- blocks everything below -->
  <article>...</article>
</main>

Bad — large inline script in head (same blocking effect as external, but you can't even cache it):

<head>
  <script>
    // 5 KB of application initialization inlined here
  </script>
</head>

Common mistakes

  • Analytics in <head> without async — the classic FCP killer. Analytics scripts should almost always be async.
  • Third-party widgets inline in body — chat widgets, ad scripts, social embeds dropped in the middle of <body> pause rendering of everything below. Use async or load on user interaction.
  • Copy-pasting vendor snippets without async/defer — many vendor integration docs still show blocking snippets. Always add async unless the documentation explicitly requires otherwise.
  • Using async for ordered scripts — async doesn't preserve execution order. If script A depends on script B, use defer on both instead.
  • Large inline scripts in head — same blocking effect as external scripts, but inlined code can't be cached across pages and bloats every HTML response.
  • Assuming "end of body" is always fine — it's better than <head> without async/defer, but defer is still safer (executes after DOMContentLoaded, guaranteed order).

Frequently asked questions

Not always. If a script depends on another script or must execute in a specific order, async may break things. In such cases, use defer — it preserves script execution order. Also, async/defer cannot be added to inline scripts (without src attribute) — these attributes only work with external files.
Blocking scripts slow down First Contentful Paint (FCP) and Largest Contentful Paint (LCP) — key Core Web Vitals metrics. Google considers these metrics for ranking. Additionally, if Googlebot doesn't wait for scripts to execute, some content may not be indexed. Eliminating render-blocking resources is one of the main PageSpeed Insights recommendations.
CSS always blocks rendering by default — the browser won't paint the page until all styles are loaded. But this is normal behavior; otherwise, users would see a flash of unstyled content. JavaScript blocks HTML parsing itself, which is worse because subsequent DOM nodes can't even be constructed. Priority is to remove blocking JS via async/defer; for CSS, inline critical styles and load the rest asynchronously via rel="preload" or media queries.
Blocking scripts pause HTML parsing from their position forward. A script in <head> blocks the browser from parsing and rendering any content — the user sees a blank page during download + execution. A script at the very end of <body> blocks parsing of whatever comes after it, which is nothing — so the visible effect is minimal. It's the old-school pre-async technique (2010-2015) and still works, just slightly worse than using defer (which downloads in parallel).
Not yet. This check focuses on JavaScript; CSS render-blocking analysis is a separate check we plan to add. CSS is more nuanced — all stylesheets block rendering by default (usually correctly, to avoid the flash of unstyled content), so the analysis has to distinguish "critical" CSS from "non-critical" that should be deferred via media queries or preload.