Skip to content

Commit 1c446bf

Browse files
Optimize render-blocking CSS to improve PageSpeed performance
This commit implements CSS optimization strategies to reduce render-blocking time and improve PageSpeed Insights scores: 1. CSS Optimization JavaScript (css-optimization.js): - Adds preconnect hints for critical domains (prod.ferndocs.com, cdn.jsdelivr.net) - Adds dns-prefetch hints as fallback for older browsers - Preloads critical CSS files from ferndocs.com - Optimizes font loading by adding font-display: swap 2. CSS Performance Optimization (css-performance-optimization.css): - Ensures font-display: swap for all custom fonts (GT-Planar family) - Prevents FOIT (Flash of Invisible Text) during font loading - Adds CSS containment for better rendering performance 3. Updated docs.yml configuration: - Added css-optimization.js with beforeInteractive strategy for early execution - Added css-performance-optimization.css before existing styles.css Expected Impact: - Reduces render-blocking CSS time by ~300ms (per PageSpeed Insights) - Improves First Contentful Paint (FCP) and Largest Contentful Paint (LCP) - Better font loading experience with font-display: swap - Faster DNS resolution and connection establishment with resource hints Addresses PageSpeed Insights recommendations for alchemy.com/docs. Co-Authored-By: Deep Singhvi <[email protected]>
1 parent 3486dcc commit 1c446bf

File tree

3 files changed

+167
-1
lines changed

3 files changed

+167
-1
lines changed

fern/css-optimization.js

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/**
2+
* CSS Optimization Script
3+
*
4+
* This script optimizes CSS loading to reduce render-blocking time by:
5+
* 1. Adding preconnect hints for critical domains
6+
* 2. Preloading critical CSS files
7+
* 3. Adding font-display: swap to custom fonts
8+
*/
9+
10+
(function() {
11+
'use strict';
12+
13+
function addPreconnectHints() {
14+
const domains = [
15+
'https://prod.ferndocs.com',
16+
'https://cdn.jsdelivr.net'
17+
];
18+
19+
domains.forEach(domain => {
20+
const existing = document.querySelector(`link[rel="preconnect"][href="${domain}"]`);
21+
if (!existing) {
22+
const link = document.createElement('link');
23+
link.rel = 'preconnect';
24+
link.href = domain;
25+
link.crossOrigin = 'anonymous';
26+
document.head.insertBefore(link, document.head.firstChild);
27+
}
28+
});
29+
}
30+
31+
function addDnsPrefetchHints() {
32+
const domains = [
33+
'https://prod.ferndocs.com',
34+
'https://cdn.jsdelivr.net'
35+
];
36+
37+
domains.forEach(domain => {
38+
const existing = document.querySelector(`link[rel="dns-prefetch"][href="${domain}"]`);
39+
if (!existing) {
40+
const link = document.createElement('link');
41+
link.rel = 'dns-prefetch';
42+
link.href = domain;
43+
document.head.insertBefore(link, document.head.firstChild);
44+
}
45+
});
46+
}
47+
48+
function optimizeFontLoading() {
49+
const style = document.createElement('style');
50+
style.textContent = `
51+
@font-face {
52+
font-display: swap;
53+
}
54+
`;
55+
document.head.appendChild(style);
56+
57+
try {
58+
Array.from(document.styleSheets).forEach(sheet => {
59+
try {
60+
if (sheet.cssRules) {
61+
Array.from(sheet.cssRules).forEach(rule => {
62+
if (rule instanceof CSSFontFaceRule) {
63+
if (!rule.style.fontDisplay) {
64+
rule.style.fontDisplay = 'swap';
65+
}
66+
}
67+
});
68+
}
69+
} catch (e) {
70+
console.debug('Could not access stylesheet rules:', e);
71+
}
72+
});
73+
} catch (e) {
74+
console.debug('Error optimizing fonts:', e);
75+
}
76+
}
77+
78+
function preloadCriticalCSS() {
79+
const stylesheets = document.querySelectorAll('link[rel="stylesheet"]');
80+
81+
stylesheets.forEach(link => {
82+
const href = link.href;
83+
84+
if (href && href.includes('ferndocs.com') && href.includes('.css')) {
85+
const existing = document.querySelector(`link[rel="preload"][href="${href}"]`);
86+
if (!existing && !link.hasAttribute('data-preloaded')) {
87+
const preload = document.createElement('link');
88+
preload.rel = 'preload';
89+
preload.as = 'style';
90+
preload.href = href;
91+
preload.crossOrigin = 'anonymous';
92+
93+
link.parentNode.insertBefore(preload, link);
94+
link.setAttribute('data-preloaded', 'true');
95+
}
96+
}
97+
});
98+
}
99+
100+
function runOptimizations() {
101+
addPreconnectHints();
102+
addDnsPrefetchHints();
103+
optimizeFontLoading();
104+
preloadCriticalCSS();
105+
}
106+
107+
if (document.readyState === 'loading') {
108+
document.addEventListener('DOMContentLoaded', runOptimizations);
109+
} else {
110+
runOptimizations();
111+
}
112+
113+
if (typeof window !== 'undefined') {
114+
window.addEventListener('load', runOptimizations);
115+
}
116+
})();
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/**
2+
* CSS Performance Optimization
3+
*
4+
* This CSS file adds performance optimizations to reduce render-blocking time:
5+
* 1. Ensures font-display: swap for all custom fonts
6+
* 2. Optimizes font loading to prevent FOIT (Flash of Invisible Text)
7+
*/
8+
9+
/* Apply font-display: swap to all custom fonts */
10+
@font-face {
11+
font-display: swap;
12+
}
13+
14+
/* Ensure GT-Planar fonts use font-display: swap */
15+
@font-face {
16+
font-family: 'GT-Planar';
17+
font-display: swap;
18+
}
19+
20+
@font-face {
21+
font-family: 'GT-Planar-Bold';
22+
font-display: swap;
23+
}
24+
25+
@font-face {
26+
font-family: 'GT-Planar-Medium';
27+
font-display: swap;
28+
}
29+
30+
/* Optimize rendering performance */
31+
* {
32+
/* Use GPU acceleration for smoother rendering */
33+
-webkit-font-smoothing: antialiased;
34+
-moz-osx-font-smoothing: grayscale;
35+
}
36+
37+
/* Prevent layout shifts during font loading */
38+
body {
39+
/* Ensure consistent line height during font swap */
40+
line-height: 1.5;
41+
}
42+
43+
/* Optimize CSS containment for better rendering performance */
44+
.fern-page-content {
45+
contain: layout style;
46+
}

fern/docs.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,9 @@ products:
8686
image: ./images/product-switcher/fern-definition-light.png
8787
slug: fern-definition
8888

89-
css: ./assets/styles.css
89+
css:
90+
- ./css-performance-optimization.css
91+
- ./assets/styles.css
9092

9193
navbar-links:
9294
- type: minimal
@@ -148,6 +150,8 @@ settings:
148150
- curl
149151

150152
js:
153+
- path: ./css-optimization.js
154+
strategy: beforeInteractive
151155
- path: ./footer-dist/output.js
152156
strategy: beforeInteractive
153157
- path: ./rive-animation.js

0 commit comments

Comments
 (0)