[{"data":1,"prerenderedAt":1220},["ShallowReactive",2],{"content:\u002Fcore-web-vitals-measurement\u002Ffont-loading-and-text-rendering-performance\u002Fvariable-fonts-vs-static-font-weights":3,"surroundings:\u002Fcore-web-vitals-measurement\u002Ffont-loading-and-text-rendering-performance\u002Fvariable-fonts-vs-static-font-weights":1211},{"id":4,"title":5,"body":6,"description":1190,"extension":1191,"meta":1192,"navigation":1204,"path":1205,"seo":1206,"stem":1209,"__hash__":1210},"content\u002Fcore-web-vitals-measurement\u002Ffont-loading-and-text-rendering-performance\u002Fvariable-fonts-vs-static-font-weights\u002Findex.md","Variable Fonts vs Static Font Weights",{"type":7,"value":8,"toc":1175},"minimark",[9,14,29,32,150,155,189,193,199,205,211,217,357,361,366,635,638,642,645,712,715,719,722,725,729,886,889,1020,1024,1031,1035,1042,1046,1079,1083,1098,1115,1124,1133,1137,1160,1165,1168,1171],[10,11,13],"h1",{"id":12},"variable-fonts-vs-static-font-weights-which-loads-faster","Variable Fonts vs Static Font Weights: Which Loads Faster?",[15,16,17,18,23,24,28],"p",{},"This comparison sits under ",[19,20,22],"a",{"href":21},"\u002Fcore-web-vitals-measurement\u002Ffont-loading-and-text-rendering-performance\u002F","Font Loading & Text Rendering Performance"," in ",[19,25,27],{"href":26},"\u002Fcore-web-vitals-measurement\u002F","Core Web Vitals & Measurement",". A variable font packs a continuous range of weights (and sometimes widths, slants or optical sizes) into one file. A static setup ships a separate file per weight and style. The performance question is not which is \"modern\" but which delivers the glyphs your page needs, for its LCP text, in fewer bytes and round trips.",[15,30,31],{},"The answer depends mostly on how many weights you actually use. A variable font file is larger than any single static weight — typically 1.5 to 2.5 times — but smaller than three or four static weights combined. Below the break-even point static fonts win; above it, the variable font does. Design systems that use two weights (regular and bold) often pay more for a variable font than they gain.",[15,33,34],{},[35,36,42,43,42,50,42,54,42,57,42,66,42,72,42,79,42,88,42,93,42,97,42,101,42,105,42,109,42,113,42,117,42,121,42,128,42,132,42,136,42,140,42,144,42],"svg",{"viewBox":37,"width":38,"role":39,"ariaLabel":40,"style":41},"0 0 760 251","100%","img","Bar chart comparing total bytes of static weights versus a single variable font file as the number of weights used grows.","height:auto;max-width:760px;display:block;margin:1.75rem auto;font-family:inherit;color:var(--fp-svg-ink)"," ",[44,45],"rect",{"className":46,"x":48,"y":48,"width":38,"height":38,"fill":49},[47],"svg-canvas","0","#ffffff",[51,52,53],"title",{},"Total font bytes by number of weights used (Latin subset, WOFF2)",[55,56,40],"desc",{},[44,58],{"x":59,"y":59,"width":60,"height":61,"rx":62,"fill":63,"stroke":64,"style":65},"1","758","249","10","none","currentColor","stroke-opacity:0.18",[67,68,53],"text",{"x":69,"y":70,"fill":64,"style":71},"28.0","34.0","font-size:16px;font-weight:700",[67,73,78],{"x":74,"y":75,"fill":64,"style":76,"textAnchor":77},"175.3","70.0","font-size:13px","end","1 static weight",[44,80],{"x":81,"y":82,"width":83,"height":84,"rx":85,"fill":86,"stroke":86,"style":87},"187.3","56.0","120.2","19","3","#0466c8","fill-opacity:0.55;stroke-opacity:0.9",[67,89,92],{"x":90,"y":75,"fill":64,"style":91},"313.4","font-size:12px;font-weight:600","21KB",[67,94,96],{"x":74,"y":95,"fill":64,"style":76,"textAnchor":77},"101.0","2 static weights",[44,98],{"x":81,"y":99,"width":100,"height":84,"rx":85,"fill":86,"stroke":86,"style":87},"87.0","240.4",[67,102,104],{"x":103,"y":95,"fill":64,"style":91},"433.6","42KB",[67,106,108],{"x":74,"y":107,"fill":64,"style":76,"textAnchor":77},"132.0","3 static weights",[44,110],{"x":81,"y":111,"width":112,"height":84,"rx":85,"fill":86,"stroke":86,"style":87},"118.0","360.6",[67,114,116],{"x":115,"y":107,"fill":64,"style":91},"553.8","63KB",[67,118,120],{"x":74,"y":119,"fill":64,"style":76,"textAnchor":77},"163.0","4 static weights",[44,122],{"x":81,"y":123,"width":124,"height":84,"rx":85,"fill":125,"stroke":126,"style":127},"149.0","480.7","#ffc300","#b8860b","fill-opacity:0.7;stroke-opacity:0.9",[67,129,131],{"x":130,"y":119,"fill":64,"style":91},"674.0","84KB",[67,133,135],{"x":74,"y":134,"fill":64,"style":76,"textAnchor":77},"194.0","Variable font (all weights)",[44,137],{"x":81,"y":138,"width":139,"height":84,"rx":85,"fill":86,"stroke":86,"style":87},"180.0","331.9",[67,141,143],{"x":142,"y":134,"fill":64,"style":91},"525.2","58KB",[67,145,149],{"x":69,"y":146,"fill":147,"style":148},"229.0","#51617a","font-size:12.5px","The break-even here is between two and three weights; italics double both sides of the comparison.",[151,152,154],"h2",{"id":153},"rapid-diagnosis","Rapid Diagnosis",[156,157,158,171,177,183],"ul",{},[159,160,161,165,166,170],"li",{},[162,163,164],"strong",{},"Count the weights your CSS uses."," Search for ",[167,168,169],"code",{},"font-weight"," values and resolve them against your font families. Many sites declare five and use two.",[159,172,173,176],{},[162,174,175],{},"Check which weight the LCP text uses."," If your heading is bold and body text regular, LCP depends on one file in the static setup — but on the whole variable file in the variable setup.",[159,178,179,182],{},[162,180,181],{},"Compare actual file sizes"," after subsetting, not vendor-reported full-font sizes.",[159,184,185,188],{},[162,186,187],{},"Check for synthetic bold or italic."," If a style is used but no matching face is declared, the browser synthesises it, which looks worse and can shift layout when a real face later loads.",[151,190,192],{"id":191},"root-cause-analysis","Root Cause Analysis",[15,194,195,198],{},[162,196,197],{},"1. Variable fonts front-load bytes."," The single file contains all the outline and variation data; the LCP heading waits for all of it, even if only one weight is visible above the fold.",[15,200,201,204],{},[162,202,203],{},"2. Static fonts multiply requests."," Each weight is a separate request; on HTTP\u002F2 that is cheap in round trips but adds per-file overhead and staggered swaps as each arrives.",[15,206,207,210],{},[162,208,209],{},"3. Staggered swaps cause visual churn."," With static weights, regular text may swap at 600ms and bold at 900ms, re-wrapping lines twice. A variable font swaps all weights at once.",[15,212,213,216],{},[162,214,215],{},"4. Rendering cost differences are small."," Variable fonts require interpolation at render time, but modern engines cache instances; for typical pages the rendering cost difference is negligible compared with download time.",[15,218,219],{},[35,220,42,223,42,226,42,229,42,231,42,234,42,236,42,241,42,248,42,252,42,257,42,260,42,264,42,268,42,272,42,275,42,279,42,282,42,285,42,288,42,292,42,294,42,296,42,298,42,300,42,303,42,307,42,309,42,312,42,314,42,317,42,320,42,324,42,326,42,329,42,331,42,334,42,338,42,342,42,346,42,348,42,352,42,354,42],{"viewBox":221,"width":38,"role":39,"ariaLabel":222,"style":41},"0 0 760 274","Comparison of a variable font and static weights across bytes, requests, swap behaviour and design flexibility.",[44,224],{"className":225,"x":48,"y":48,"width":38,"height":38,"fill":49},[47],[51,227,228],{},"Choosing between variable and static fonts",[55,230,222],{},[44,232],{"x":59,"y":59,"width":60,"height":233,"rx":62,"fill":63,"stroke":64,"style":65},"272",[67,235,228],{"x":69,"y":70,"fill":64,"style":71},[44,237],{"x":69,"y":82,"width":238,"height":239,"rx":48,"fill":64,"stroke":64,"style":240},"210.0","30.0","fill-opacity:0.06;stroke-opacity:0.4",[67,242,247],{"x":243,"y":244,"fill":64,"style":245,"textAnchor":246},"38.0","75.5","font-size:12.5px;font-weight:700","start","Aspect",[44,249],{"x":250,"y":82,"width":251,"height":239,"rx":48,"fill":64,"stroke":64,"style":240},"238.0","247.0",[67,253,256],{"x":254,"y":244,"fill":64,"style":245,"textAnchor":255},"361.5","middle","Variable font",[44,258],{"x":259,"y":82,"width":251,"height":239,"rx":48,"fill":64,"stroke":64,"style":240},"485.0",[67,261,263],{"x":262,"y":244,"fill":64,"style":245,"textAnchor":255},"608.5","Static weights",[44,265],{"x":69,"y":266,"width":238,"height":239,"rx":48,"fill":63,"stroke":64,"style":267},"86.0","stroke-opacity:0.35",[67,269,271],{"x":243,"y":270,"fill":64,"style":245,"textAnchor":246},"105.5","Bytes for 1-2 weights",[44,273],{"x":250,"y":266,"width":251,"height":239,"rx":48,"fill":125,"stroke":126,"style":274},"fill-opacity:0.24;stroke-opacity:0.9",[67,276,278],{"x":254,"y":270,"fill":64,"style":277,"textAnchor":255},"font-size:12px","larger",[44,280],{"x":259,"y":266,"width":251,"height":239,"rx":48,"fill":86,"stroke":86,"style":281},"fill-opacity:0.14;stroke-opacity:0.9",[67,283,284],{"x":262,"y":270,"fill":64,"style":277,"textAnchor":255},"smaller",[44,286],{"x":69,"y":287,"width":238,"height":239,"rx":48,"fill":63,"stroke":64,"style":267},"116.0",[67,289,291],{"x":243,"y":290,"fill":64,"style":245,"textAnchor":246},"135.5","Bytes for 4+ weights",[44,293],{"x":250,"y":287,"width":251,"height":239,"rx":48,"fill":86,"stroke":86,"style":281},[67,295,284],{"x":254,"y":290,"fill":64,"style":277,"textAnchor":255},[44,297],{"x":259,"y":287,"width":251,"height":239,"rx":48,"fill":125,"stroke":126,"style":274},[67,299,278],{"x":262,"y":290,"fill":64,"style":277,"textAnchor":255},[44,301],{"x":69,"y":302,"width":238,"height":239,"rx":48,"fill":63,"stroke":64,"style":267},"146.0",[67,304,306],{"x":243,"y":305,"fill":64,"style":245,"textAnchor":246},"165.5","Requests",[44,308],{"x":250,"y":302,"width":251,"height":239,"rx":48,"fill":86,"stroke":86,"style":281},[67,310,311],{"x":254,"y":305,"fill":64,"style":277,"textAnchor":255},"one per style",[44,313],{"x":259,"y":302,"width":251,"height":239,"rx":48,"fill":64,"stroke":64,"style":240},[67,315,316],{"x":262,"y":305,"fill":64,"style":277,"textAnchor":255},"one per weight",[44,318],{"x":69,"y":319,"width":238,"height":239,"rx":48,"fill":63,"stroke":64,"style":267},"176.0",[67,321,323],{"x":243,"y":322,"fill":64,"style":245,"textAnchor":246},"195.5","Swap behaviour",[44,325],{"x":250,"y":319,"width":251,"height":239,"rx":48,"fill":86,"stroke":86,"style":281},[67,327,328],{"x":254,"y":322,"fill":64,"style":277,"textAnchor":255},"all text at once",[44,330],{"x":259,"y":319,"width":251,"height":239,"rx":48,"fill":125,"stroke":126,"style":274},[67,332,333],{"x":262,"y":322,"fill":64,"style":277,"textAnchor":255},"staggered per weight",[44,335],{"x":69,"y":336,"width":238,"height":337,"rx":48,"fill":63,"stroke":64,"style":267},"206.0","46.0",[67,339,341],{"x":243,"y":340,"fill":64,"style":245,"textAnchor":246},"225.5","Intermediate weights and",[67,343,345],{"x":243,"y":344,"fill":64,"style":245,"textAnchor":246},"241.5","animation",[44,347],{"x":250,"y":336,"width":251,"height":337,"rx":48,"fill":86,"stroke":86,"style":281},[67,349,351],{"x":254,"y":350,"fill":64,"style":277,"textAnchor":255},"233.5","any value",[44,353],{"x":259,"y":336,"width":251,"height":337,"rx":48,"fill":125,"stroke":126,"style":274},[67,355,356],{"x":262,"y":350,"fill":64,"style":277,"textAnchor":255},"fixed steps",[151,358,360],{"id":359},"step-by-step-making-the-choice","Step-by-Step: Making the Choice",[362,363,365],"h3",{"id":364},"_1-measure-the-weights-in-use","1. Measure the weights in use",[367,368,373],"pre",{"className":369,"code":370,"language":371,"meta":372,"style":372},"language-javascript shiki shiki-themes github-light-high-contrast github-dark-high-contrast github-light-high-contrast","\u002F\u002F Run in the console on representative pages: which weights are rendered?\nconst used = new Set();\nfor (const el of document.querySelectorAll('body *')) {\n  if (!el.childNodes.length || ![...el.childNodes].some((n) => n.nodeType === 3 && n.textContent.trim())) continue;\n  const cs = getComputedStyle(el);\n  used.add(`${cs.fontFamily.split(',')[0]} ${cs.fontWeight} ${cs.fontStyle}`);\n}\nconsole.table([...used]);\n\u002F\u002F trade-off: this inspects one page in one state. Run it on each template and\n\u002F\u002F after opening menus and modals, or rarely shown weights will be missed.\n","javascript","",[167,374,375,384,409,442,517,534,600,606,623,629],{"__ignoreMap":372},[376,377,380],"span",{"class":378,"line":379},"line",1,[376,381,383],{"class":382},"sjfSM","\u002F\u002F Run in the console on representative pages: which weights are rendered?\n",[376,385,387,391,395,398,401,405],{"class":378,"line":386},2,[376,388,390],{"class":389},"sPARh","const",[376,392,394],{"class":393},"sPXB4"," used",[376,396,397],{"class":389}," =",[376,399,400],{"class":389}," new",[376,402,404],{"class":403},"smZ65"," Set",[376,406,408],{"class":407},"saISM","();\n",[376,410,412,415,418,420,423,426,429,432,435,439],{"class":378,"line":411},3,[376,413,414],{"class":389},"for",[376,416,417],{"class":407}," (",[376,419,390],{"class":389},[376,421,422],{"class":393}," el",[376,424,425],{"class":389}," of",[376,427,428],{"class":407}," document.",[376,430,431],{"class":403},"querySelectorAll",[376,433,434],{"class":407},"(",[376,436,438],{"class":437},"sZ8jY","'body *'",[376,440,441],{"class":407},")) {\n",[376,443,445,448,450,453,456,459,462,465,468,471,474,477,480,484,487,490,493,496,499,502,505,508,511,514],{"class":378,"line":444},4,[376,446,447],{"class":389},"  if",[376,449,417],{"class":407},[376,451,452],{"class":389},"!",[376,454,455],{"class":407},"el.childNodes.",[376,457,458],{"class":393},"length",[376,460,461],{"class":389}," ||",[376,463,464],{"class":389}," !",[376,466,467],{"class":407},"[",[376,469,470],{"class":389},"...",[376,472,473],{"class":407},"el.childNodes].",[376,475,476],{"class":403},"some",[376,478,479],{"class":407},"((",[376,481,483],{"class":482},"sQw3B","n",[376,485,486],{"class":407},") ",[376,488,489],{"class":389},"=>",[376,491,492],{"class":407}," n.nodeType ",[376,494,495],{"class":389},"===",[376,497,498],{"class":393}," 3",[376,500,501],{"class":389}," &&",[376,503,504],{"class":407}," n.textContent.",[376,506,507],{"class":403},"trim",[376,509,510],{"class":407},"())) ",[376,512,513],{"class":389},"continue",[376,515,516],{"class":407},";\n",[376,518,520,523,526,528,531],{"class":378,"line":519},5,[376,521,522],{"class":389},"  const",[376,524,525],{"class":393}," cs",[376,527,397],{"class":389},[376,529,530],{"class":403}," getComputedStyle",[376,532,533],{"class":407},"(el);\n",[376,535,537,540,543,545,548,551,554,557,559,562,564,567,570,572,575,578,580,582,585,587,589,591,594,597],{"class":378,"line":536},6,[376,538,539],{"class":407},"  used.",[376,541,542],{"class":403},"add",[376,544,434],{"class":407},[376,546,547],{"class":437},"`${",[376,549,550],{"class":407},"cs",[376,552,553],{"class":437},".",[376,555,556],{"class":407},"fontFamily",[376,558,553],{"class":437},[376,560,561],{"class":403},"split",[376,563,434],{"class":437},[376,565,566],{"class":437},"','",[376,568,569],{"class":437},")[",[376,571,48],{"class":393},[376,573,574],{"class":437},"]",[376,576,577],{"class":437},"} ${",[376,579,550],{"class":407},[376,581,553],{"class":437},[376,583,584],{"class":407},"fontWeight",[376,586,577],{"class":437},[376,588,550],{"class":407},[376,590,553],{"class":437},[376,592,593],{"class":407},"fontStyle",[376,595,596],{"class":437},"}`",[376,598,599],{"class":407},");\n",[376,601,603],{"class":378,"line":602},7,[376,604,605],{"class":407},"}\n",[376,607,609,612,615,618,620],{"class":378,"line":608},8,[376,610,611],{"class":407},"console.",[376,613,614],{"class":403},"table",[376,616,617],{"class":407},"([",[376,619,470],{"class":389},[376,621,622],{"class":407},"used]);\n",[376,624,626],{"class":378,"line":625},9,[376,627,628],{"class":382},"\u002F\u002F trade-off: this inspects one page in one state. Run it on each template and\n",[376,630,632],{"class":378,"line":631},10,[376,633,634],{"class":382},"\u002F\u002F after opening menus and modals, or rarely shown weights will be missed.\n",[15,636,637],{},"Expected outcome: an accurate list such as \"Inter 400 normal, Inter 700 normal, Inter 400 italic\".",[362,639,641],{"id":640},"_2-compare-subset-file-sizes-for-both-options","2. Compare subset file sizes for both options",[15,643,644],{},"Subset both the variable font and the static weights you need to the same character set, then compare totals. If you only need a narrower weight range, restrict the variable font's axis to shrink it.",[367,646,650],{"className":647,"code":648,"language":649,"meta":372,"style":372},"language-bash shiki shiki-themes github-light-high-contrast github-dark-high-contrast github-light-high-contrast","# Restrict a variable font's weight axis to 400-700, then subset to Latin.\nfonttools varLib.instancer Inter-Variable.ttf wght=400:700 -o inter-400-700.ttf\npyftsubset inter-400-700.ttf --unicodes=\"U+0000-00FF,U+2000-206F\" --flavor=woff2 \\\n  --output-file=inter-400-700-latin.woff2\n# trade-off: restricting the axis removes weights outside the range; any CSS\n# asking for 800 will be clamped to 700. Keep the range aligned with the design tokens.\n","bash",[167,651,652,657,677,697,702,707],{"__ignoreMap":372},[376,653,654],{"class":378,"line":379},[376,655,656],{"class":382},"# Restrict a variable font's weight axis to 400-700, then subset to Latin.\n",[376,658,659,662,665,668,671,674],{"class":378,"line":386},[376,660,661],{"class":482},"fonttools",[376,663,664],{"class":437}," varLib.instancer",[376,666,667],{"class":437}," Inter-Variable.ttf",[376,669,670],{"class":437}," wght=400:700",[376,672,673],{"class":393}," -o",[376,675,676],{"class":437}," inter-400-700.ttf\n",[376,678,679,682,685,688,691,694],{"class":378,"line":411},[376,680,681],{"class":482},"pyftsubset",[376,683,684],{"class":437}," inter-400-700.ttf",[376,686,687],{"class":393}," --unicodes=",[376,689,690],{"class":437},"\"U+0000-00FF,U+2000-206F\"",[376,692,693],{"class":393}," --flavor=woff2",[376,695,696],{"class":389}," \\\n",[376,698,699],{"class":378,"line":444},[376,700,701],{"class":393},"  --output-file=inter-400-700-latin.woff2\n",[376,703,704],{"class":378,"line":519},[376,705,706],{"class":382},"# trade-off: restricting the axis removes weights outside the range; any CSS\n",[376,708,709],{"class":378,"line":536},[376,710,711],{"class":382},"# asking for 800 will be clamped to 700. Keep the range aligned with the design tokens.\n",[15,713,714],{},"Expected outcome: real byte totals for both options at your character set.",[362,716,718],{"id":717},"_3-optimise-for-the-lcp-text-not-the-whole-page","3. Optimise for the LCP text, not the whole page",[15,720,721],{},"If static, preload only the weight the LCP heading uses and let the others load normally. If variable, preload the single file. Compare the bytes that must arrive before the LCP paint in each setup.",[15,723,724],{},"Expected outcome: a decision based on the critical-path bytes, not total bytes.",[362,726,728],{"id":727},"_4-declare-faces-precisely","4. Declare faces precisely",[367,730,734],{"className":731,"code":732,"language":733,"meta":372,"style":372},"language-css shiki shiki-themes github-light-high-contrast github-dark-high-contrast github-light-high-contrast","\u002F* Variable: one face covering the range. *\u002F\n@font-face { font-family: \"Inter\"; src: url(\"\u002Ffonts\u002Finter-400-700-latin.woff2\") format(\"woff2\");\n  font-weight: 400 700; font-display: swap; }\n\u002F* Static: one face per weight actually used. *\u002F\n@font-face { font-family: \"Inter\"; src: url(\"\u002Ffonts\u002Finter-700-latin.woff2\") format(\"woff2\");\n  font-weight: 700; font-display: swap; }\n\u002F* trade-off: declaring a variable face with a weight range that does not match\n   the file's axis leads to faux bolding outside the range. Keep font-weight\n   in @font-face equal to the file's real axis range. *\u002F\n","css",[167,735,736,741,786,812,817,852,871,876,881],{"__ignoreMap":372},[376,737,738],{"class":378,"line":379},[376,739,740],{"class":382},"\u002F* Variable: one face covering the range. *\u002F\n",[376,742,743,746,749,752,755,758,761,764,766,769,771,774,776,779,781,784],{"class":378,"line":386},[376,744,745],{"class":389},"@font-face",[376,747,748],{"class":407}," { ",[376,750,751],{"class":393},"font-family",[376,753,754],{"class":407},": ",[376,756,757],{"class":437},"\"Inter\"",[376,759,760],{"class":407},"; ",[376,762,763],{"class":393},"src",[376,765,754],{"class":407},[376,767,768],{"class":393},"url",[376,770,434],{"class":407},[376,772,773],{"class":437},"\"\u002Ffonts\u002Finter-400-700-latin.woff2\"",[376,775,486],{"class":407},[376,777,778],{"class":393},"format",[376,780,434],{"class":407},[376,782,783],{"class":437},"\"woff2\"",[376,785,599],{"class":407},[376,787,788,791,793,796,799,801,804,806,809],{"class":378,"line":411},[376,789,790],{"class":393},"  font-weight",[376,792,754],{"class":407},[376,794,795],{"class":393},"400",[376,797,798],{"class":393}," 700",[376,800,760],{"class":407},[376,802,803],{"class":393},"font-display",[376,805,754],{"class":407},[376,807,808],{"class":393},"swap",[376,810,811],{"class":407},"; }\n",[376,813,814],{"class":378,"line":444},[376,815,816],{"class":382},"\u002F* Static: one face per weight actually used. *\u002F\n",[376,818,819,821,823,825,827,829,831,833,835,837,839,842,844,846,848,850],{"class":378,"line":519},[376,820,745],{"class":389},[376,822,748],{"class":407},[376,824,751],{"class":393},[376,826,754],{"class":407},[376,828,757],{"class":437},[376,830,760],{"class":407},[376,832,763],{"class":393},[376,834,754],{"class":407},[376,836,768],{"class":393},[376,838,434],{"class":407},[376,840,841],{"class":437},"\"\u002Ffonts\u002Finter-700-latin.woff2\"",[376,843,486],{"class":407},[376,845,778],{"class":393},[376,847,434],{"class":407},[376,849,783],{"class":437},[376,851,599],{"class":407},[376,853,854,856,858,861,863,865,867,869],{"class":378,"line":536},[376,855,790],{"class":393},[376,857,754],{"class":407},[376,859,860],{"class":393},"700",[376,862,760],{"class":407},[376,864,803],{"class":393},[376,866,754],{"class":407},[376,868,808],{"class":393},[376,870,811],{"class":407},[376,872,873],{"class":378,"line":602},[376,874,875],{"class":382},"\u002F* trade-off: declaring a variable face with a weight range that does not match\n",[376,877,878],{"class":378,"line":608},[376,879,880],{"class":382},"   the file's axis leads to faux bolding outside the range. Keep font-weight\n",[376,882,883],{"class":378,"line":625},[376,884,885],{"class":382},"   in @font-face equal to the file's real axis range. *\u002F\n",[15,887,888],{},"Expected outcome: no synthetic styles and no unused files.",[15,890,891],{},[35,892,42,895,42,898,42,901,42,903,42,920,42,923,42,925,42,930,42,936,42,939,42,943,42,951,42,957,42,961,42,966,42,969,42,972,42,974,42,976,42,979,42,982,42,985,42,988,42,991,42,995,42,997,42,1000,42,1003,42,1006,42,1010,42,1013,42,1016,42],{"viewBox":893,"width":38,"role":39,"ariaLabel":894,"style":41},"0 0 760 325","Decision sequence for choosing between a variable font and static font weights based on the weights in use and design needs.",[44,896],{"className":897,"x":48,"y":48,"width":38,"height":38,"fill":49},[47],[51,899,900],{},"Variable or static?",[55,902,894],{},[904,905,906],"defs",{},[907,908,915],"marker",{"id":909,"viewBox":910,"refX":911,"refY":912,"markerWidth":913,"markerHeight":913,"orient":914},"fa36246651","0 0 10 10","9","5","7","auto-start-reverse",[916,917],"path",{"d":918,"fill":64,"style":919},"M0 0 L10 5 L0 10 z","fill-opacity:0.7",[44,921],{"x":59,"y":59,"width":60,"height":922,"rx":62,"fill":63,"stroke":64,"style":65},"323",[67,924,900],{"x":69,"y":70,"fill":64,"style":71},[44,926],{"x":69,"y":82,"width":927,"height":928,"rx":929,"fill":64,"stroke":64,"style":240},"320.0","35.0","6",[67,931,935],{"x":932,"y":933,"fill":64,"style":934,"textAnchor":255},"188.0","78.0","font-size:13px;font-weight:700","Using three or more weights of one style?",[44,937],{"x":938,"y":82,"width":927,"height":928,"rx":929,"fill":86,"stroke":86,"style":281},"412.0",[67,940,942],{"x":941,"y":933,"fill":64,"style":148,"textAnchor":255},"572.0","Variable font, axis restricted to the range used",[378,944],{"x1":945,"y1":946,"x2":947,"y2":946,"stroke":64,"strokeWidth":948,"style":949,"markerEnd":950},"348.0","73.5","410.0","1.5","stroke-opacity:0.6","url(#fa36246651)",[67,952,956],{"x":953,"y":954,"fill":86,"style":955,"textAnchor":255},"380.0","66.5","font-size:11.5px;font-weight:700","yes",[378,958],{"x1":932,"y1":959,"x2":932,"y2":960,"stroke":64,"strokeWidth":948,"style":949,"markerEnd":950},"91.0","125.0",[67,962,965],{"x":963,"y":964,"fill":147,"style":955},"196.0","113.0","no",[44,967],{"x":69,"y":968,"width":927,"height":928,"rx":929,"fill":64,"stroke":64,"style":240},"127.0",[67,970,971],{"x":932,"y":123,"fill":64,"style":934,"textAnchor":255},"Animating or fine-tuning weight?",[44,973],{"x":938,"y":968,"width":927,"height":928,"rx":929,"fill":86,"stroke":86,"style":281},[67,975,256],{"x":941,"y":123,"fill":64,"style":148,"textAnchor":255},[378,977],{"x1":945,"y1":978,"x2":947,"y2":978,"stroke":64,"strokeWidth":948,"style":949,"markerEnd":950},"144.5",[67,980,956],{"x":953,"y":981,"fill":86,"style":955,"textAnchor":255},"137.5",[378,983],{"x1":932,"y1":984,"x2":932,"y2":963,"stroke":64,"strokeWidth":948,"style":949,"markerEnd":950},"162.0",[67,986,965],{"x":963,"y":987,"fill":147,"style":955},"184.0",[44,989],{"x":69,"y":990,"width":927,"height":928,"rx":929,"fill":64,"stroke":64,"style":240},"198.0",[67,992,994],{"x":932,"y":993,"fill":64,"style":934,"textAnchor":255},"220.0","LCP text uses one weight, rest below the fold?",[44,996],{"x":938,"y":990,"width":927,"height":928,"rx":929,"fill":86,"stroke":86,"style":281},[67,998,999],{"x":941,"y":993,"fill":64,"style":148,"textAnchor":255},"Static weights, preload only the LCP weight",[378,1001],{"x1":945,"y1":1002,"x2":947,"y2":1002,"stroke":64,"strokeWidth":948,"style":949,"markerEnd":950},"215.5",[67,1004,956],{"x":953,"y":1005,"fill":86,"style":955,"textAnchor":255},"208.5",[378,1007],{"x1":932,"y1":1008,"x2":932,"y2":1009,"stroke":64,"strokeWidth":948,"style":949,"markerEnd":950},"233.0","267.0",[67,1011,965],{"x":963,"y":1012,"fill":147,"style":955},"255.0",[44,1014],{"x":69,"y":1015,"width":927,"height":70,"rx":929,"fill":125,"stroke":126,"style":274},"269.0",[67,1017,1019],{"x":932,"y":1018,"fill":64,"style":148,"textAnchor":255},"290.5","Static weights for one or two weights",[151,1021,1023],{"id":1022},"verification","Verification",[15,1025,1026,1027,1030],{},"Measure text LCP and total font bytes on representative templates for both setups under the same throttling. Watch the filmstrip for staggered swaps with static weights. Prefer the option with fewer critical-path bytes unless the visual churn of staggered swaps is noticeable — in which case the variable font's single swap may be worth a slightly later paint. Confirm no ",[167,1028,1029],{},"font-synthesis"," is occurring by checking glyph shapes in bold and italic text.",[151,1032,1034],{"id":1033},"italics-optical-sizes-and-width-axes","Italics, Optical Sizes and Width Axes",[15,1036,1037,1038,1041],{},"Italics are usually a separate file in both approaches — most variable fonts ship roman and italic as two files — so using any italic text doubles the comparison. Fonts with an optical-size axis (",[167,1039,1040],{},"opsz",") adjust letterforms for small and large text automatically, which can improve readability, but the axis adds bytes; if you only ever use text at body and heading sizes, a static cut per size may be smaller. Width axes are valuable for responsive typography but rarely used in practice. As a rule, every axis you keep should correspond to a design decision someone actually made; instancing away unused axes is free performance.",[151,1043,1045],{"id":1044},"common-mistakes-with-variable-fonts","Common Mistakes with Variable Fonts",[156,1047,1048,1054,1067,1073],{},[159,1049,1050,1053],{},[162,1051,1052],{},"Shipping the full axis range."," A 100–900 weight axis when the design uses 400–700 carries outline deltas you never render. Instance the axis down.",[159,1055,1056,1063,1064,553],{},[162,1057,1058,1059,1062],{},"Declaring ",[167,1060,1061],{},"font-weight: 400"," on a variable face."," The face then only matches weight 400; bold text falls back to synthetic bolding. Declare the range, for example ",[167,1065,1066],{},"font-weight: 100 900",[159,1068,1069,1072],{},[162,1070,1071],{},"Forgetting the italic file."," Many variable families ship italics separately; omitting them yields synthetic obliques that look wrong and can change text width.",[159,1074,1075,1078],{},[162,1076,1077],{},"Comparing unsubsetted files."," Vendor download sizes include every script. Compare after subsetting to your character set, where the balance often shifts.",[151,1080,1082],{"id":1081},"faq","FAQ",[1084,1085,1088,1092],"details",{"className":1086},[1087],"faq-item",[1089,1090,1091],"summary",{},"Do variable fonts render more slowly?",[15,1093,1094,1095,1097],{},"Interpolating outlines costs a little more than drawing a static instance, but engines cache rasterised glyphs, and the difference is not measurable in INP or paint timings for normal text. Animating ",[167,1096,169],{}," continuously does force repeated layout and glyph rasterisation, which is a different and more expensive pattern.",[1084,1099,1101,1104],{"className":1100},[1087],[1089,1102,1103],{},"Does a variable font help CLS?",[15,1105,1106,1107,1110,1111,553],{},"Indirectly: one swap instead of several means fewer reflows of text, and if you use metric-matched fallbacks the single swap is easier to tune. It does not remove the need for ",[167,1108,1109],{},"size-adjust"," and related overrides, covered in ",[19,1112,1114],{"href":1113},"\u002Fcore-web-vitals-measurement\u002Ffont-loading-and-text-rendering-performance\u002Ffixing-cls-from-web-font-swap\u002F","fixing CLS from web font swap",[1084,1116,1118,1121],{"className":1117},[1087],[1089,1119,1120],{},"What about system font stacks instead of either?",[15,1122,1123],{},"System fonts cost zero bytes and never swap, making them the fastest option by definition. Many design systems use them for body text and a single web font weight for headings — a hybrid that captures most of the brand value at a fraction of the cost.",[1084,1125,1127,1130],{"className":1126},[1087],[1089,1128,1129],{},"Is the break-even point the same for every font?",[15,1131,1132],{},"No. It depends on how much outline data the variable masters need relative to a single static instance, which varies by typeface design and character set. Geometric sans-serifs with simple outlines often have small variable overheads; detailed serifs and display faces with many masters can be much larger. Always compare real subset files for your typeface rather than relying on a general rule.",[151,1134,1136],{"id":1135},"related","Related",[156,1138,1139,1146,1153],{},[159,1140,1141,1145],{},[19,1142,1144],{"href":1143},"\u002Fcore-web-vitals-measurement\u002Ffont-loading-and-text-rendering-performance\u002Fsubsetting-web-fonts-with-unicode-range\u002F","Subsetting web fonts with unicode-range"," — shrinking whichever files you choose.",[159,1147,1148,1152],{},[19,1149,1151],{"href":1150},"\u002Fcore-web-vitals-measurement\u002Ffont-loading-and-text-rendering-performance\u002Fself-hosting-google-fonts\u002F","Self-hosting Google Fonts"," — hosting variable fonts from your own origin.",[159,1154,1155,1159],{},[19,1156,1158],{"href":1157},"\u002Fcore-web-vitals-measurement\u002Ffont-loading-and-text-rendering-performance\u002Ffont-display-swap-vs-optional-for-lcp\u002F","Font-display swap vs optional for LCP"," — how the chosen file interacts with rendering.",[1161,1162,1164],"script",{"type":1163},"application\u002Fld+json","\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"HowTo\",\n  \"name\": \"Variable Fonts vs Static Font Weights: Which Loads Faster?\",\n  \"description\": \"When a single variable font file beats multiple static weights for loading performance, and when it does not.\",\n  \"step\": [\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 1,\n      \"name\": \"Measure the weights in use\",\n      \"text\": \"Expected outcome: an accurate list such as \\\"Inter 400 normal, Inter 700 normal, Inter 400 italic\\\".\"\n    },\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 2,\n      \"name\": \"Compare subset file sizes for both options\",\n      \"text\": \"Subset both the variable font and the static weights you need to the same character set, then compare totals.\"\n    },\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 3,\n      \"name\": \"Optimise for the LCP text, not the whole page\",\n      \"text\": \"If static, preload only the weight the LCP heading uses and let the others load normally.\"\n    },\n    {\n      \"@type\": \"HowToStep\",\n      \"position\": 4,\n      \"name\": \"Declare faces precisely\",\n      \"text\": \"Expected outcome: no synthetic styles and no unused files.\"\n    }\n  ]\n}\n",[1161,1166,1167],{"type":1163},"\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"TechArticle\",\n  \"headline\": \"Variable Fonts vs Static Font Weights: Which Loads Faster?\",\n  \"description\": \"When a single variable font file beats multiple static weights for loading performance, and when it does not.\",\n  \"datePublished\": \"2026-10-06\",\n  \"dateModified\": \"2026-10-06\",\n  \"author\": {\n    \"@type\": \"Organization\",\n    \"name\": \"frontend-performance.com\"\n  },\n  \"publisher\": {\n    \"@type\": \"Organization\",\n    \"name\": \"frontend-performance.com\"\n  },\n  \"mainEntityOfPage\": {\n    \"@type\": \"WebPage\",\n    \"@id\": \"https:\u002F\u002Ffrontend-performance.com\u002Fcore-web-vitals-measurement\u002Ffont-loading-and-text-rendering-performance\u002Fvariable-fonts-vs-static-font-weights\u002F\"\n  }\n}\n",[1161,1169,1170],{"type":1163},"\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"BreadcrumbList\",\n  \"itemListElement\": [\n    {\n      \"@type\": \"ListItem\",\n      \"position\": 1,\n      \"name\": \"Home\",\n      \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002F\"\n    },\n    {\n      \"@type\": \"ListItem\",\n      \"position\": 2,\n      \"name\": \"Core Web Vitals & Measurement\",\n      \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fcore-web-vitals-measurement\u002F\"\n    },\n    {\n      \"@type\": \"ListItem\",\n      \"position\": 3,\n      \"name\": \"Font Loading & Text Rendering Performance\",\n      \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fcore-web-vitals-measurement\u002Ffont-loading-and-text-rendering-performance\u002F\"\n    },\n    {\n      \"@type\": \"ListItem\",\n      \"position\": 4,\n      \"name\": \"Variable Fonts vs Static Font Weights\",\n      \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fcore-web-vitals-measurement\u002Ffont-loading-and-text-rendering-performance\u002Fvariable-fonts-vs-static-font-weights\u002F\"\n    }\n  ]\n}\n",[1172,1173,1174],"style",{},"html pre.shiki code .sjfSM, html code.shiki .sjfSM{--shiki-default:#66707B;--shiki-dark:#BDC4CC;--shiki-light:#66707B}html pre.shiki code .sPARh, html code.shiki .sPARh{--shiki-default:#A0111F;--shiki-dark:#FF9492;--shiki-light:#A0111F}html pre.shiki code .sPXB4, html code.shiki .sPXB4{--shiki-default:#023B95;--shiki-dark:#91CBFF;--shiki-light:#023B95}html pre.shiki code .smZ65, html code.shiki .smZ65{--shiki-default:#622CBC;--shiki-dark:#DBB7FF;--shiki-light:#622CBC}html pre.shiki code .saISM, html code.shiki .saISM{--shiki-default:#0E1116;--shiki-dark:#F0F3F6;--shiki-light:#0E1116}html pre.shiki code .sZ8jY, html code.shiki .sZ8jY{--shiki-default:#032563;--shiki-dark:#ADDCFF;--shiki-light:#032563}html pre.shiki code .sQw3B, html code.shiki .sQw3B{--shiki-default:#702C00;--shiki-dark:#FFB757;--shiki-light:#702C00}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}",{"title":372,"searchDepth":386,"depth":386,"links":1176},[1177,1178,1179,1185,1186,1187,1188,1189],{"id":153,"depth":386,"text":154},{"id":191,"depth":386,"text":192},{"id":359,"depth":386,"text":360,"children":1180},[1181,1182,1183,1184],{"id":364,"depth":411,"text":365},{"id":640,"depth":411,"text":641},{"id":717,"depth":411,"text":718},{"id":727,"depth":411,"text":728},{"id":1022,"depth":386,"text":1023},{"id":1033,"depth":386,"text":1034},{"id":1044,"depth":386,"text":1045},{"id":1081,"depth":386,"text":1082},{"id":1135,"depth":386,"text":1136},"When a single variable font file beats multiple static weights for loading performance, and when it does not.","md",{"slug":1193,"type":1194,"breadcrumb":1195,"datePublished":1203,"dateModified":1203},"variable-fonts-vs-static-font-weights","article",[1196,1199,1200,1201],{"name":1197,"url":1198},"Home","\u002F",{"name":27,"url":26},{"name":22,"url":21},{"name":5,"url":1202},"\u002Fcore-web-vitals-measurement\u002Ffont-loading-and-text-rendering-performance\u002Fvariable-fonts-vs-static-font-weights\u002F","2026-10-06",true,"\u002Fcore-web-vitals-measurement\u002Ffont-loading-and-text-rendering-performance\u002Fvariable-fonts-vs-static-font-weights",{"title":1207,"description":1208},"Variable Fonts vs Static Font Weights for Performance","One variable font or several static weights? Compare bytes, requests, rendering cost and LCP impact, with a break-even rule for how many weights you use.","core-web-vitals-measurement\u002Ffont-loading-and-text-rendering-performance\u002Fvariable-fonts-vs-static-font-weights\u002Findex","iHIvTvybyWJyPZoRIJsu74w7n2mWvgFayyK8yoU-Tak",[1212,1216],{"title":1213,"path":1214,"stem":1215},"Subsetting Web Fonts with unicode-range","\u002Fcore-web-vitals-measurement\u002Ffont-loading-and-text-rendering-performance\u002Fsubsetting-web-fonts-with-unicode-range","core-web-vitals-measurement\u002Ffont-loading-and-text-rendering-performance\u002Fsubsetting-web-fonts-with-unicode-range\u002Findex",{"title":1217,"path":1218,"stem":1219},"Long Animation Frames (LoAF) API","\u002Fcore-web-vitals-measurement\u002Flong-animation-frames-api","core-web-vitals-measurement\u002Flong-animation-frames-api\u002Findex",1791308073878]