Skip to content

Commit 932e737

Browse files
committed
Add byte-size metrics for CSS media queries
1 parent 874dc69 commit 932e737

File tree

1 file changed

+63
-6
lines changed

1 file changed

+63
-6
lines changed

pages/Loading/CSS-Media-Queries-Analysis.mdx

Lines changed: 63 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
### CSS Media Queries Analysis
22

3-
Analyze all `@media` rules in CSS stylesheets to identify classes and properties targeting viewports bigger than a specified breakpoint (default: 768px). Results are grouped by inline CSS and external files.
3+
Analyze all `@media` rules in CSS stylesheets to identify classes and properties targeting viewports bigger than a specified breakpoint (default: 768px). Results are grouped by inline CSS and external files, with byte size estimates for potential mobile savings.
44

55
#### Snippet
66

@@ -16,6 +16,8 @@ function analyzeCSSMediaQueries(minWidth = 768) {
1616
let inlineTotalProperties = 0;
1717
let filesTotalClasses = 0;
1818
let filesTotalProperties = 0;
19+
let inlineTotalBytes = 0;
20+
let filesTotalBytes = 0;
1921

2022
// Helper to check if media query targets bigger than specified breakpoint
2123
function isBiggerThanBreakpoint(mediaText) {
@@ -41,7 +43,7 @@ function analyzeCSSMediaQueries(minWidth = 768) {
4143
return false;
4244
}
4345

44-
// Helper to count classes in CSS text
46+
// Helper to count classes and properties in CSS text
4547
function countClassesAndProperties(cssText) {
4648
const classMatches = cssText.match(/\.[a-zA-Z0-9_-]+/g) || [];
4749
const propertyMatches = cssText.match(/[a-z-]+\s*:/g) || [];
@@ -52,6 +54,20 @@ function analyzeCSSMediaQueries(minWidth = 768) {
5254
};
5355
}
5456

57+
// Helper to calculate byte size
58+
function getByteSize(text) {
59+
return new Blob([text]).size;
60+
}
61+
62+
// Helper to format bytes
63+
function formatBytes(bytes) {
64+
if (bytes === 0) return "0 Bytes";
65+
const k = 1024;
66+
const sizes = ["Bytes", "KB", "MB"];
67+
const i = Math.floor(Math.log(bytes) / Math.log(k));
68+
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
69+
}
70+
5571
// Iterate through all stylesheets
5672
stylesheets.forEach((sheet, sheetIndex) => {
5773
try {
@@ -69,23 +85,27 @@ function analyzeCSSMediaQueries(minWidth = 768) {
6985
if (isBiggerThanBreakpoint(mediaText)) {
7086
const cssText = rule.cssText;
7187
const counts = countClassesAndProperties(cssText);
88+
const byteSize = getByteSize(cssText);
7289

7390
const mediaQueryData = {
7491
source: source,
7592
mediaQuery: mediaText,
7693
classes: counts.classes,
7794
properties: counts.properties,
78-
cssTextLength: cssText.length,
95+
bytes: byteSize,
96+
bytesFormatted: formatBytes(byteSize),
7997
};
8098

8199
if (isInline) {
82100
inlineMediaQueries.push(mediaQueryData);
83101
inlineTotalClasses += counts.classes;
84102
inlineTotalProperties += counts.properties;
103+
inlineTotalBytes += byteSize;
85104
} else {
86105
fileMediaQueries.push(mediaQueryData);
87106
filesTotalClasses += counts.classes;
88107
filesTotalProperties += counts.properties;
108+
filesTotalBytes += byteSize;
89109
}
90110
}
91111
}
@@ -95,25 +115,41 @@ function analyzeCSSMediaQueries(minWidth = 768) {
95115
}
96116
});
97117

118+
const totalBytes = inlineTotalBytes + filesTotalBytes;
119+
98120
// Display results
99121
console.group(`📊 CSS Media Queries Analysis (min-width > ${minWidth}px)`);
100122
console.log(`Total @media rules found: ${inlineMediaQueries.length + fileMediaQueries.length}`);
101123
console.log(`Total classes: ${inlineTotalClasses + filesTotalClasses}`);
102124
console.log(`Total properties: ${inlineTotalProperties + filesTotalProperties}`);
103125
console.groupEnd();
104126

127+
// Mobile Savings Estimate
128+
console.group("💾 POTENTIAL MOBILE SAVINGS");
129+
console.log(
130+
`%cEstimated CSS bytes that mobile doesn't need: ${formatBytes(totalBytes)}`,
131+
"font-weight: bold; color: #22c55e; font-size: 14px;",
132+
);
133+
console.log(` └─ From inline CSS: ${formatBytes(inlineTotalBytes)}`);
134+
console.log(` └─ From external files: ${formatBytes(filesTotalBytes)}`);
135+
console.log("");
136+
console.log("💡 By splitting these styles into separate files with media queries,");
137+
console.log(" mobile users won't need to download, parse, or process this CSS.");
138+
console.groupEnd();
139+
105140
// Inline CSS Results
106141
console.group("🔷 INLINE CSS (<style> tags)");
107142
console.log(`Media queries: ${inlineMediaQueries.length}`);
108143
console.log(`Classes: ${inlineTotalClasses}`);
109144
console.log(`Properties: ${inlineTotalProperties}`);
145+
console.log(`Total size: ${formatBytes(inlineTotalBytes)}`);
110146
if (inlineMediaQueries.length > 0) {
111147
// console.table(inlineMediaQueries, [
112148
// "source",
113149
// "mediaQuery",
114150
// "classes",
115151
// "properties",
116-
// "cssTextLength",
152+
// "bytesFormatted",
117153
// ]);
118154
} else {
119155
console.log(`No inline media queries found for viewports > ${minWidth}px.`);
@@ -125,13 +161,14 @@ function analyzeCSSMediaQueries(minWidth = 768) {
125161
console.log(`Media queries: ${fileMediaQueries.length}`);
126162
console.log(`Classes: ${filesTotalClasses}`);
127163
console.log(`Properties: ${filesTotalProperties}`);
164+
console.log(`Total size: ${formatBytes(filesTotalBytes)}`);
128165
if (fileMediaQueries.length > 0) {
129166
// console.table(fileMediaQueries, [
130167
// "source",
131168
// "mediaQuery",
132169
// "classes",
133170
// "properties",
134-
// "cssTextLength",
171+
// "bytesFormatted",
135172
// ]);
136173
} else {
137174
console.log(`No external file media queries found for viewports > ${minWidth}px.`);
@@ -144,16 +181,22 @@ function analyzeCSSMediaQueries(minWidth = 768) {
144181
mediaQueries: inlineMediaQueries.length + fileMediaQueries.length,
145182
classes: inlineTotalClasses + filesTotalClasses,
146183
properties: inlineTotalProperties + filesTotalProperties,
184+
bytes: totalBytes,
185+
bytesFormatted: formatBytes(totalBytes),
147186
},
148187
inline: {
149188
mediaQueries: inlineMediaQueries.length,
150189
classes: inlineTotalClasses,
151190
properties: inlineTotalProperties,
191+
bytes: inlineTotalBytes,
192+
bytesFormatted: formatBytes(inlineTotalBytes),
152193
},
153194
files: {
154195
mediaQueries: fileMediaQueries.length,
155196
classes: filesTotalClasses,
156197
properties: filesTotalProperties,
198+
bytes: filesTotalBytes,
199+
bytesFormatted: formatBytes(filesTotalBytes),
157200
},
158201
},
159202
details: {
@@ -175,25 +218,33 @@ analyzeCSSMediaQueries();
175218

176219
The snippet analyzes and groups results by:
177220

221+
**Potential Mobile Savings:**
222+
223+
- **Estimated bytes** that mobile devices don't need to download/process
224+
- Breakdown by inline CSS vs external files
225+
- This represents CSS that could be eliminated from mobile experience by splitting files
226+
178227
**Inline CSS (`<style>` tags):**
179228

180229
- Number of @media rules targeting viewports larger than the specified breakpoint
181230
- Total CSS class selectors in inline media queries
182231
- Total CSS properties in inline media queries
232+
- Total byte size of inline media queries
183233

184234
**External Files (`.css` files):**
185235

186236
- Number of @media rules targeting viewports larger than the specified breakpoint
187237
- Total CSS class selectors in external file media queries
188238
- Total CSS properties in external file media queries
239+
- Total byte size of external file media queries
189240

190241
**Each media query includes:**
191242

192243
- **source**: Stylesheet URL or inline style tag identifier
193244
- **mediaQuery**: The media query condition (e.g., `min-width: 1024px`)
194245
- **classes**: Number of CSS class selectors
195246
- **properties**: Number of CSS properties
196-
- **cssTextLength**: Size of the CSS text in characters
247+
- **bytesFormatted**: Size of the CSS in bytes (KB/MB)
197248

198249
#### Customizing the Breakpoint
199250

@@ -253,6 +304,12 @@ Understanding how much CSS is dedicated to larger viewports helps identify optim
253304
- Use tools like PurgeCSS or UnCSS to remove unused selectors
254305
- Reduces overall CSS bundle size
255306

307+
**6. Measure the Impact**
308+
309+
- The "Potential Mobile Savings" metric shows exactly how many bytes mobile users could save
310+
- Compare this against your total CSS size to understand the optimization opportunity
311+
- Even 20-50 KB savings can improve mobile performance significantly
312+
256313
#### Further Reading
257314

258315
For an in-depth understanding of CSS and network performance optimization strategies, check out this excellent article:

0 commit comments

Comments
 (0)