Skip to content

Commit e9e5f4a

Browse files
committed
Improve SVG Embedded Bitmap Analysis snippet
- Detect standalone inline SVGs vs those already using the sprite pattern and show the breakdown in the summary line - Add SVG Sprite Opportunity tip when 5+ standalone inline SVGs are found - Suppress Promise return value with void IIFE - Document the sprite tip and update Further Reading with <use> MDN link
1 parent 01babcb commit e9e5f4a

1 file changed

Lines changed: 59 additions & 4 deletions

File tree

pages/Media/SVG-Embedded-Bitmap-Analysis.mdx

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ The correct pattern is to reference bitmap assets as separate files:
3838
// SVG Embedded Bitmap Analysis
3939
// https://webperf-snippets.nucliweb.net
4040

41-
(async () => {
41+
void (async () => {
4242
function formatSize(bytes) {
4343
if (!bytes || bytes === 0) return "";
4444
if (bytes < 1024) return `${bytes} B`;
@@ -122,7 +122,11 @@ The correct pattern is to reference bitmap assets as separate files:
122122
);
123123

124124
// ── Inline <svg> elements (DOM scan) ────────────────────────────────
125-
const inlineSvgTotal = document.querySelectorAll("svg").length;
125+
const inlineSvgs = Array.from(document.querySelectorAll("svg"));
126+
const inlineSvgTotal = inlineSvgs.length;
127+
const svgsWithUse = inlineSvgs.filter((svg) => svg.querySelector("use")).length;
128+
const standaloneInlineSvgs = inlineSvgTotal - svgsWithUse;
129+
126130
const inlineResults = Array.from(document.querySelectorAll("svg"))
127131
.map((svg, i) => {
128132
const html = svg.outerHTML;
@@ -150,7 +154,11 @@ The correct pattern is to reference bitmap assets as separate files:
150154
console.log("");
151155
console.log("%cSummary", "font-weight: bold;");
152156
console.log(` External SVG files : ${svgEntries.length}`);
153-
console.log(` Inline <svg> elements : ${inlineSvgTotal}`);
157+
const inlineLabel =
158+
svgsWithUse > 0
159+
? `${inlineSvgTotal} (${svgsWithUse} using <use>, ${standaloneInlineSvgs} standalone)`
160+
: `${inlineSvgTotal}`;
161+
console.log(` Inline <svg> elements : ${inlineLabel}`);
154162
console.log(
155163
` SVGs with bitmaps : ${withBitmaps.length}${withBitmaps.length > 0 ? " ⚠️" : ""}`,
156164
);
@@ -211,6 +219,28 @@ The correct pattern is to reference bitmap assets as separate files:
211219
);
212220
}
213221

222+
if (standaloneInlineSvgs >= 5) {
223+
console.log("");
224+
console.group("%c💡 SVG Sprite Opportunity", "color: #3b82f6; font-weight: bold;");
225+
console.log("");
226+
console.log(` ${standaloneInlineSvgs} standalone inline <svg> elements detected.`);
227+
console.log(" Each one duplicates markup in the HTML and cannot be cached independently.");
228+
console.log(" Consider an SVG sprite: define each icon once as a <symbol> and");
229+
console.log(' reference it anywhere with <use href="#icon-id">.');
230+
console.log("");
231+
console.log('%c <!-- Sprite (once, hidden) -->', "font-family: monospace; color: #6b7280;");
232+
console.log(
233+
'%c <svg hidden>\n <symbol id="icon-arrow" viewBox="0 0 24 24">…</symbol>\n </svg>',
234+
"font-family: monospace;",
235+
);
236+
console.log('%c <!-- Usage (anywhere, N times) -->', "font-family: monospace; color: #6b7280;");
237+
console.log(
238+
'%c <svg aria-hidden="true"><use href="#icon-arrow"/></svg>',
239+
"font-family: monospace;",
240+
);
241+
console.groupEnd();
242+
}
243+
214244
console.groupEnd();
215245
})();
216246
```
@@ -222,7 +252,7 @@ The correct pattern is to reference bitmap assets as separate files:
222252
| Field | Description |
223253
| ----------------------- | --------------------------------------------------------------------------------------------------------- |
224254
| External SVG files | Count of SVG resources captured by the Performance API (loaded via `<img>`, `<object>`, CSS, fetch, etc.) |
225-
| Inline `<svg>` elements | Count of `<svg>` elements present in the DOM |
255+
| Inline `<svg>` elements | Count of `<svg>` elements present in the DOM. When some already use the sprite pattern the breakdown shows `N using <use>, M standalone` |
226256
| SVGs with bitmaps | SVGs (external or inline) that contain at least one embedded bitmap |
227257

228258
#### External SVG Resources Table
@@ -253,11 +283,36 @@ The correct pattern is to reference bitmap assets as separate files:
253283
| 🖼️ | `inline` | Base64-encoded bitmap embedded directly as a `data:image/…;base64,` URI. The reported size is an estimate derived from the base64 string length |
254284
| 🔗 | `external` | Bitmap file referenced via `href` or `xlink:href` on an `<image>` element. The bitmap is a separate HTTP request, but it is still discovered only after the SVG has loaded |
255285

286+
#### SVG Sprite Opportunity
287+
288+
When 5 or more standalone inline `<svg>` elements are detected (i.e. not already using `<use>`), the snippet shows a tip suggesting the SVG sprite pattern.
289+
290+
Inline SVGs repeated across a page inflate HTML size and cannot be cached independently. The sprite pattern defines each icon once as a `<symbol>` in a hidden `<svg>` block and references it anywhere with `<use href="#id">`:
291+
292+
```html
293+
<!-- Define once (hidden, ideally in a separate .svg file loaded via fetch or server-side include) -->
294+
<svg hidden>
295+
<symbol id="icon-arrow" viewBox="0 0 24 24">…</symbol>
296+
<symbol id="icon-close" viewBox="0 0 24 24">…</symbol>
297+
</svg>
298+
299+
<!-- Use anywhere, any number of times -->
300+
<svg aria-hidden="true"><use href="#icon-arrow"/></svg>
301+
<svg aria-hidden="true"><use href="#icon-close"/></svg>
302+
```
303+
304+
The summary line for inline `<svg>` elements shows a breakdown when the sprite pattern is already partially in use:
305+
306+
```
307+
Inline <svg> elements : 211 (5 using <use>, 206 standalone)
308+
```
309+
256310
> **CORS note**: The snippet fetches each SVG with `cache: "force-cache"` to read headers and content without triggering new network requests. Cross-origin SVGs without CORS headers cannot be read — in that case the snippet falls back to Performance API timing data for size and compression, and bitmap detection is skipped for that resource.
257311
258312
### Further Reading
259313

260314
- [SVG `<image>` element](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/image) | MDN
315+
- [SVG `<use>` element](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/use) | MDN
261316
- [Data URLs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URLs) | MDN
262317
- [SVGOMG](https://jakearchibald.github.io/svgomg/) | jakearchibald.github.io
263318
- [SVGO](https://github.com/svg/svgo) | GitHub

0 commit comments

Comments
 (0)