Resource loading and critical rendering path skill

The browser converts raw bytes into rendered pixels through a precise pipeline.

by wondelai·MIT license·★ 2,235 Stars on the repo·GitHub ↗

Use now

Files of Resource loading and critical rendering path

wondelai/main1 file
resource-loading.md
Show the full text422 lines

Resource Loading and Critical Rendering Path

The browser converts raw bytes into rendered pixels through a precise pipeline. Understanding this pipeline reveals exactly which resources block rendering and how to eliminate or defer them.

Table of Contents

  1. The Critical Rendering Path
  2. Render-Blocking Resources
  3. Async and Defer
  4. Resource Hints
  5. Font Loading Strategies
  6. Image Optimization
  7. Resource Loading Priority
  8. Practical Loading Strategy

The Critical Rendering Path

Every page load follows this sequence:

HTML bytes → Parse → DOM
                      ↓
CSS bytes  → Parse → CSSOM
                      ↓
              Render Tree (DOM + CSSOM)
                      ↓
                    Layout (geometry calculation)
                      ↓
                    Paint (pixel rendering)
                      ↓
                    Composite (layer assembly)

The key insight: The browser cannot paint anything until both the DOM and CSSOM are complete. CSS is render-blocking. JavaScript is parser-blocking. Every blocking resource directly adds to time-to-first-paint.

DOM Construction

The browser receives HTML bytes, decodes them into characters, tokenizes them into tags, and builds the DOM tree. This is incremental -- the parser processes HTML as it arrives, building the tree progressively.

When parsing stops:

  • A <script> tag without async or defer halts DOM construction. The browser must download the script, execute it (because it might call document.write()), and then resume parsing.
  • The parser does not stop for CSS files, but rendering is blocked until CSS is parsed.
CSSOM Construction

CSS files are fetched and parsed into the CSSOM (CSS Object Model). Unlike DOM construction:

  • CSSOM is not incremental -- the browser waits for all CSS before computing styles
  • CSS is render-blocking but not parser-blocking (DOM construction continues)
  • A <script> after a <link rel="stylesheet"> is blocked until the CSS loads (because the script might query computed styles)
Render Tree

The render tree combines the DOM and CSSOM, containing only visible elements with their computed styles. Elements with display: none are excluded. The render tree triggers:

  1. Layout (reflow): Calculates the exact position and size of each element
  2. Paint: Fills in pixels -- text, colors, borders, shadows, images
  3. Composite: Assembles painted layers into the final image (GPU-accelerated for transformed/animated elements)

Render-Blocking Resources

CSS is render-blocking

The browser will not render any content until all CSS in the <head> is loaded and parsed. This means:

<!-- This CSS file blocks ALL rendering until loaded -->
<link rel="stylesheet" href="styles.css">

Optimization strategies:

Inline critical CSS: Extract the styles needed for above-the-fold content and embed them directly in the HTML:

