What “Tight Mode” Means for Browser Resource Loading
Browsers don’t fetch resources identically. Chrome and Safari both enforce what’s called “Tight Mode,” a constraint on which resources load first and in what order — but they implement it in very different ways. Documentation is sparse: the concept appears in a Google document Patrick Meenan originally wrote in 2015 and updated in November 2023, plus a presentation by Akamai’s Robin Marx at We Love Speed. Here’s a practical summary of what Tight Mode does, what triggers it, and how the major browsers diverge.
Tight Mode Is the First of Two Loading Phases
As Patrick Meenan explains:
“Chrome loads resources in 2 phases. ‘Tight mode’ is the initial phase and constraints [sic] loading lower-priority resources until the body is attached to the document (essentially, after all blocking scripts in the head have been executed).”
In this first phase, Chrome allows resources marked High and Medium priority. Everything else is held back — left out until the document body is attached, meaning blocking scripts in the <head> have finished executing. Low-priority resources then load in a second phase.
There’s an important exception to that rule, discussed below. For now, the key point is which browsers enforce Tight Mode at all.
Chrome and Safari Both Use Tight Mode — Differently
Chrome and Safari both have working implementations of Tight Mode. Safari also restricts its initial fetch to High-priority resources, but the waterfall behavior looks quite different from Chrome’s even with identical HTML. For example, Safari holds back the first five Medium-priority PNG images while Chrome allows them through. Safari makes all Medium- and Low-priority resources wait until High-priority items finish loading. Chrome, meanwhile, appears to exclude some High-priority resources from Tight Mode — the reason for that becomes clear when looking at what triggers the mode.
Firefox takes neither approach: it applies no extra tightening based on resource priority and follows the classic waterfall loading pattern.
What Triggers Tight Mode in Each Browser
Chrome and Safari enter Tight Mode under different conditions, as summarized below.
| Chrome | Safari | |
|---|---|---|
| Tight Mode triggered | While blocking JS in the <head> is busy. | While blocking JS or CSS anywhere is busy. |
Chrome only considers the document <head> and only when JavaScript is involved. Safari also considers CSS and looks anywhere in the document — not just the <head> but the <body> as well. That explains why Chrome leaves some High-priority images out of Tight Mode: it only cares about JavaScript in this context. A script with fetchpriority="high" in the <body> is not treated as High priority by Chrome and loads after other items. Safari honors fetchpriority anywhere in the document.
Safari’s behavior has its own quirks. For markup like this:
<head>
<!-- two high-priority scripts -->
<script src="script-1.js"></script>
<script src="script-1.js"></script>
<!-- two low-priority scripts -->
<script src="script-3.js" defer></script>
<script src="script-4.js" defer></script>
</head>
<body>
<!-- five low-priority scripts -->
<img src="image-1.jpg">
<img src="image-2.jpg">
<img src="image-3.jpg">
<img src="image-4.jpg">
<img src="image-5.jpg">
</body>
You might expect Safari to delay two Low-priority scripts in the <head> until five images in the <body> download. Instead, Safari loads those two scripts during its Tight Mode phase.
<head> with High priority. (Large preview)Exceptions to the Tight Mode Rule
The second part of Meenan’s definition is the caveat mentioned earlier:
“In tight mode, low-priority resources are only loaded if there are less than two in-flight requests at the time that they are discovered.”
Here, “in-flight” means fewer than two High- or Medium-priority items currently being requested. Robin Marx demonstrates this by comparing Chrome and Safari under identical conditions: two High-priority scripts and ten regular images.
<head>
<!-- two high-priority scripts -->
<script src="script-1.js"></script>
<script src="script-1.js"></script>
</head>
<body>
<!-- ten low-priority images -->
<img src="image-1.jpg">
<img src="image-2.jpg">
<img src="image-3.jpg">
<img src="image-4.jpg">
<img src="image-5.jpg">
<!-- rest of images -->
<img src="image-10.jpg">
</body>
Safari behaves as expected — the two High-priority scripts load first, then the 10 images follow.
Chrome is less predictable. The two High-priority scripts load first, then Chrome lets in only the first five images (Medium priority) while excluding the last five (Low priority). Chrome does this because it’s hedging on the Largest Contentful Paint (LCP) often being among those first images, so it automatically prioritizes up to five non-critical images as an LCP optimization. Chrome accepts only up to two Medium-priority resources this way; the rest are downgraded to Low priority.
Safari similarly extends Tight Mode admission to both Medium- and Low-priority resources, anywhere in the document, except for asynchronous or deferred scripts — as seen earlier, those load immediately anyway.
Working With Tight Mode
Tools that influence priority include resource hints (preload, preconnect), the Fetch Priority API, and lazy-loading techniques. Marking items with fetchpriority="high" or fetchpriority="low" is the direct way to affect Tight Mode behavior.
<img src="lcp-image.jpg" fetchpriority="high">
<link rel="preload" href="defer.js" as="script" fetchpriority="low">
fetchpriority="high"can pull items lower in the document into Tight Mode;fetchpriority="low"can push items higher in the document out of it.- In Chrome, this works for images, asynchronous or deferred scripts, and scripts at the end of the
<body>. - In Safari, this only affects images.
For the full technical walkthrough, Robin Marx’s presentation is the most thorough source available, starting around the 28:32 marker.




