JS Checker Fixes: JavaScript Errors, Weight and Crawlability
JavaScript runs menus, forms, baskets, tracking and, on many modern sites, the content itself. When it goes wrong, visitors rarely see an error message; a button just stops working or the page feels sluggish.
Our JavaScript Checker loads your page in headless Chromium, captures console errors and warnings, measures bundle size and parse and execution time, flags render-blocking scripts, lists third-party tags with their cost, and compares the rendered page with what a crawler receives. This page explains each finding and links the guide that fixes it.
The three kinds of JavaScript problem
Every finding the checker reports belongs to one of three families. Knowing which family a problem is in tells you who needs to fix it and how urgent it is.
1. Things that are broken
Syntax errors and uncaught exceptions stop code from running. A syntax error prevents the whole script
file from executing, so every feature in that file is lost, not just the line with the mistake. An uncaught
runtime error, such as TypeError: Cannot read properties of null, stops the current task
and anything that depended on it. Failed requests for script files (404s) and blocked cross-origin requests
fall into this family too.
2. Things that are slow
Scripts that block rendering, bundles that are too large, and long tasks that hog the browser's main thread make pages slower to appear and slower to respond. These show up as poor First Contentful Paint, Largest Contentful Paint and, most of all, Interaction to Next Paint, because the browser cannot respond to a tap while it is busy running script.
3. Things that are invisible to machines
Content, links or metadata that only exist after JavaScript runs may not be seen by every crawler. Google renders pages in a recent version of Chromium, but rendering can happen after the initial crawl and can fail if scripts error or resources are blocked. Many other crawlers, including a number of AI crawlers, are widely reported to read only the raw HTML.
How scripts load: defer, async and modules
A plain <script src> in the head makes the browser stop reading the HTML, download
the script, run it, and only then carry on. On a slow connection that can add seconds before anything
appears. The fix is almost always to tell the browser it does not need to wait.
| How it is loaded | Blocks HTML parsing? | When it runs | Good for |
|---|---|---|---|
| Plain script in the head | Yes | Immediately, in order | Very little: tiny inline code that must run before anything else |
defer | No | After the HTML is parsed, in document order | Most site scripts that work with the page |
async | Not while downloading; briefly when it runs | As soon as it arrives, in any order | Independent scripts such as analytics |
type="module" | No | Deferred by default | Modern code split into modules |
Because deferred scripts keep their order, switching from plain to defer is usually safe
for scripts that depend on each other. Switching to async is not, since a library and the
code that uses it may run in the wrong order. Inline scripts that call a deferred library also need moving
or wrapping so they wait for it.
Downloading is only part of the cost. Once a script arrives, the browser has to parse, compile and execute it, and on a mid-range phone that takes several times longer than on a developer laptop. That is why the checker reports parse and execution time alongside file size: a script that downloads quickly can still hold up the main thread for a long time.
JavaScript and crawlers
If your page's main text, internal links, title or canonical tag are created by JavaScript, it matters how search engines and AI systems handle rendering.
Google crawls the HTML first, then queues the page for rendering in an evergreen Chromium browser,
and uses the rendered result for indexing. For most sites this works, but it depends on your scripts
running without errors, on Google being allowed to fetch your script and API files, and on content appearing
without a click or scroll. Links must be real <a href> elements to be followed; click
handlers on other elements are not links to a crawler.
Other crawlers vary. Some render JavaScript, many do not, and behaviour changes over time. If you want a page's content to be reliably read by search engines and AI assistants alike, the safe approach is to make sure the important content is in the HTML the server sends.
Ways to get content into the initial HTML
- Static generation: build the HTML at deploy time. Ideal for content that changes occasionally.
- Server-side rendering: build the HTML per request, then add interactivity in the browser.
- Hybrid approaches: most modern frameworks let you choose per route, and some send only the interactive parts as JavaScript.
Dynamic rendering, where bots are served a different pre-rendered version from users, still works but Google describes it as a workaround rather than a long-term solution. Prefer rendering the same HTML for everyone.
The fix guides
Each guide covers one checker finding: how to confirm it, how to trace it to the responsible code and how to fix it.
Errors
Fixing JavaScript syntax errors
covers unterminated strings, mismatched brackets, bad merges and minification problems, and using source
maps to get from a minified bundle back to the original line. Fixing
console errors at page load covers common TypeError and ReferenceError
messages, missing script files and cross-origin errors, and how to sort your own errors from third-party
ones.
Speed and responsiveness
Fixing render-blocking scripts
covers choosing between defer, async and modules, and what to keep inline.
Fixing oversized bundles covers code
splitting by route, lazy-loading components, tree shaking and replacing heavy libraries with smaller
ones. Fixing long tasks covers breaking
work into chunks, yielding back to the browser, and moving heavy computation into Web Workers to improve
INP. Fixing third-party tag bloat
covers auditing tags, managing them through a tag manager, server-side tagging and removing the ones
that no longer pay their way.
Reliability and crawlability
Fixing memory leaks covers listeners, timers and observers that single-page apps forget to clean up, and using the DevTools Memory panel to find them. Fixing JavaScript that crawlers cannot render covers checking what crawlers see and moving key content into server-rendered or static HTML.
By platform
React and Next.js covers hydration mismatches, effect clean-up, bundle splitting and choosing server or client rendering per page. WordPress covers theme and plugin script conflicts, jQuery dependencies and deferring scripts without breaking page builders. Shopify covers theme scripts, app embeds and leftover code from uninstalled apps.
Which findings to fix first
- Errors in your own code on key journeys. A console error on the checkout, contact form or booking page may mean the feature is broken for some visitors right now. Reproduce it, fix it and add a test.
- Content crawlers cannot see. If the main text or links of important pages only exist after JavaScript runs, that can limit how the page is indexed and cited. This is structural work, so plan it early.
- Render-blocking scripts. Adding
deferis often a one-word change with a clear effect on first paint. - Third-party tags. Remove unused tags before optimising the rest; it is the cheapest saving available.
- Long tasks and bundle size. These drive INP and need more engineering time. Focus on the interactions people use most, such as opening the menu, filtering products or adding to basket.
- Memory leaks and third-party errors. Important on long-lived single-page apps; for errors inside vendor code, report them to the vendor and consider alternatives.
Order of work
- Run the checker. Test your key templates with the JavaScript Checker and save the console log, the script list with sizes and timings, and the rendered-versus-raw comparison.
- Sort errors by owner. Split them into your code, your platform or theme, and third parties.
- Fix breaking errors first, using source maps to find the original file and line.
- Check crawlable content. Compare the raw HTML with the rendered page and list anything important that only appears after scripts run.
- Unblock rendering. Add
deferorasyncwhere appropriate and test that everything still works. - Cut weight. Remove unused tags and libraries, split bundles by route and lazy-load features used by few visitors.
- Improve responsiveness. Profile slow interactions in the DevTools Performance panel and break up the long tasks behind them.
- Re-run and monitor. Test again, then keep an eye on error monitoring and real-user INP.
For more detail, see the JS Checker Guide, the example report or the beginner tutorial. For how JavaScript affects the three Core Web Vitals, read the Core Web Vitals Guide.
1. Do JavaScript console errors affect SEO?
Not directly; search engines do not score pages on console output. The risk is indirect. If an error stops a script that builds content, links or metadata, that material may be missing when Google renders the page. If an error breaks a form or basket, visitors cannot complete what they came to do. So check whether each error actually stops something working. An error that breaks content or a key journey is urgent; a harmless warning is not.
2. What is the difference between async and defer?
Both let the browser keep reading the HTML while a script downloads. A deferred script waits until the HTML has been fully parsed and then runs in the order it appears in the page, which makes it safe for scripts that depend on each other. An async script runs as soon as it finishes downloading, in whatever order that happens, so it suits independent scripts such as analytics. For most site code, defer is the safer default.
3. Can Google see content loaded by JavaScript?
Usually, yes. Google renders pages with a recent version of Chromium and indexes the rendered result. But rendering can happen some time after crawling, it depends on your scripts running without errors and on Google being allowed to fetch them, and content that appears only after a click or scroll may be missed. Other search engines and many AI crawlers are less capable. Putting important content in the server-sent HTML is the most reliable approach.
4. How big should my JavaScript bundle be?
There is no official limit, and the right size depends on what the page needs to do. What matters is how much script has to download, parse and run before the page is usable, especially on mid-range phones. A reasonable approach is to send only the code each page needs, load everything else on demand, and set a budget for your key templates that you check on every release. The checker's size and timing figures give you a baseline.
5. What is a long task?
A long task is any piece of work that keeps the browser's main thread busy for more than 50 milliseconds. While it runs, the browser cannot respond to taps, clicks or key presses, so the page feels frozen. Long tasks during an interaction are the main cause of poor Interaction to Next Paint. They are fixed by doing less work, splitting it into smaller chunks that give the browser a chance to respond in between, or moving it to a Web Worker.
6. Should I remove jQuery from my site?
Only if it is practical. jQuery itself is not especially large, and many WordPress themes and plugins depend on it, so removing it can break things. The bigger costs usually come from the plugins and scripts built on top of it. If your own code uses jQuery for a few simple tasks, modern browser features can replace it. If your theme depends on it, focus on loading it without blocking rendering and on removing plugins you do not need.
7. How do I find which script is slowing my page down?
Start with the checker's list of scripts, which shows each file's size and how long it takes to parse and run, including third-party tags. Then record a page load and a typical interaction in the Performance panel of Chrome DevTools with CPU throttling switched on. Long tasks are marked, and you can see which script and function they came from. The Coverage panel also shows how much of each script actually runs on the page.
8. Is dynamic rendering still recommended?
No. Dynamic rendering means detecting crawlers and serving them a pre-rendered version of the page while users get the JavaScript version. Google has described it as a workaround rather than a recommended long-term solution, and it adds complexity and the risk of the two versions drifting apart. Server-side rendering, static generation or a hybrid of the two give crawlers and visitors the same complete HTML, which is simpler to maintain and more reliable across different crawlers.
The JavaScript Checker loads your page in headless Chromium, captures every console error and warning, measures bundle size and execution time, lists third-party tags with their cost and shows what the rendered page looks like to a crawler.
Run the JavaScript Checker โ