<head>
  <style>
    /* Critical styles for above-the-fold content */
    body { font-family: system-ui; margin: 0; }
    .hero { padding: 2rem; background: #f8f9fa; }
    .nav { display: flex; gap: 1rem; }
  </style>
  <!-- Load full stylesheet asynchronously -->
  <link rel="preload" href="styles.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
  <noscript><link rel="stylesheet" href="styles.css"></noscript>
</head>

Media queries for conditional CSS: Stylesheets with media queries that do not match the current context are downloaded but do not block rendering:

<!-- Blocks rendering (matches all screens) -->
<link rel="stylesheet" href="styles.css">

<!-- Does NOT block rendering on screen (only for print) -->
<link rel="stylesheet" href="print.css" media="print">

<!-- Does NOT block rendering below 768px -->
<link rel="stylesheet" href="desktop.css" media="(min-width: 768px)">

Remove unused CSS: Audit CSS with Chrome DevTools Coverage panel. Typical sites ship 60-90% unused CSS.

JavaScript is parser-blocking

A <script> tag without attributes halts DOM parsing:

<p>This paragraph is parsed</p>
<script src="app.js"></script>
<!-- DOM parsing stops until app.js downloads AND executes -->
<p>This paragraph waits</p>

Async and Defer

The async and defer attributes change how scripts interact with the parser:

defer
<script src="app.js" defer></script>
  • Downloads in parallel with DOM parsing (non-blocking)
  • Executes after DOM parsing is complete, before DOMContentLoaded
  • Multiple deferred scripts execute in document order
  • Best for: Most application scripts that depend on the DOM
async
<script src="analytics.js" async></script>
  • Downloads in parallel with DOM parsing (non-blocking)
  • Executes immediately when download completes (may interrupt parsing)
  • No guaranteed execution order between multiple async scripts
  • Best for: Independent scripts that do not depend on DOM or other scripts (analytics, ads)
Comparison
Attribute Download Execution Order guaranteed Blocks parsing
None Sequential Immediately Yes Yes
async Parallel When ready No Briefly (during execution)
defer Parallel After DOM parsed Yes No
Module scripts
<script type="module" src="app.mjs"></script>

Module scripts are deferred by default. Adding async to a module script makes it execute as soon as its dependency graph is resolved.

Resource Hints

Resource hints allow developers to inform the browser about resources it will need, enabling earlier loading.

dns-prefetch

Resolves the DNS for a domain before any request is made:

<link rel="dns-prefetch" href="https://cdn.example.com">
  • Cheapest hint -- only does DNS resolution
  • Use for third-party domains (analytics, fonts, CDNs)
  • Saves 20-120ms per domain
preconnect

Resolves DNS, establishes TCP connection, and negotiates TLS:

<link rel="preconnect" href="https://cdn.example.com">
  • More expensive than dns-prefetch (holds a connection open)
  • Use for origins you will definitely request from within seconds
  • Limit to 2-4 critical origins to avoid wasting connections
  • Always include crossorigin for CORS-enabled resources:
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
preload

Fetches a specific resource at high priority without blocking rendering:

<link rel="preload" href="/fonts/main.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/hero.webp" as="image">
<link rel="preload" href="/critical.css" as="style">
  • The as attribute is required -- it sets the correct priority and CORS mode
  • Fetches immediately at high priority
  • Does not apply the resource (does not render CSS, execute JS, etc.)
  • Use for critical resources discovered late in the HTML (fonts referenced in CSS, images in CSS backgrounds)
  • Warning: Preloading too many resources dilutes the benefit -- limit to truly critical resources (LCP image, critical fonts)
prefetch

Fetches a resource at low priority for a likely future navigation:

<link rel="prefetch" href="/next-page.html">
<link rel="prefetch" href="/next-page-data.json">
  • Downloaded at lowest priority during idle time
  • Stored in the HTTP cache for future use
  • Use for resources needed on the next likely page (next step in a flow, frequently visited page)
  • Does not work if the user has Data Saver enabled
prerender / Speculation Rules

Modern browsers support the Speculation Rules API for prerendering entire pages:

<script type="speculationrules">
{
  "prerender": [
    { "urls": ["/likely-next-page"] }
  ]
}
</script>
  • Renders the entire page in a hidden tab
  • Near-instant navigation when the user clicks
  • Expensive in terms of memory and bandwidth -- use only for high-confidence predictions

Font Loading Strategies

Web fonts create unique performance challenges because the browser may hide text while fonts load (Flash of Invisible Text, or FOIT) or show a jarring swap (Flash of Unstyled Text, or FOUT).

font-display values
@font-face {
  font-family: 'Custom Font';
  src: url('font.woff2') format('woff2');
  font-display: swap;  /* Show fallback immediately, swap when ready */
}
Value Behavior Best for
auto Browser default (usually FOIT for 3s) Not recommended
block Invisible text for up to 3s, then swap Icon fonts only
swap Show fallback immediately, swap when loaded Body text, most use cases
fallback Brief invisible period (100ms), then fallback, then swap Balanced approach
optional Brief invisible period, uses font only if cached Performance-critical; accepts FOUT
Preloading fonts

Fonts referenced in CSS are discovered late -- the browser must load HTML, then CSS, then discover the font URL. Preloading jumps the queue:

<link rel="preload" href="/fonts/main.woff2" as="font" type="font/woff2" crossorigin>

The crossorigin attribute is required even for same-origin fonts because the font specification requires CORS.

Font subsetting

Subset fonts to include only the characters needed:

  • Latin-only sites can drop CJK, Cyrillic, and other ranges
  • Use unicode-range in @font-face to load character ranges on demand
@font-face {
  font-family: 'Custom Font';
  src: url('font-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF;  /* Basic Latin */
}

Image Optimization

Images typically account for 50-70% of total page weight.

Lazy loading
<!-- Browser-native lazy loading -->
<img src="photo.jpg" loading="lazy" alt="Description">

<!-- Do NOT lazy-load above-fold images (LCP candidates) -->
<img src="hero.jpg" loading="eager" fetchpriority="high" alt="Hero">
Responsive images

Serve appropriately sized images for each viewport:

<img
  srcset="photo-400.webp 400w,
          photo-800.webp 800w,
          photo-1200.webp 1200w"
  sizes="(max-width: 600px) 400px,
         (max-width: 1000px) 800px,
         1200px"
  src="photo-800.webp"
  alt="Description"
>
Modern formats
Format Compression Browser support Best for
AVIF Best (50% smaller than JPEG) Chrome, Firefox, Safari 16+ Photos, complex images
WebP Good (25-35% smaller than JPEG) All modern browsers General purpose
JPEG Baseline Universal Fallback
PNG Lossless Universal Transparency, screenshots
SVG Vector (tiny for icons) Universal Icons, logos, illustrations

Use the <picture> element for format negotiation:

<picture>
  <source srcset="photo.avif" type="image/avif">
  <source srcset="photo.webp" type="image/webp">
  <img src="photo.jpg" alt="Description">
</picture>
Explicit dimensions

Always set width and height (or use CSS aspect-ratio) to prevent layout shift:

<img src="photo.jpg" width="800" height="600" alt="Description">
img {
  aspect-ratio: 4 / 3;
  width: 100%;
  height: auto;
}

Resource Loading Priority

Modern browsers assign priorities based on resource type and position. The fetchpriority attribute gives developers explicit control:

<!-- High priority for LCP image -->
<img src="hero.webp" fetchpriority="high" alt="Hero">

<!-- Low priority for below-fold image -->
<img src="footer-bg.webp" fetchpriority="low" loading="lazy" alt="">

<!-- High priority for critical script -->
<script src="critical.js" fetchpriority="high"></script>
Default browser priorities
Resource Default priority
HTML document Highest
CSS in <head> Highest
Preloaded resources High
Scripts in <head> High
Images in viewport High
Scripts at end of body Medium
Images out of viewport Low
Prefetched resources Lowest

Practical Loading Strategy

A complete resource loading strategy for a typical page:

<head>
  <!-- 1. DNS prefetch for third-party origins -->
  <link rel="dns-prefetch" href="https://analytics.example.com">

  <!-- 2. Preconnect to critical origins -->
  <link rel="preconnect" href="https://cdn.example.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>

  <!-- 3. Preload critical resources discovered late -->
  <link rel="preload" href="/fonts/main.woff2" as="font" type="font/woff2" crossorigin>
  <link rel="preload" href="/hero.avif" as="image">

  <!-- 4. Inline critical CSS -->
  <style>/* above-fold styles */</style>

  <!-- 5. Async load full stylesheet -->
  <link rel="preload" href="/styles.css" as="style" onload="this.onload=null;this.rel='stylesheet'">

  <!-- 6. Deferred application scripts -->
  <script src="/app.js" defer></script>

  <!-- 7. Async independent scripts -->
  <script src="/analytics.js" async></script>
</head>
<body>
  <!-- 8. LCP element with high priority -->
  <img src="/hero.avif" fetchpriority="high" alt="Hero" width="1200" height="600">

  <!-- 9. Below-fold images lazy loaded -->
  <img src="/feature.webp" loading="lazy" alt="Feature" width="800" height="400">

  <!-- 10. Prefetch next page for likely navigation -->
  <link rel="prefetch" href="/next-page.html">
</body>

This ordering ensures critical resources load first, nothing blocks rendering unnecessarily, and resources for future navigations are prepared during idle time.

1# Resource Loading and Critical Rendering Path
2 
3The browser converts raw bytes into rendered pixels through a precise pipeline. Understanding this pipeline reveals exactly which resources block rendering and how to eliminate or defer them.
4 
5 
6## Table of Contents
71. [The Critical Rendering Path](#the-critical-rendering-path)
82. [Render-Blocking Resources](#render-blocking-resources)
93. [Async and Defer](#async-and-defer)
104. [Resource Hints](#resource-hints)
115. [Font Loading Strategies](#font-loading-strategies)
126. [Image Optimization](#image-optimization)
137. [Resource Loading Priority](#resource-loading-priority)
148. [Practical Loading Strategy](#practical-loading-strategy)
15 
16---
17 
18## The Critical Rendering Path
19 
20Every page load follows this sequence:
21 
22```
23HTML bytes → Parse → DOM
24 ↓
25CSS bytes → Parse → CSSOM
26 ↓
27 Render Tree (DOM + CSSOM)
28 ↓
29 Layout (geometry calculation)
30 ↓
31 Paint (pixel rendering)
32 ↓
33 Composite (layer assembly)
34```
35 
36**The key insight:** The browser cannot paint anything until both the DOM and CSSOM are complete. CSS is **render-blocking**. JavaScript is **parser-blocking**. Every blocking resource directly adds to time-to-first-paint.
37 
38### DOM Construction
39 
40The browser receives HTML bytes, decodes them into characters, tokenizes them into tags, and builds the DOM tree. This is incremental -- the parser processes HTML as it arrives, building the tree progressively.
41 
42**When parsing stops:**
43- A `<script>` tag without `async` or `defer` halts DOM construction. The browser must download the script, execute it (because it might call `document.write()`), and then resume parsing.
44- The parser does not stop for CSS files, but rendering is blocked until CSS is parsed.
45 
46### CSSOM Construction
47 
48CSS files are fetched and parsed into the CSSOM (CSS Object Model). Unlike DOM construction:
49- CSSOM is not incremental -- the browser waits for all CSS before computing styles
50- CSS is render-blocking but not parser-blocking (DOM construction continues)
51- A `<script>` after a `<link rel="stylesheet">` is blocked until the CSS loads (because the script might query computed styles)
52 
53### Render Tree
54 
55The render tree combines the DOM and CSSOM, containing only visible elements with their computed styles. Elements with `display: none` are excluded. The render tree triggers:
56 
571. **Layout (reflow):** Calculates the exact position and size of each element
582. **Paint:** Fills in pixels -- text, colors, borders, shadows, images
593. **Composite:** Assembles painted layers into the final image (GPU-accelerated for transformed/animated elements)
60 
61## Render-Blocking Resources
62 
63### CSS is render-blocking
64 
65The browser will not render any content until all CSS in the `<head>` is loaded and parsed. This means:
66 
67```html
68<!-- This CSS file blocks ALL rendering until loaded -->
69<link rel="stylesheet" href="styles.css">
70```
71 
72**Optimization strategies:**
73 
74**Inline critical CSS:** Extract the styles needed for above-the-fold content and embed them directly in the HTML:
75 
76```html
77<head>
78 <style>
79 /* Critical styles for above-the-fold content */
80 body { font-family: system-ui; margin: 0; }
81 .hero { padding: 2rem; background: #f8f9fa; }
82 .nav { display: flex; gap: 1rem; }
83 </style>
84 <!-- Load full stylesheet asynchronously -->
85 <link rel="preload" href="styles.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
86 <noscript><link rel="stylesheet" href="styles.css"></noscript>
87</head>
88```
89 
90**Media queries for conditional CSS:** Stylesheets with media queries that do not match the current context are downloaded but do not block rendering:
91 
92```html
93<!-- Blocks rendering (matches all screens) -->
94<link rel="stylesheet" href="styles.css">
95 
96<!-- Does NOT block rendering on screen (only for print) -->
97<link rel="stylesheet" href="print.css" media="print">
98 
99<!-- Does NOT block rendering below 768px -->
100<link rel="stylesheet" href="desktop.css" media="(min-width: 768px)">
101```
102 
103**Remove unused CSS:** Audit CSS with Chrome DevTools Coverage panel. Typical sites ship 60-90% unused CSS.
104 
105### JavaScript is parser-blocking
106 
107A `<script>` tag without attributes halts DOM parsing:
108 
109```html
110<p>This paragraph is parsed</p>
111<script src="app.js"></script>
112<!-- DOM parsing stops until app.js downloads AND executes -->
113<p>This paragraph waits</p>
114```
115 
116## Async and Defer
117 
118The `async` and `defer` attributes change how scripts interact with the parser:
119 
120### `defer`
121 
122```html
123<script src="app.js" defer></script>
124```
125 
126- Downloads in parallel with DOM parsing (non-blocking)
127- Executes **after** DOM parsing is complete, before `DOMContentLoaded`
128- Multiple deferred scripts execute in document order
129- **Best for:** Most application scripts that depend on the DOM
130 
131### `async`
132 
133```html
134<script src="analytics.js" async></script>
135```
136 
137- Downloads in parallel with DOM parsing (non-blocking)
138- Executes **immediately** when download completes (may interrupt parsing)
139- No guaranteed execution order between multiple async scripts
140- **Best for:** Independent scripts that do not depend on DOM or other scripts (analytics, ads)
141 
142### Comparison
143 
144| Attribute | Download | Execution | Order guaranteed | Blocks parsing |
145|-----------|----------|-----------|-----------------|----------------|
146| None | Sequential | Immediately | Yes | Yes |
147| `async` | Parallel | When ready | No | Briefly (during execution) |
148| `defer` | Parallel | After DOM parsed | Yes | No |
149 
150### Module scripts
151 
152```html
153<script type="module" src="app.mjs"></script>
154```
155 
156Module scripts are deferred by default. Adding `async` to a module script makes it execute as soon as its dependency graph is resolved.
157 
158## Resource Hints
159 
160Resource hints allow developers to inform the browser about resources it will need, enabling earlier loading.
161 
162### `dns-prefetch`
163 
164Resolves the DNS for a domain before any request is made:
165 
166```html
167<link rel="dns-prefetch" href="https://cdn.example.com">
168```
169 
170- Cheapest hint -- only does DNS resolution
171- Use for third-party domains (analytics, fonts, CDNs)
172- Saves 20-120ms per domain
173 
174### `preconnect`
175 
176Resolves DNS, establishes TCP connection, and negotiates TLS:
177 
178```html
179<link rel="preconnect" href="https://cdn.example.com">
180```
181 
182- More expensive than `dns-prefetch` (holds a connection open)
183- Use for origins you will definitely request from within seconds
184- Limit to 2-4 critical origins to avoid wasting connections
185- Always include `crossorigin` for CORS-enabled resources:
186 
187```html
188<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
189```
190 
191### `preload`
192 
193Fetches a specific resource at high priority without blocking rendering:
194 
195```html
196<link rel="preload" href="/fonts/main.woff2" as="font" type="font/woff2" crossorigin>
197<link rel="preload" href="/hero.webp" as="image">
198<link rel="preload" href="/critical.css" as="style">
199```
200 
201- **The `as` attribute is required** -- it sets the correct priority and CORS mode
202- Fetches immediately at high priority
203- Does not apply the resource (does not render CSS, execute JS, etc.)
204- Use for critical resources discovered late in the HTML (fonts referenced in CSS, images in CSS backgrounds)
205- **Warning:** Preloading too many resources dilutes the benefit -- limit to truly critical resources (LCP image, critical fonts)
206 
207### `prefetch`
208 
209Fetches a resource at low priority for a likely future navigation:
210 
211```html
212<link rel="prefetch" href="/next-page.html">
213<link rel="prefetch" href="/next-page-data.json">
214```
215 
216- Downloaded at lowest priority during idle time
217- Stored in the HTTP cache for future use
218- Use for resources needed on the next likely page (next step in a flow, frequently visited page)
219- Does not work if the user has Data Saver enabled
220 
221### `prerender` / Speculation Rules
222 
223Modern browsers support the Speculation Rules API for prerendering entire pages:
224 
225```html
226<script type="speculationrules">
227{
228 "prerender": [
229 { "urls": ["/likely-next-page"] }
230 ]
231}
232</script>
233```
234 
235- Renders the entire page in a hidden tab
236- Near-instant navigation when the user clicks
237- Expensive in terms of memory and bandwidth -- use only for high-confidence predictions
238 
239## Font Loading Strategies
240 
241Web fonts create unique performance challenges because the browser may hide text while fonts load (Flash of Invisible Text, or FOIT) or show a jarring swap (Flash of Unstyled Text, or FOUT).
242 
243### `font-display` values
244 
245```css
246@font-face {
247 font-family: 'Custom Font';
248 src: url('font.woff2') format('woff2');
249 font-display: swap; /* Show fallback immediately, swap when ready */
250}
251```
252 
253| Value | Behavior | Best for |
254|-------|----------|----------|
255| `auto` | Browser default (usually FOIT for 3s) | Not recommended |
256| `block` | Invisible text for up to 3s, then swap | Icon fonts only |
257| `swap` | Show fallback immediately, swap when loaded | Body text, most use cases |
258| `fallback` | Brief invisible period (100ms), then fallback, then swap | Balanced approach |
259| `optional` | Brief invisible period, uses font only if cached | Performance-critical; accepts FOUT |
260 
261### Preloading fonts
262 
263Fonts referenced in CSS are discovered late -- the browser must load HTML, then CSS, then discover the font URL. Preloading jumps the queue:
264 
265```html
266<link rel="preload" href="/fonts/main.woff2" as="font" type="font/woff2" crossorigin>
267```
268 
269The `crossorigin` attribute is required even for same-origin fonts because the font specification requires CORS.
270 
271### Font subsetting
272 
273Subset fonts to include only the characters needed:
274- Latin-only sites can drop CJK, Cyrillic, and other ranges
275- Use `unicode-range` in `@font-face` to load character ranges on demand
276 
277```css
278@font-face {
279 font-family: 'Custom Font';
280 src: url('font-latin.woff2') format('woff2');
281 unicode-range: U+0000-00FF; /* Basic Latin */
282}
283```
284 
285## Image Optimization
286 
287Images typically account for 50-70% of total page weight.
288 
289### Lazy loading
290 
291```html
292<!-- Browser-native lazy loading -->
293<img src="photo.jpg" loading="lazy" alt="Description">
294 
295<!-- Do NOT lazy-load above-fold images (LCP candidates) -->
296<img src="hero.jpg" loading="eager" fetchpriority="high" alt="Hero">
297```
298 
299### Responsive images
300 
301Serve appropriately sized images for each viewport:
302 
303```html
304<img
305 srcset="photo-400.webp 400w,
306 photo-800.webp 800w,
307 photo-1200.webp 1200w"
308 sizes="(max-width: 600px) 400px,
309 (max-width: 1000px) 800px,
310 1200px"
311 src="photo-800.webp"
312 alt="Description"
313>
314```
315 
316### Modern formats
317 
318| Format | Compression | Browser support | Best for |
319|--------|-------------|-----------------|----------|
320| **AVIF** | Best (50% smaller than JPEG) | Chrome, Firefox, Safari 16+ | Photos, complex images |
321| **WebP** | Good (25-35% smaller than JPEG) | All modern browsers | General purpose |
322| **JPEG** | Baseline | Universal | Fallback |
323| **PNG** | Lossless | Universal | Transparency, screenshots |
324| **SVG** | Vector (tiny for icons) | Universal | Icons, logos, illustrations |
325 
326Use the `<picture>` element for format negotiation:
327 
328```html
329<picture>
330 <source srcset="photo.avif" type="image/avif">
331 <source srcset="photo.webp" type="image/webp">
332 <img src="photo.jpg" alt="Description">
333</picture>
334```
335 
336### Explicit dimensions
337 
338Always set width and height (or use CSS `aspect-ratio`) to prevent layout shift:
339 
340```html
341<img src="photo.jpg" width="800" height="600" alt="Description">
342```
343 
344```css
345img {
346 aspect-ratio: 4 / 3;
347 width: 100%;
348 height: auto;
349}
350```
351 
352## Resource Loading Priority
353 
354Modern browsers assign priorities based on resource type and position. The `fetchpriority` attribute gives developers explicit control:
355 
356```html
357<!-- High priority for LCP image -->
358<img src="hero.webp" fetchpriority="high" alt="Hero">
359 
360<!-- Low priority for below-fold image -->
361<img src="footer-bg.webp" fetchpriority="low" loading="lazy" alt="">
362 
363<!-- High priority for critical script -->
364<script src="critical.js" fetchpriority="high"></script>
365```
366 
367### Default browser priorities
368 
369| Resource | Default priority |
370|----------|-----------------|
371| HTML document | Highest |
372| CSS in `<head>` | Highest |
373| Preloaded resources | High |
374| Scripts in `<head>` | High |
375| Images in viewport | High |
376| Scripts at end of body | Medium |
377| Images out of viewport | Low |
378| Prefetched resources | Lowest |
379 
380## Practical Loading Strategy
381 
382A complete resource loading strategy for a typical page:
383 
384```html
385<head>
386 <!-- 1. DNS prefetch for third-party origins -->
387 <link rel="dns-prefetch" href="https://analytics.example.com">
388 
389 <!-- 2. Preconnect to critical origins -->
390 <link rel="preconnect" href="https://cdn.example.com">
391 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
392 
393 <!-- 3. Preload critical resources discovered late -->
394 <link rel="preload" href="/fonts/main.woff2" as="font" type="font/woff2" crossorigin>
395 <link rel="preload" href="/hero.avif" as="image">
396 
397 <!-- 4. Inline critical CSS -->
398 <style>/* above-fold styles */</style>
399 
400 <!-- 5. Async load full stylesheet -->
401 <link rel="preload" href="/styles.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
402 
403 <!-- 6. Deferred application scripts -->
404 <script src="/app.js" defer></script>
405 
406 <!-- 7. Async independent scripts -->
407 <script src="/analytics.js" async></script>
408</head>
409<body>
410 <!-- 8. LCP element with high priority -->
411 <img src="/hero.avif" fetchpriority="high" alt="Hero" width="1200" height="600">
412 
413 <!-- 9. Below-fold images lazy loaded -->
414 <img src="/feature.webp" loading="lazy" alt="Feature" width="800" height="400">
415 
416 <!-- 10. Prefetch next page for likely navigation -->
417 <link rel="prefetch" href="/next-page.html">
418</body>
419```
420 
421This ordering ensures critical resources load first, nothing blocks rendering unnecessarily, and resources for future navigations are prepared during idle time.
422 

Discussion

Alternatives

⚡ NEXUS Quick-Start Guide> Get from zero to orchestrated multi-agent pipeline in 5 minutes.Business & ops · MIT🎯 NEXUS Agent Activation Prompts> Ready-to-use prompt templates for activating any agent within the NEXUS pipeline. Copy, customize the [PLACEHOLDERS], and deploy.Business & ops · MITArbor — Autonomous Optimization via Hypothesis Tree RefinementAutonomously improve a real artifact (code, training recipe, agent harness, data pipeline, prompt) against an objective and an evaluator, using Hypothesis Tree Refinement (HTR) from the Arbor paper. Use this whenever someone wants to iteratively optimize something over many experiments without overfitting — e.g. "get my model's eval score up", "improve this agent/harness", "tune this pipeline", "beat the baseline on this benchmark", "run a search over approaches and keep the best", "do an MLE-bench / Kaggle-style optimization", or any long-horizon "make this artifact better and don't just memorize the dev set" task. Trigger it even when the user doesn't say "Arbor" or "hypothesis tree" but describes repeated experiment-and-evaluate loops, branching exploration of competing ideas, or worries about a dev/test gap. Runs Claude itself as the coordinator with subagent executors in isolated git worktrees; for the standalone `arbor` CLI tool see references/arbor-upstream.md.Science · MIT/cs:cro-review — CRO Forcing Questions/cs:cro-review <plan> — Pipeline-paranoid interrogation of revenue, win rate, NRR, and ramp time. Use when the forecast misses pipeline coverage, win rates drop, or before scaling the sales team. · MIT