shakapacker 9.3.0.beta.4 → 9.3.0.beta.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +50 -3
- data/CLAUDE.md +13 -0
- data/Gemfile.lock +1 -1
- data/README.md +19 -0
- data/docs/configuration.md +35 -0
- data/docs/early_hints.md +426 -0
- data/docs/early_hints_manual_api.md +454 -0
- data/docs/feature_testing.md +492 -0
- data/lib/install/config/shakapacker.yml +27 -0
- data/lib/shakapacker/configuration.rb +4 -0
- data/lib/shakapacker/helper.rb +409 -14
- data/lib/shakapacker/railtie.rb +4 -0
- data/lib/shakapacker/version.rb +1 -1
- data/package/configExporter/buildValidator.ts +1 -2
- data/package/configExporter/cli.ts +194 -28
- data/package/configExporter/fileWriter.ts +17 -8
- data/package/configExporter/types.ts +6 -1
- data/package/utils/errorCodes.ts +1 -0
- data/package/utils/errorHelpers.ts +16 -12
- data/package-lock.json +2 -2
- data/package.json +2 -2
- data/scripts/remove-use-strict.js +0 -1
- data/test/package/configExporter.test.js +45 -0
- data/test/package/rules/babel.test.js +1 -0
- data/test/package/rules/swc.test.js +1 -0
- metadata +5 -2
|
@@ -0,0 +1,454 @@
|
|
|
1
|
+
# HTTP 103 Early Hints - Manual API Guide
|
|
2
|
+
|
|
3
|
+
> **📚 Main Documentation:** This guide covers the manual `send_pack_early_hints` API for advanced use cases. For the recommended controller-based API (`configure_pack_early_hints`, `skip_send_pack_early_hints`) and comprehensive setup instructions, see [early_hints.md](early_hints.md).
|
|
4
|
+
|
|
5
|
+
This guide focuses on **manual control** of early hints for advanced scenarios where you need to send hints before expensive controller work or customize hints per-pack in layouts.
|
|
6
|
+
|
|
7
|
+
## Automatic vs Manual API
|
|
8
|
+
|
|
9
|
+
By default, Shakapacker automatically sends early hints when `javascript_pack_tag` and `stylesheet_pack_tag` are called (after views render). The manual API allows you to:
|
|
10
|
+
|
|
11
|
+
- **Send hints earlier** - Before controller work starts, maximizing parallelism
|
|
12
|
+
- **Customize per-pack** - Different strategies for different packs in the same layout
|
|
13
|
+
- **Override automatic behavior** - When you need fine-grained control
|
|
14
|
+
|
|
15
|
+
## ⚠️ IMPORTANT: Performance Testing Required
|
|
16
|
+
|
|
17
|
+
**Early hints can improve OR hurt performance** depending on your application:
|
|
18
|
+
|
|
19
|
+
- ✅ **May help**: Large JS bundles (>500KB), slow controllers (>300ms), fast CDN
|
|
20
|
+
- ❌ **May hurt**: Large images as LCP (Largest Contentful Paint), small JS bundles
|
|
21
|
+
- ⚠️ **Test before deploying**: Measure LCP and Time to Interactive before/after enabling
|
|
22
|
+
|
|
23
|
+
**How to test:**
|
|
24
|
+
|
|
25
|
+
1. Enable early hints in production for 10% of traffic
|
|
26
|
+
2. Measure Core Web Vitals (LCP, FCP, TTI) for both groups
|
|
27
|
+
3. Only keep enabled if metrics improve
|
|
28
|
+
|
|
29
|
+
See the [Feature Testing Guide](feature_testing.md#http-103-early-hints) for testing instructions and the [main documentation](early_hints.md) for comprehensive troubleshooting.
|
|
30
|
+
|
|
31
|
+
## When to Use the Manual API
|
|
32
|
+
|
|
33
|
+
Use `send_pack_early_hints` when you need:
|
|
34
|
+
|
|
35
|
+
1. **Maximum parallelism** - Send hints BEFORE expensive controller work (database queries, API calls)
|
|
36
|
+
2. **Per-pack customization** - Different hint strategies for different packs in layouts
|
|
37
|
+
3. **Dynamic control** - Runtime decisions about which packs to hint
|
|
38
|
+
|
|
39
|
+
For most applications, use the [controller-based API](early_hints.md#controller-configuration) instead (`configure_pack_early_hints`, `skip_send_pack_early_hints`).
|
|
40
|
+
|
|
41
|
+
## Manual API Patterns
|
|
42
|
+
|
|
43
|
+
### Pattern 1: Per-Pack Customization in Layout
|
|
44
|
+
|
|
45
|
+
Customize hint handling per pack using a hash:
|
|
46
|
+
|
|
47
|
+
```erb
|
|
48
|
+
<%# app/views/layouts/application.html.erb %>
|
|
49
|
+
<!DOCTYPE html>
|
|
50
|
+
<html>
|
|
51
|
+
<head>
|
|
52
|
+
<%# Mixed handling: preload application, prefetch vendor %>
|
|
53
|
+
<%= stylesheet_pack_tag 'application', 'vendor',
|
|
54
|
+
early_hints: { 'application' => 'preload', 'vendor' => 'prefetch' } %>
|
|
55
|
+
</head>
|
|
56
|
+
<body>
|
|
57
|
+
<%= yield %>
|
|
58
|
+
<%# Disable early hints for this tag %>
|
|
59
|
+
<%= javascript_pack_tag 'application', early_hints: false %>
|
|
60
|
+
</body>
|
|
61
|
+
</html>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
**Options:**
|
|
65
|
+
|
|
66
|
+
- `"preload"` - High priority (default)
|
|
67
|
+
- `"prefetch"` - Low priority
|
|
68
|
+
- `false` or `"none"` - Disabled
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
### Pattern 2: Controller Override (Before Expensive Work)
|
|
73
|
+
|
|
74
|
+
Send hints manually in controller BEFORE expensive work to maximize parallelism:
|
|
75
|
+
|
|
76
|
+
```ruby
|
|
77
|
+
class PostsController < ApplicationController
|
|
78
|
+
def show
|
|
79
|
+
# Send hints BEFORE expensive work
|
|
80
|
+
send_pack_early_hints({
|
|
81
|
+
"application" => { js: "preload", css: "preload" },
|
|
82
|
+
"admin" => { js: "prefetch", css: "none" }
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
# Browser now downloading assets while we do expensive work
|
|
86
|
+
@post = Post.includes(:comments, :author, :tags).find(params[:id])
|
|
87
|
+
@related = @post.find_related_posts(limit: 10) # Expensive query
|
|
88
|
+
# ... more work ...
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**Timeline:**
|
|
94
|
+
|
|
95
|
+
1. Request arrives
|
|
96
|
+
2. `send_pack_early_hints` called → HTTP 103 sent immediately
|
|
97
|
+
3. Browser starts downloading assets
|
|
98
|
+
4. Rails continues with expensive queries (IN PARALLEL with browser downloads)
|
|
99
|
+
5. View renders
|
|
100
|
+
6. HTTP 200 sent with full HTML
|
|
101
|
+
7. Assets already downloaded = faster page load
|
|
102
|
+
|
|
103
|
+
**Benefits:**
|
|
104
|
+
|
|
105
|
+
- ✅ Parallelizes browser downloads with server processing
|
|
106
|
+
- ✅ Can save 200-500ms on pages with slow controllers
|
|
107
|
+
- ✅ Most valuable for pages with expensive queries/API calls
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
### Pattern 3: View Override
|
|
112
|
+
|
|
113
|
+
Views can use `append_*_pack_tag` to add packs dynamically:
|
|
114
|
+
|
|
115
|
+
```erb
|
|
116
|
+
<%# app/views/posts/edit.html.erb %>
|
|
117
|
+
<% append_javascript_pack_tag 'admin_tools' %>
|
|
118
|
+
|
|
119
|
+
<div class="post-editor">
|
|
120
|
+
<%# ... editor UI ... %>
|
|
121
|
+
</div>
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
```erb
|
|
125
|
+
<%# app/views/layouts/application.html.erb %>
|
|
126
|
+
<!DOCTYPE html>
|
|
127
|
+
<html>
|
|
128
|
+
<head>
|
|
129
|
+
<%= stylesheet_pack_tag 'application' %>
|
|
130
|
+
</head>
|
|
131
|
+
<body>
|
|
132
|
+
<%= yield %> <%# View has run, admin_tools added to queue %>
|
|
133
|
+
|
|
134
|
+
<%# Sends hints for BOTH application + admin_tools %>
|
|
135
|
+
<%= javascript_pack_tag 'application' %>
|
|
136
|
+
</body>
|
|
137
|
+
</html>
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
**How it works:**
|
|
141
|
+
|
|
142
|
+
- Views call `append_javascript_pack_tag('admin_tools')`
|
|
143
|
+
- Layout calls `javascript_pack_tag('application')`
|
|
144
|
+
- Helper combines: `['application', 'admin_tools']`
|
|
145
|
+
- Sends hints for ALL packs automatically
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## Configuration
|
|
150
|
+
|
|
151
|
+
> **📚 Configuration:** See the [main documentation](early_hints.md#quick-start) for all configuration options including global settings, priority levels (preload/prefetch/none), and per-controller configuration.
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## Duplicate Prevention
|
|
156
|
+
|
|
157
|
+
Hints are automatically prevented from being sent twice:
|
|
158
|
+
|
|
159
|
+
```ruby
|
|
160
|
+
# Controller
|
|
161
|
+
def show
|
|
162
|
+
send_pack_early_hints({ "application" => { js: "preload", css: "preload" } })
|
|
163
|
+
# ... expensive work ...
|
|
164
|
+
end
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
```erb
|
|
168
|
+
<%# Layout %>
|
|
169
|
+
<%= javascript_pack_tag 'application' %>
|
|
170
|
+
<%# Won't send duplicate hint - already sent in controller %>
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
**How it works:**
|
|
174
|
+
|
|
175
|
+
- Tracks which packs have sent JS hints: `@early_hints_javascript = {}`
|
|
176
|
+
- Tracks which packs have sent CSS hints: `@early_hints_stylesheets = {}`
|
|
177
|
+
- Skips sending hints for packs already sent
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## When to Use Each Pattern
|
|
182
|
+
|
|
183
|
+
### Pattern 1 (Per-Pack) - Best for:
|
|
184
|
+
|
|
185
|
+
- Mixed vendor bundles (preload critical, prefetch non-critical)
|
|
186
|
+
- Different handling for different packs
|
|
187
|
+
- Layout-specific optimizations
|
|
188
|
+
|
|
189
|
+
### Pattern 2 (Controller) - Best for:
|
|
190
|
+
|
|
191
|
+
- Slow controllers with expensive queries (>300ms)
|
|
192
|
+
- Large JS bundles (>500KB)
|
|
193
|
+
- APIs calls in controller
|
|
194
|
+
- Maximum parallelism needed
|
|
195
|
+
|
|
196
|
+
### Pattern 3 (View Override) - Best for:
|
|
197
|
+
|
|
198
|
+
- Admin sections with extra packs
|
|
199
|
+
- Feature flags determining packs
|
|
200
|
+
- Page-specific bundles
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## Full Example: Mixed Patterns
|
|
205
|
+
|
|
206
|
+
```ruby
|
|
207
|
+
# app/controllers/posts_controller.rb
|
|
208
|
+
class PostsController < ApplicationController
|
|
209
|
+
def index
|
|
210
|
+
# Fast controller, automatic hints work fine (Pattern 1)
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
def show
|
|
214
|
+
# Slow controller, send hints early for parallelism (Pattern 2)
|
|
215
|
+
send_pack_early_hints({
|
|
216
|
+
"application" => { js: "preload", css: "preload" }
|
|
217
|
+
})
|
|
218
|
+
|
|
219
|
+
# Expensive work happens in parallel with browser downloads
|
|
220
|
+
@post = Post.includes(:comments, :author).find(params[:id])
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
```erb
|
|
226
|
+
<%# app/views/posts/show.html.erb %>
|
|
227
|
+
<% if current_user&.admin? %>
|
|
228
|
+
<%# Pattern 3: Dynamic pack loading based on user role %>
|
|
229
|
+
<% append_javascript_pack_tag 'admin_tools' %>
|
|
230
|
+
<% end %>
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
```erb
|
|
234
|
+
<%# app/views/layouts/application.html.erb %>
|
|
235
|
+
<!DOCTYPE html>
|
|
236
|
+
<html>
|
|
237
|
+
<head>
|
|
238
|
+
<%= stylesheet_pack_tag 'application' %>
|
|
239
|
+
</head>
|
|
240
|
+
<body>
|
|
241
|
+
<%= yield %>
|
|
242
|
+
|
|
243
|
+
<%# Sends hints for application + admin_tools (if appended) %>
|
|
244
|
+
<%# Won't duplicate hints already sent in controller %>
|
|
245
|
+
<%= javascript_pack_tag 'application' %>
|
|
246
|
+
</body>
|
|
247
|
+
</html>
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
## Preloading Non-Pack Assets (Images, Videos, Fonts)
|
|
253
|
+
|
|
254
|
+
**Shakapacker's early hints are for pack assets (JS/CSS bundles).** For non-pack assets like hero images, videos, and fonts, you have two options.
|
|
255
|
+
|
|
256
|
+
> **Note:** The [main documentation](early_hints.md#4-preloading-hero-images-and-videos) covers using Rails' built-in `preload_link_tag` for images and videos, which is simpler than the manual approach below.
|
|
257
|
+
|
|
258
|
+
### Option 1: Manual Early Hints (For LCP/Critical Assets)
|
|
259
|
+
|
|
260
|
+
**IMPORTANT:** Browsers only process the FIRST HTTP 103 response. If you need both pack assets AND images/videos in early hints, you must send them together in ONE call.
|
|
261
|
+
|
|
262
|
+
```ruby
|
|
263
|
+
class PostsController < ApplicationController
|
|
264
|
+
before_action :send_critical_early_hints, only: [:show]
|
|
265
|
+
|
|
266
|
+
private
|
|
267
|
+
|
|
268
|
+
def send_critical_early_hints
|
|
269
|
+
# Build all early hints in ONE call (packs + images)
|
|
270
|
+
links = []
|
|
271
|
+
|
|
272
|
+
# Pack assets (using Shakapacker manifest)
|
|
273
|
+
js_path = "/packs/#{Shakapacker.manifest.lookup!('application.js')}"
|
|
274
|
+
css_path = "/packs/#{Shakapacker.manifest.lookup!('application.css')}"
|
|
275
|
+
links << "<#{js_path}>; rel=preload; as=script"
|
|
276
|
+
links << "<#{css_path}>; rel=preload; as=style"
|
|
277
|
+
|
|
278
|
+
# Critical images (for LCP - Largest Contentful Paint)
|
|
279
|
+
links << "<#{view_context.asset_path('hero.jpg')}>; rel=preload; as=image"
|
|
280
|
+
|
|
281
|
+
# Send ONE HTTP 103 response with all hints
|
|
282
|
+
request.send_early_hints("Link" => links.join(", "))
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
def show
|
|
286
|
+
# Early hints already sent, browser downloading assets in parallel
|
|
287
|
+
@post = Post.find(params[:id])
|
|
288
|
+
end
|
|
289
|
+
end
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
**When to use:**
|
|
293
|
+
|
|
294
|
+
- Pages with hero images affecting LCP (Largest Contentful Paint)
|
|
295
|
+
- Videos that must load quickly
|
|
296
|
+
- Critical fonts not in pack bundles
|
|
297
|
+
|
|
298
|
+
### Option 2: HTML Preload Links (Simpler, No Early Hints)
|
|
299
|
+
|
|
300
|
+
Use Rails' `preload_link_tag` to add `<link rel="preload">` in the HTML:
|
|
301
|
+
|
|
302
|
+
```erb
|
|
303
|
+
<%# app/views/layouts/application.html.erb %>
|
|
304
|
+
<!DOCTYPE html>
|
|
305
|
+
<html>
|
|
306
|
+
<head>
|
|
307
|
+
<%# Shakapacker sends early hints for packs %>
|
|
308
|
+
<%= stylesheet_pack_tag 'application' %>
|
|
309
|
+
|
|
310
|
+
<%# Preload link in HTML (no HTTP 103, but still speeds up loading) %>
|
|
311
|
+
<%= preload_link_tag asset_path('hero.jpg'), as: 'image' %>
|
|
312
|
+
</head>
|
|
313
|
+
<body>
|
|
314
|
+
<%= yield %>
|
|
315
|
+
<%= javascript_pack_tag 'application' %>
|
|
316
|
+
</body>
|
|
317
|
+
</html>
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
**When to use:**
|
|
321
|
+
|
|
322
|
+
- Images that don't affect LCP
|
|
323
|
+
- Less critical assets
|
|
324
|
+
- Simpler implementation preferred
|
|
325
|
+
|
|
326
|
+
**Note:** `preload_link_tag` only adds HTML `<link>` tags - it does NOT send HTTP 103 Early Hints.
|
|
327
|
+
|
|
328
|
+
---
|
|
329
|
+
|
|
330
|
+
## Requirements & Limitations
|
|
331
|
+
|
|
332
|
+
> **📚 Full Requirements:** See the [main documentation](early_hints.md#requirements) for complete browser and server requirements. This section covers limitations specific to the manual API.
|
|
333
|
+
|
|
334
|
+
**IMPORTANT:** Understand these limitations when using the manual API:
|
|
335
|
+
|
|
336
|
+
### Architecture: Proxy Required for HTTP/2
|
|
337
|
+
|
|
338
|
+
**Standard production architecture for Early Hints:**
|
|
339
|
+
|
|
340
|
+
```
|
|
341
|
+
Browser (HTTP/2)
|
|
342
|
+
↓
|
|
343
|
+
Proxy (Thruster ✅, nginx ✅, Cloudflare ✅)
|
|
344
|
+
├─ Receives HTTP/2
|
|
345
|
+
├─ Translates to HTTP/1.1
|
|
346
|
+
↓
|
|
347
|
+
Puma (HTTP/1.1 with --early-hints flag)
|
|
348
|
+
├─ Sends HTTP/1.1 103 Early Hints ✅
|
|
349
|
+
├─ Sends HTTP/1.1 200 OK
|
|
350
|
+
↓
|
|
351
|
+
Proxy
|
|
352
|
+
├─ Translates to HTTP/2
|
|
353
|
+
↓
|
|
354
|
+
Browser (HTTP/2 103) ✅
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
**Key insights:**
|
|
358
|
+
|
|
359
|
+
- Puma always runs HTTP/1.1 and requires `--early-hints` flag
|
|
360
|
+
- The proxy handles HTTP/2 for external clients
|
|
361
|
+
- **NOT all proxies support early hints** (Control Plane ❌, AWS ALB ❌)
|
|
362
|
+
|
|
363
|
+
### Puma Limitation: HTTP/1.1 Only
|
|
364
|
+
|
|
365
|
+
**Puma ONLY supports HTTP/1.1 Early Hints** (not HTTP/2). This is a Rack/Puma limitation, and **there are no plans to add HTTP/2 support to Puma**.
|
|
366
|
+
|
|
367
|
+
- ✅ **Works**: Puma 5+ with HTTP/1.1
|
|
368
|
+
- ❌ **Doesn't work**: Puma with HTTP/2 (h2)
|
|
369
|
+
- ✅ **Solution**: Use a proxy in front of Puma (Thruster, nginx, etc.)
|
|
370
|
+
|
|
371
|
+
**This is the expected architecture** - there's always something in front of Puma to handle HTTP/2 translation in production.
|
|
372
|
+
|
|
373
|
+
### Browser Behavior
|
|
374
|
+
|
|
375
|
+
**Browsers only process the FIRST `HTTP/1.1 103` response.**
|
|
376
|
+
|
|
377
|
+
- Shakapacker sends ONE 103 response with ALL hints (JS + CSS combined)
|
|
378
|
+
- Subsequent 103 responses are ignored by browsers
|
|
379
|
+
- This is by design per the HTTP 103 spec
|
|
380
|
+
|
|
381
|
+
### Testing Locally
|
|
382
|
+
|
|
383
|
+
> **📚 Full Testing Guide:** See the [Feature Testing Guide](feature_testing.md#http-103-early-hints) for comprehensive testing instructions with browser DevTools and curl.
|
|
384
|
+
|
|
385
|
+
**Step 1: Enable early hints in your test environment**
|
|
386
|
+
|
|
387
|
+
```yaml
|
|
388
|
+
# config/shakapacker.yml
|
|
389
|
+
development: # or production
|
|
390
|
+
early_hints:
|
|
391
|
+
enabled: true
|
|
392
|
+
debug: true # Shows hints in HTML comments
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
**Step 2: Start Rails with Puma's `--early-hints` flag**
|
|
396
|
+
|
|
397
|
+
```bash
|
|
398
|
+
# Option 1: Test in development (if enabled above)
|
|
399
|
+
bundle exec puma --early-hints
|
|
400
|
+
|
|
401
|
+
# Option 2: Test in production mode locally (more realistic)
|
|
402
|
+
RAILS_ENV=production rails assets:precompile # Compile assets first
|
|
403
|
+
RAILS_ENV=production bundle exec puma --early-hints -e production
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
**Step 3: Test with curl**
|
|
407
|
+
|
|
408
|
+
```bash
|
|
409
|
+
# Use HTTP/1.1 (NOT HTTP/2)
|
|
410
|
+
curl -v http://localhost:3000/
|
|
411
|
+
|
|
412
|
+
# Look for this in output:
|
|
413
|
+
< HTTP/1.1 103 Early Hints
|
|
414
|
+
< link: </packs/application-abc123.js>; rel=preload; as=script
|
|
415
|
+
< link: </packs/application-abc123.css>; rel=preload; as=style
|
|
416
|
+
<
|
|
417
|
+
< HTTP/1.1 200 OK
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
**Important notes:**
|
|
421
|
+
|
|
422
|
+
- Use `http://` (not `https://`) for local testing
|
|
423
|
+
- Puma dev mode uses HTTP/1.1 (not HTTP/2)
|
|
424
|
+
- Test in production mode for realistic asset paths with content hashes
|
|
425
|
+
- Early hints must be `enabled: true` for the environment you're testing
|
|
426
|
+
|
|
427
|
+
### Production Setup
|
|
428
|
+
|
|
429
|
+
> **📚 Production Setup:** See the [main documentation](early_hints.md#requirements) for complete production setup instructions including Puma configuration, proxy setup (Thruster, nginx, Cloudflare), and troubleshooting proxy issues.
|
|
430
|
+
|
|
431
|
+
**Quick checklist:**
|
|
432
|
+
|
|
433
|
+
- Puma 5+ with `--early-hints` flag (REQUIRED)
|
|
434
|
+
- HTTP/2-capable proxy (Thruster ✅, nginx ✅, Cloudflare ✅, Control Plane ❌, AWS ALB ❌)
|
|
435
|
+
- Rails 5.2+
|
|
436
|
+
|
|
437
|
+
---
|
|
438
|
+
|
|
439
|
+
## Troubleshooting
|
|
440
|
+
|
|
441
|
+
> **📚 Complete Troubleshooting:** See the [main documentation](early_hints.md#troubleshooting) for comprehensive troubleshooting including debug mode, proxy configuration, and performance optimization.
|
|
442
|
+
|
|
443
|
+
Quick debugging steps:
|
|
444
|
+
|
|
445
|
+
1. Enable `debug: true` in shakapacker.yml to see hints in HTML comments
|
|
446
|
+
2. Verify Puma started with `--early-hints` flag
|
|
447
|
+
3. Test with `curl -v http://localhost:3000/` to see if Puma sends 103 responses
|
|
448
|
+
4. Check if your proxy strips 103 responses (Control Plane ❌, AWS ALB ❌)
|
|
449
|
+
|
|
450
|
+
### Reference
|
|
451
|
+
|
|
452
|
+
- [Main Early Hints Documentation](early_hints.md)
|
|
453
|
+
- [Feature Testing Guide](feature_testing.md#http-103-early-hints)
|
|
454
|
+
- [Rails 103 Early Hints Analysis](https://island94.org/2025/10/rails-103-early-hints-could-be-better-maybe-doesn-t-matter)
|