LW IT Solutions logo LW IT Solutions logo LW IT Solutions
« Blog Overview /Web Development/Tutorials / Blocking Scripts: What Twenty HTML Responses Reveal—and...
Read this article in other languages:

Blocking Scripts: What Twenty HTML Responses Reveal—and What They Do Not

Blocking Scripts: What Twenty HTML Responses Reveal—and What They Do Not

Management Summary

Website scripts provide interactive features, analytics and consent handling, but some can delay the browser while a page is being built. Changing when these scripts run may improve loading, provided their dependencies remain intact. A historical review of twenty responses identifies possible sources of delay, rather than measuring what visitors actually experience. The practical issue is therefore both speed and correct behaviour: moving a script can shorten a wait while also disrupting a function that relies on its timing.

Contents
  1. 745 tags found, 660 classified
  2. Responses are not always front pages
  3. Loading rules need their conditions
  4. Byte position is not DOM completeness
  5. Network cost requires a browser trace
  6. What the analyzer can establish
  7. Questions and answers
  8. Sources

A script’s position in HTML can help locate a dependency problem. It cannot measure the resulting delay or prove which elements exist at execution time. A historical sample of twenty responses illustrates both the value and the limits of static analysis.

745 detected tags, 660 classified records; no timing measurement.
745 detected tags, 660 classified records; no timing measurement.

745 tags found, 660 classified

The saved measurement from 6 September 2026 at 14:26:11 +02:00 contains 745 detected script tags, averaging 37.25 per response. Only 660 received detailed classifications: 283 blocking, 230 data, 70 async, 52 defer and 25 module.

The difference is a limit in the analyzer. It retains at most 120 script records per document. ZEIT supplied 205 detected tags, leaving 85 outside the detailed count. Its reported last blocking position therefore applies only to the first 120 records.

Responses are not always front pages

The Stack Overflow response had status 429 and the Allegro response 403. Their one and two detected tags belong to those returned documents, not verified normal front pages. The sample is historical and selected, not a current performance ranking.

GitHub’s response had eight module records and six data records, with no blocking classification. That does not establish uninterrupted parsing, completed layout or freedom from expensive JavaScript. Sixteen responses had a blocking classification before the detected closing head tag; this is a location finding, not a measured first-paint penalty.

Loading rules need their conditions

For parser-inserted classic scripts, an external script without async or defer normally pauses parsing for loading and execution. defer postpones execution until parsing ends; async removes the wait for fetching, but execution can still occupy the main thread. Neither attribute changes an inline classic script’s timing.

Modules are deferred by default, including inline modules; async also applies to modules. Data blocks, import maps and speculation rules are distinct cases. nomodule, Content Security Policy (CSP), failed fetches and the insertion method can prevent or change execution. Five analyzer buckets are therefore not a complete browser model.

Byte position is not DOM completeness

Thirteen recorded positions round to 95–100 percent. Three, not four, are below 50 percent; the Bund result is 55 percent. The ZEIT value of 42 percent is limited by the 120-record cap. Heise’s recorded position is 6,016 within 943,607 bytes, leaving 937,591 bytes from the opening script tag onward.

That remainder includes the script itself. The document object model (DOM) is the browser’s structured representation of page elements. The remaining byte count does not show exactly which of those elements are unavailable when the script executes. Earlier code can add or remove nodes, HTML parsing can rearrange structure, and later callbacks run at different times. A speculative scanner can also fetch resources beyond a paused main parser.

Network cost requires a browser trace

Seven responses have a blocking classification with a different normalized hostname. The comparison removes www and ignores scheme and port; it identifies neither every cross-origin request nor third-party ownership. Three have no detected preconnect anywhere, which says nothing about host-specific hint coverage on the others.

The saved LukasWojcik result places stub.js at 96 percent, with 3,082 bytes remaining from its tag. No elapsed delay was measured. Cache hits, existing connections and speculative loading can avoid new setup work. An inline stub removes its separate fetch, but still executes code and needs to satisfy the applicable CSP.

What the analyzer can establish

The linked analyzer inspects up to 3 MiB of fetched HTML without executing it. Eleven local fixtures exposed limits: script-like text in comments or templates is counted, nomodule still enters the blocking bucket, inline async modules enter the module bucket, and an empty integrity attribute counts as present.

The document.write finding is a text match in inline content, not proof of a call. The API can insert into the parser stream, be ignored or replace a document depending on context. Likewise, Subresource Integrity (SRI) needs usable integrity metadata and appropriate cross-origin access, not merely an attribute name.

Script Loading and Execution Order Analyzer

Questions and answers

How can a loading change be checked?

Browser performance traces before and after a change need comparable cache and network conditions. Resource timing, main-thread work and rendering provide the performance evidence; dependent code and consent behaviour need functional tests. Static counts identify candidates for investigation; the trace measures the effect.

Can a consent stub simply receive defer or async?

A consent stub is a small placeholder script that queues calls until the full consent software loads. Changing its loading order requires checking every dependency. A queue must exist before code uses it; changing timing can break that contract. An inline copy also needs a maintained update process. preconnect and preload may reduce waiting, but provide no fixed saving or exemption from execution cost.

Lukas Wojcik

Lukas Wojcik

Systems architect and technology enthusiast specializing in scalable tracking solutions, GMP Stack (GA4 & GTM), and robust backend architectures. Advocate for clean code and privacy-first design.

Get in touch

A question or an idea for a web project? Tell me a little about it. This form uses reCAPTCHA and formconfirmed to protect against spam.

Write a comment

Edge cases the article misses and questions about the code are welcome here.

The email address is not published. Required fields are marked with an asterisk.

LUKASWOJCIK.COM · NEWSLETTER

Fresh ideas in your inbox

New articles, practical tools and updates from the projects.

Choose topics (optional)
No selection: all topics.

Subscription starts after confirmation by email. · Privacy

Privacy · Newsletter

Email address, language, selected topics and subscription/confirmation dates are stored to deliver the newsletter. Double opt-in is required. Every issue includes an immediate unsubscribe link. Formconfirmed checks the signup for spam. No email open or click tracking.

Read the full privacy policy ↗