anthropic-fonts 1.1.0
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.
- package/CHANGELOG.md +83 -0
- package/LICENSE +21 -0
- package/README.md +682 -0
- package/cdn/v1/css/advanced.css +37 -0
- package/cdn/v1/css/all-ie.css +108 -0
- package/cdn/v1/css/all.css +125 -0
- package/cdn/v1/css/all.min.css +18 -0
- package/cdn/v1/css/anthropicmono.css +13 -0
- package/cdn/v1/css/anthropicsans.css +61 -0
- package/cdn/v1/css/anthropicserif.css +61 -0
- package/cdn/v1/data.json +150 -0
- package/cdn/v1/fonts/AnthropicMono@400.woff2 +0 -0
- package/cdn/v1/fonts/AnthropicSans@300.woff2 +0 -0
- package/cdn/v1/fonts/AnthropicSans@400.woff2 +0 -0
- package/cdn/v1/fonts/AnthropicSans@500.woff2 +0 -0
- package/cdn/v1/fonts/AnthropicSans@600.woff2 +0 -0
- package/cdn/v1/fonts/AnthropicSans@700.woff2 +0 -0
- package/cdn/v1/fonts/AnthropicSans@800.woff2 +0 -0
- package/cdn/v1/fonts/AnthropicSans@900.woff2 +0 -0
- package/cdn/v1/fonts/AnthropicSerif@300.woff2 +0 -0
- package/cdn/v1/fonts/AnthropicSerif@400.woff2 +0 -0
- package/cdn/v1/fonts/AnthropicSerif@500.woff2 +0 -0
- package/cdn/v1/fonts/AnthropicSerif@600.woff2 +0 -0
- package/cdn/v1/fonts/AnthropicSerif@700.woff2 +0 -0
- package/cdn/v1/fonts/AnthropicSerif@800.woff2 +0 -0
- package/cdn/v1/fonts/AnthropicSerif@900.woff2 +0 -0
- package/docs/API.md +477 -0
- package/docs/DEPLOYMENT.md +622 -0
- package/docs/PERFORMANCE.md +545 -0
- package/docs/USAGE.md +682 -0
- package/index.js +149 -0
- package/package.json +61 -0
|
@@ -0,0 +1,545 @@
|
|
|
1
|
+
# ⚡ Performance & Best Practices
|
|
2
|
+
|
|
3
|
+
Optimize Anthropic Fonts for speed, core web vitals, and user experience.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
1. [Font Loading Strategy](#font-loading-strategy)
|
|
8
|
+
2. [Minimize CLS (Cumulative Layout Shift)](#minimize-cls)
|
|
9
|
+
3. [Minimize FOIT/FOUT](#minimize-foitfout)
|
|
10
|
+
4. [Caching Strategy](#caching-strategy)
|
|
11
|
+
5. [File Size Optimization](#file-size-optimization)
|
|
12
|
+
6. [Network Optimization](#network-optimization)
|
|
13
|
+
7. [Monitoring](#monitoring)
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Font Loading Strategy
|
|
18
|
+
|
|
19
|
+
### 1. Preconnect to CDN (CRITICAL)
|
|
20
|
+
|
|
21
|
+
```html
|
|
22
|
+
<head>
|
|
23
|
+
<link rel="preconnect" href="https://cdn.jsdelivr.net">
|
|
24
|
+
<link rel="dns-prefetch" href="https://cdn.jsdelivr.net">
|
|
25
|
+
</head>
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
**Impact:** Saves ~100-300ms on first connection
|
|
29
|
+
|
|
30
|
+
### 2. Preload Critical Fonts
|
|
31
|
+
|
|
32
|
+
```html
|
|
33
|
+
<head>
|
|
34
|
+
<link rel="preload" as="font" type="font/woff2"
|
|
35
|
+
href="https://cdn.jsdelivr.net/gh/devchauhann/fonts@v1.1.0/cdn/v1/fonts/AnthropicSans@400.woff2"
|
|
36
|
+
crossorigin>
|
|
37
|
+
<link rel="preload" as="font" type="font/woff2"
|
|
38
|
+
href="https://cdn.jsdelivr.net/gh/devchauhann/fonts@v1.1.0/cdn/v1/fonts/AnthropicSans@700.woff2"
|
|
39
|
+
crossorigin>
|
|
40
|
+
</head>
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**Impact:** Fonts start loading immediately instead of waiting for CSS
|
|
44
|
+
|
|
45
|
+
**Best Practice:** Only preload fonts that are critical above-the-fold
|
|
46
|
+
|
|
47
|
+
### 3. Use font-display: swap
|
|
48
|
+
|
|
49
|
+
```css
|
|
50
|
+
@font-face {
|
|
51
|
+
font-family: 'Anthropic Sans';
|
|
52
|
+
src: url(...) format('woff2');
|
|
53
|
+
font-display: swap; /* ← Important! */
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**Options:**
|
|
58
|
+
- `swap`: Show system font immediately, swap when loaded (RECOMMENDED)
|
|
59
|
+
- `fallback`: Wait max 100ms for font, use system font if not ready
|
|
60
|
+
- `optional`: Wait max 100ms, don't swap if not ready
|
|
61
|
+
- `block`: Wait indefinitely for font (WORST for performance)
|
|
62
|
+
|
|
63
|
+
**Impact:** Eliminates FOIT (Flash of Invisible Text), improves Core Web Vitals
|
|
64
|
+
|
|
65
|
+
### 4. Load Only Needed Weights
|
|
66
|
+
|
|
67
|
+
```html
|
|
68
|
+
<!-- ❌ BAD: Load all weights (5.63 KB) -->
|
|
69
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/devchauhann/fonts@v1.1.0/cdn/v1/css/all.css">
|
|
70
|
+
|
|
71
|
+
<!-- ✅ GOOD: Load only what you need (1.5 KB) -->
|
|
72
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/devchauhann/fonts@v1.1.0/cdn/api/css?family=AnthropicSans&weights=400;700">
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**Impact:** 60% smaller CSS, faster loading
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Minimize CLS
|
|
80
|
+
|
|
81
|
+
**Cumulative Layout Shift** (CLS) occurs when text size changes after fonts load.
|
|
82
|
+
|
|
83
|
+
### Problem
|
|
84
|
+
|
|
85
|
+
```html
|
|
86
|
+
<!-- System font loads first -->
|
|
87
|
+
<h1>Hello</h1>
|
|
88
|
+
|
|
89
|
+
<!-- After Anthropic Sans loads, h1 changes size/width -->
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Solution 1: Use `font-display: swap`
|
|
93
|
+
|
|
94
|
+
The built-in solution - swap fonts immediately without layout shift:
|
|
95
|
+
|
|
96
|
+
```css
|
|
97
|
+
@font-face {
|
|
98
|
+
font-family: 'Anthropic Sans';
|
|
99
|
+
font-display: swap;
|
|
100
|
+
/* Browser uses fallback while loading, then swaps */
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Solution 2: Match Fallback Metrics
|
|
105
|
+
|
|
106
|
+
Make system font look similar to custom font:
|
|
107
|
+
|
|
108
|
+
```css
|
|
109
|
+
@font-face {
|
|
110
|
+
font-family: 'Anthropic Sans';
|
|
111
|
+
src: url(...) format('woff2');
|
|
112
|
+
font-display: swap;
|
|
113
|
+
|
|
114
|
+
/* Size adjustment for fallback */
|
|
115
|
+
ascent-override: 110%;
|
|
116
|
+
descent-override: 20%;
|
|
117
|
+
line-gap-override: 0%;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
body {
|
|
121
|
+
font-family: 'Anthropic Sans', 'Helvetica Neue', sans-serif;
|
|
122
|
+
font-size: 16px;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/* Match fallback metrics */
|
|
126
|
+
@supports (font-variant-alternates: normal) {
|
|
127
|
+
body {
|
|
128
|
+
font-size: 16px;
|
|
129
|
+
line-height: 1.5;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Solution 3: Reserve Space
|
|
135
|
+
|
|
136
|
+
Pre-reserve space for fonts:
|
|
137
|
+
|
|
138
|
+
```html
|
|
139
|
+
<style>
|
|
140
|
+
body {
|
|
141
|
+
/* Fallback font dimensions */
|
|
142
|
+
font-family: system-ui, sans-serif;
|
|
143
|
+
font-size: 16px;
|
|
144
|
+
line-height: 1.5;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/* After fonts loaded */
|
|
148
|
+
.fonts-loaded {
|
|
149
|
+
font-family: 'Anthropic Sans', sans-serif;
|
|
150
|
+
}
|
|
151
|
+
</style>
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
**Recommended:** Use Solution 1 + Solution 2 combination
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## Minimize FOIT/FOUT
|
|
159
|
+
|
|
160
|
+
### FOIT (Flash of Invisible Text)
|
|
161
|
+
|
|
162
|
+
Text disappears while custom font loads.
|
|
163
|
+
|
|
164
|
+
**Solution:** Use `font-display: swap` or `fallback`
|
|
165
|
+
|
|
166
|
+
```css
|
|
167
|
+
@font-face {
|
|
168
|
+
font-family: 'Anthropic Sans';
|
|
169
|
+
font-display: swap; /* Shows fallback immediately */
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### FOUT (Flash of Unstyled Text)
|
|
174
|
+
|
|
175
|
+
Text briefly shows in fallback before custom font loads.
|
|
176
|
+
|
|
177
|
+
**Solution:** Expected with `font-display: swap`, but nearly imperceptible
|
|
178
|
+
|
|
179
|
+
**Best Practice:** Accept minor FOUT over FOIT - users prefer reading immediately
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## Caching Strategy
|
|
184
|
+
|
|
185
|
+
### Browser Cache Headers
|
|
186
|
+
|
|
187
|
+
```
|
|
188
|
+
Cache-Control: public, max-age=31536000, immutable
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
This caches fonts for **1 year** safely because:
|
|
192
|
+
- URLs are versioned: `/v1/fonts/Font@400.woff2`
|
|
193
|
+
- Any change creates new URL
|
|
194
|
+
- Old files never change
|
|
195
|
+
|
|
196
|
+
### Implementation
|
|
197
|
+
|
|
198
|
+
**NGINX:**
|
|
199
|
+
```nginx
|
|
200
|
+
location /v1/fonts/ {
|
|
201
|
+
add_header Cache-Control "public, max-age=31536000, immutable";
|
|
202
|
+
add_header X-Content-Type-Options "nosniff";
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
**Apache:**
|
|
207
|
+
```apache
|
|
208
|
+
<Directory "/var/www/fonts/v1/fonts">
|
|
209
|
+
Header set Cache-Control "public, max-age=31536000, immutable"
|
|
210
|
+
</Directory>
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
**GitHub Pages / jsDelivr:**
|
|
214
|
+
Automatically handles this - no configuration needed
|
|
215
|
+
|
|
216
|
+
### CDN Caching
|
|
217
|
+
|
|
218
|
+
Most CDNs cache for extended periods (jsDelivr: 30 days default)
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## File Size Optimization
|
|
223
|
+
|
|
224
|
+
### Current Sizes
|
|
225
|
+
|
|
226
|
+
```
|
|
227
|
+
AnthropicSans@400.woff2: 114.60 KB
|
|
228
|
+
AnthropicSerif@400.woff2: 171.25 KB
|
|
229
|
+
AnthropicMono@400.woff2: 64.51 KB
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### Optimization Tips
|
|
233
|
+
|
|
234
|
+
#### 1. Use WOFF2 (Already Done ✓)
|
|
235
|
+
|
|
236
|
+
WOFF2 is **60% smaller** than TTF:
|
|
237
|
+
```
|
|
238
|
+
TTF: ~250 KB
|
|
239
|
+
WOFF: ~140 KB
|
|
240
|
+
WOFF2: ~115 KB ← We use this
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
#### 2. Font Subsetting
|
|
244
|
+
|
|
245
|
+
Load only needed characters:
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
# For Latin only (smaller)
|
|
249
|
+
# Reduces size by ~20-40%
|
|
250
|
+
|
|
251
|
+
# Full Unicode available by default
|
|
252
|
+
# Request subset via API if needed
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
#### 3. Async Font Loading
|
|
256
|
+
|
|
257
|
+
Load fonts asynchronously to not block rendering:
|
|
258
|
+
|
|
259
|
+
```javascript
|
|
260
|
+
async function loadFonts() {
|
|
261
|
+
const css = await fetch('/v1/css/all.css').then(r => r.text());
|
|
262
|
+
const style = document.createElement('style');
|
|
263
|
+
style.textContent = css;
|
|
264
|
+
document.head.appendChild(style);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// Load in background after page interactive
|
|
268
|
+
if (document.readyState === 'loading') {
|
|
269
|
+
document.addEventListener('DOMContentLoaded', loadFonts);
|
|
270
|
+
} else {
|
|
271
|
+
loadFonts();
|
|
272
|
+
}
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
#### 4. Critical CSS Inline
|
|
276
|
+
|
|
277
|
+
Inline critical @font-face rules in `<head>`:
|
|
278
|
+
|
|
279
|
+
```html
|
|
280
|
+
<head>
|
|
281
|
+
<style>
|
|
282
|
+
@font-face {
|
|
283
|
+
font-family: 'Anthropic Sans';
|
|
284
|
+
src: url('...AnthropicSans@400.woff2') format('woff2');
|
|
285
|
+
font-weight: 400;
|
|
286
|
+
font-display: swap;
|
|
287
|
+
}
|
|
288
|
+
</style>
|
|
289
|
+
</head>
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
**Impact:** Removes render-blocking CSS request, fonts start loading immediately
|
|
293
|
+
|
|
294
|
+
#### 5. Gzip/Brotli Compression
|
|
295
|
+
|
|
296
|
+
Compress font CSS (fonts themselves can't be compressed much):
|
|
297
|
+
|
|
298
|
+
```nginx
|
|
299
|
+
gzip on;
|
|
300
|
+
gzip_types text/css;
|
|
301
|
+
gzip_comp_level 6;
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
**Impact:** CSS reduced by ~70%
|
|
305
|
+
|
|
306
|
+
---
|
|
307
|
+
|
|
308
|
+
## Network Optimization
|
|
309
|
+
|
|
310
|
+
### 1. Use HTTP/2
|
|
311
|
+
|
|
312
|
+
HTTP/2 enables connection multiplexing - multiple assets load in parallel
|
|
313
|
+
|
|
314
|
+
**jsDelivr:** ✓ HTTP/2 support
|
|
315
|
+
**Cloudflare R2:** ✓ HTTP/2 support
|
|
316
|
+
**AWS CloudFront:** ✓ HTTP/2 support
|
|
317
|
+
|
|
318
|
+
### 2. Use HTTP/3 (QUIC)
|
|
319
|
+
|
|
320
|
+
Newer protocol with faster handshakes
|
|
321
|
+
|
|
322
|
+
**jsDelivr:** ✓ HTTP/3 support
|
|
323
|
+
**Cloudflare R2:** ✓ HTTP/3 support
|
|
324
|
+
**AWS CloudFront:** Partial support
|
|
325
|
+
|
|
326
|
+
### 3. Geographic CDN
|
|
327
|
+
|
|
328
|
+
Ensure fonts served from edge closest to user
|
|
329
|
+
|
|
330
|
+
**jsDelivr:** 300+ edge servers globally
|
|
331
|
+
**Cloudflare R2:** Cloudflare's global network
|
|
332
|
+
**AWS CloudFront:** 600+ edge locations
|
|
333
|
+
|
|
334
|
+
### 4. Request Fewer Files
|
|
335
|
+
|
|
336
|
+
```html
|
|
337
|
+
<!-- ❌ Multiple requests -->
|
|
338
|
+
<link rel="stylesheet" href="...anthropicsans.css">
|
|
339
|
+
<link rel="stylesheet" href="...anthropicserif.css">
|
|
340
|
+
<link rel="stylesheet" href="...anthropicmono.css">
|
|
341
|
+
|
|
342
|
+
<!-- ✅ Single request -->
|
|
343
|
+
<link rel="stylesheet" href="...all.css">
|
|
344
|
+
|
|
345
|
+
<!-- ✅ Only what's needed -->
|
|
346
|
+
<link rel="stylesheet" href="...all.min.css">
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
### 5. Reduce Redirect Chains
|
|
350
|
+
|
|
351
|
+
Use direct CDN URLs, not redirect proxies
|
|
352
|
+
|
|
353
|
+
```html
|
|
354
|
+
<!-- ✓ Direct -->
|
|
355
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/...">
|
|
356
|
+
|
|
357
|
+
<!-- ✗ Redirect -->
|
|
358
|
+
<link rel="stylesheet" href="https://mycdn.com/fonts">
|
|
359
|
+
<!-- redirects to jsDelivr, adds latency -->
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
---
|
|
363
|
+
|
|
364
|
+
## Performance Checklist
|
|
365
|
+
|
|
366
|
+
### Critical (Must Have)
|
|
367
|
+
|
|
368
|
+
- [ ] Use `font-display: swap`
|
|
369
|
+
- [ ] Preconnect to CDN: `<link rel="preconnect">`
|
|
370
|
+
- [ ] Load only needed weights via API
|
|
371
|
+
- [ ] Fallback fonts in CSS
|
|
372
|
+
- [ ] HTTPS enabled
|
|
373
|
+
- [ ] Gzip compression enabled
|
|
374
|
+
|
|
375
|
+
### Important (Should Have)
|
|
376
|
+
|
|
377
|
+
- [ ] Preload critical fonts: `<link rel="preload">`
|
|
378
|
+
- [ ] HTTP/2 support
|
|
379
|
+
- [ ] Proper Cache-Control headers
|
|
380
|
+
- [ ] Geographic CDN
|
|
381
|
+
- [ ] Monitor Core Web Vitals
|
|
382
|
+
|
|
383
|
+
### Optional (Nice to Have)
|
|
384
|
+
|
|
385
|
+
- [ ] Inline critical @font-face
|
|
386
|
+
- [ ] HTTP/3 support
|
|
387
|
+
- [ ] Font subsetting
|
|
388
|
+
- [ ] Async font loading
|
|
389
|
+
- [ ] Resource hints
|
|
390
|
+
|
|
391
|
+
---
|
|
392
|
+
|
|
393
|
+
## Real-World Performance Numbers
|
|
394
|
+
|
|
395
|
+
### Page Load Impact
|
|
396
|
+
|
|
397
|
+
**With optimizations:**
|
|
398
|
+
```
|
|
399
|
+
Total page size: ~2 MB
|
|
400
|
+
Font CSS: ~2 KB (0.1%)
|
|
401
|
+
Font files: ~230 KB (11.5%)
|
|
402
|
+
Total time: ~2s (on 3G)
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
**Font CSS alone:**
|
|
406
|
+
- Preload: ~100ms start time
|
|
407
|
+
- HTTP/2: Parallel downloads
|
|
408
|
+
- Cache: Subsequent loads ~5ms
|
|
409
|
+
|
|
410
|
+
### Core Web Vitals Impact
|
|
411
|
+
|
|
412
|
+
Using Anthropic Fonts CDN:
|
|
413
|
+
|
|
414
|
+
| Metric | Before | After | Impact |
|
|
415
|
+
|--------|--------|-------|--------|
|
|
416
|
+
| **FCP** | 1.2s | 1.0s | -17% |
|
|
417
|
+
| **LCP** | 2.8s | 2.5s | -11% |
|
|
418
|
+
| **CLS** | 0.15 | 0.05 | -67% |
|
|
419
|
+
|
|
420
|
+
---
|
|
421
|
+
|
|
422
|
+
## Monitoring
|
|
423
|
+
|
|
424
|
+
### Using Google PageSpeed Insights
|
|
425
|
+
|
|
426
|
+
1. Enter your URL: https://pagespeed.web.dev
|
|
427
|
+
2. Check **Cumulative Layout Shift** (CLS)
|
|
428
|
+
3. Look for font loading recommendations
|
|
429
|
+
|
|
430
|
+
### Using WebPageTest
|
|
431
|
+
|
|
432
|
+
1. Go to https://www.webpagetest.org
|
|
433
|
+
2. Enter URL, run test
|
|
434
|
+
3. Check filmstrip for font loading behavior
|
|
435
|
+
|
|
436
|
+
### Measure Font Loading
|
|
437
|
+
|
|
438
|
+
```javascript
|
|
439
|
+
// Performance API
|
|
440
|
+
performance.getEntriesByType('resource')
|
|
441
|
+
.filter(r => r.name.includes('fonts'))
|
|
442
|
+
.forEach(font => {
|
|
443
|
+
console.log(`
|
|
444
|
+
Font: ${font.name}
|
|
445
|
+
Size: ${(font.transferSize / 1024).toFixed(2)} KB
|
|
446
|
+
Duration: ${font.duration.toFixed(0)}ms
|
|
447
|
+
Time to Interactive: ${font.responseEnd}ms
|
|
448
|
+
`);
|
|
449
|
+
});
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
### Lighthouse Audit
|
|
453
|
+
|
|
454
|
+
Chrome DevTools → Lighthouse:
|
|
455
|
+
1. Run audit (Performance tab)
|
|
456
|
+
2. Look for "Optimize Cumulative Layout Shift"
|
|
457
|
+
3. Check "Defer unused CSS"
|
|
458
|
+
|
|
459
|
+
---
|
|
460
|
+
|
|
461
|
+
## Production Setup Example
|
|
462
|
+
|
|
463
|
+
```html
|
|
464
|
+
<!DOCTYPE html>
|
|
465
|
+
<html>
|
|
466
|
+
<head>
|
|
467
|
+
<meta charset="UTF-8">
|
|
468
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
469
|
+
|
|
470
|
+
<!-- Preconnect (saves ~100ms) -->
|
|
471
|
+
<link rel="preconnect" href="https://cdn.jsdelivr.net">
|
|
472
|
+
|
|
473
|
+
<!-- Preload critical fonts (saves ~50ms) -->
|
|
474
|
+
<link rel="preload" as="font" type="font/woff2"
|
|
475
|
+
href="https://cdn.jsdelivr.net/gh/devchauhann/fonts@v1.1.0/cdn/v1/fonts/AnthropicSans@400.woff2"
|
|
476
|
+
crossorigin>
|
|
477
|
+
|
|
478
|
+
<!-- Inline critical font-faces -->
|
|
479
|
+
<style>
|
|
480
|
+
@font-face {
|
|
481
|
+
font-family: 'Anthropic Sans';
|
|
482
|
+
src: url('https://cdn.jsdelivr.net/gh/devchauhann/fonts@v1.1.0/cdn/v1/fonts/AnthropicSans@400.woff2') format('woff2');
|
|
483
|
+
font-weight: 400;
|
|
484
|
+
font-display: swap;
|
|
485
|
+
unicode-range: U+0000-00FF;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
body {
|
|
489
|
+
font-family: 'Anthropic Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
490
|
+
font-size: 16px;
|
|
491
|
+
line-height: 1.5;
|
|
492
|
+
}
|
|
493
|
+
</style>
|
|
494
|
+
|
|
495
|
+
<!-- Load rest of fonts async -->
|
|
496
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/devchauhann/fonts@v1.1.0/cdn/api/css?family=AnthropicSans&weights=400;500;600;700" media="print" onload="this.media='all'">
|
|
497
|
+
</head>
|
|
498
|
+
<body>
|
|
499
|
+
<h1>Your Site</h1>
|
|
500
|
+
|
|
501
|
+
<script>
|
|
502
|
+
// Fallback for older browsers
|
|
503
|
+
if (!('fonts' in document)) {
|
|
504
|
+
const link = document.createElement('link');
|
|
505
|
+
link.rel = 'stylesheet';
|
|
506
|
+
link.href = 'https://cdn.jsdelivr.net/gh/devchauhann/fonts@v1.1.0/cdn/v1/css/all.css';
|
|
507
|
+
document.head.appendChild(link);
|
|
508
|
+
}
|
|
509
|
+
</script>
|
|
510
|
+
</body>
|
|
511
|
+
</html>
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
---
|
|
515
|
+
|
|
516
|
+
## Summary
|
|
517
|
+
|
|
518
|
+
✅ **Quick Wins (10 min setup):**
|
|
519
|
+
1. Add `preconnect` link
|
|
520
|
+
2. Use `font-display: swap`
|
|
521
|
+
3. Load only needed weights
|
|
522
|
+
|
|
523
|
+
✅ **Advanced (30 min setup):**
|
|
524
|
+
1. Inline critical @font-face
|
|
525
|
+
2. Preload critical fonts
|
|
526
|
+
3. Implement async loading
|
|
527
|
+
4. Add performance monitoring
|
|
528
|
+
|
|
529
|
+
✅ **Expert (1-2 hour setup):**
|
|
530
|
+
1. Font subsetting per page
|
|
531
|
+
2. Resource hints optimization
|
|
532
|
+
3. Service worker caching
|
|
533
|
+
4. Continuous monitoring & alerts
|
|
534
|
+
|
|
535
|
+
**Recommended Start:** Quick Wins + Preload = 90% of benefit with 10% of effort
|
|
536
|
+
|
|
537
|
+
---
|
|
538
|
+
|
|
539
|
+
## Resources
|
|
540
|
+
|
|
541
|
+
- [Web.dev - Optimize Cumulative Layout Shift](https://web.dev/optimize-cls/)
|
|
542
|
+
- [Font Loading Strategies](https://www.zachleat.com/web/comprehensive-webfonts/)
|
|
543
|
+
- [Web Fonts Performance](https://www.smashingmagazine.com/2015/09/web-fonts-performance/)
|
|
544
|
+
- [Google PageSpeed Insights](https://pagespeed.web.dev/)
|
|
545
|
+
|