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
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 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.


