template-kit/size-assets
The template-kit/size-assets authoring rule — what it enforces, why, and how to fix it.
A section’s static assets — the svg, images, and fonts it imports or
url()-references — must total ≤ 250 KB raw. Raw, not gzip: images and fonts are already compressed formats, so gzipping them again buys nothing.
A section’s static assets are budgeted by total raw bytes, 250 KB or less. What is measured is every asset the published section actually ships:
- an svg, image, or font
imported directly inRenderer.tsx(or an island), and - an svg, image, or font
url()-referenced from the section’s own CSS or from a package stylesheet its module graph pulls in — including a webfont@font-faces.
The same asset referenced twice (from both a stylesheet and a component, say) counts once, not twice.
The budget is visible in template-kit check’s configuration and is not
author-overridable. A workspace cannot raise it, and there is no per-section exemption.
Reason
Section titled “Reason”An svg icon or a product photo a section imports, and a webfont a package’s stylesheet pulls in, both ship to the same page load as the section’s own code and CSS — they are not free just because they never appear in a byte-budget an author is used to watching.
Fonts are the sharpest case. A url()-referenced webfont used to inline as part of the
compiled stylesheet, which made a large font look like a CSS problem: trimming your own
rules never fixed it, because the bytes were never your CSS to begin with. This rule
separates that weight into its own budget — a font, an icon, or an image is measured as
what it is, and the stylesheet budget (size-section-css) is left
to measure only what it actually contains.
Two moves, in order of how often they work:
- Shrink or subset the asset. A full variable font family, shipped for three
weights actually used, is the usual cause — subset it to the characters and weights
the section renders. An unoptimized PNG is the other common case — recompress it, or
switch to a format built for the content (
webp/aviffor photos,svgfor icons). - Drop assets the section does not use. A copied-in icon set or a leftover preview image that never renders still ships its bytes — delete what the section does not reference.
Before
Section titled “Before”import "brandfont/css"; // ← ships the package's full variable font family
export default function Renderer() { return <h1 style={{ fontFamily: "BrandFont" }}>Welcome home</h1>;}import heroIcon from "./assets/hero-icon.svg"; // ← a small, single-purpose asset
export default function Renderer() { // Uses a font the template's theme already declares (`--tr-font-<name>`), // which costs nothing because it is already loaded — no package font import. return ( <h1 className="tr-font-display"> <img src={heroIcon} alt="" /> Welcome home </h1> );}See also
Section titled “See also”size-section-css— the stylesheet budget this rule was split out of; aurl()-referenced font now counts here, not there.size-renderer-bundle— the same idea applied to the section’s JavaScript.- Theme and CSS — the fonts and tokens the page already loads, which cost you nothing to reuse.