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 Tight Mode screenshot
Figure 1: Chrome loads resources in two phases, the first of which is called “Tight Mode.” (Large preview)

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.

A screenshot comparing Tight Mode in Chrome with Tight Mode in Safari.
Figure 2: Comparing Tight Mode in Chrome with Tight Mode in Safari. Notice that Chrome allows five images marked with High priority to slip out of Tight Mode. (Large preview)

What Triggers Tight Mode in Each Browser

Chrome and Safari enter Tight Mode under different conditions, as summarized below.

ChromeSafari
Tight Mode triggeredWhile 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.

Safari deferred scripts
Figure 4: Safari treats deferred scripts in the <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.

Safari Tight Mode
(Large preview)

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.

Chrome Tight Mode
(Large preview)

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.

Smashing Editorial