[{"data":1,"prerenderedAt":1204},["ShallowReactive",2],{"content:\u002Fcore-web-vitals-measurement\u002Ffont-loading-and-text-rendering-performance\u002Ffont-display-swap-vs-optional-for-lcp":3,"surroundings:\u002Fcore-web-vitals-measurement\u002Ffont-loading-and-text-rendering-performance\u002Ffont-display-swap-vs-optional-for-lcp":1195},{"id":4,"title":5,"body":6,"description":1174,"extension":1175,"meta":1176,"navigation":1188,"path":1189,"seo":1190,"stem":1193,"__hash__":1194},"content\u002Fcore-web-vitals-measurement\u002Ffont-loading-and-text-rendering-performance\u002Ffont-display-swap-vs-optional-for-lcp\u002Findex.md","font-display: swap vs optional for LCP",{"type":7,"value":8,"toc":1165},"minimark",[9,14,49,54,94,98,200,331,335,347,361,370,384,388,397,614,621,630,705,708,717,787,790,799,803,810,813,1009,1029,1033,1048,1069,1083,1092,1107,1122,1126,1150,1155,1158,1161],[10,11,13],"h1",{"id":12},"font-display-swap-vs-optional-which-one-should-your-fonts-use","font-display: swap vs optional — Which One Should Your Fonts Use?",[15,16,17,18,23,24,28,29,33,34,38,39,43,44,48],"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 the ",[19,25,27],{"href":26},"\u002Fcore-web-vitals-measurement\u002F","Core Web Vitals & Measurement"," area. Both values solve the invisible-text problem that the default ",[30,31,32],"code",{},"block"," behaviour creates, and both let text paint almost immediately — so neither is a meaningful lever on ",[19,35,37],{"href":36},"\u002Fcore-web-vitals-measurement\u002Fmeasuring-lcp-with-chrome-devtools\u002F","LCP"," once you have moved off the default. What separates them is what happens ",[40,41,42],"em",{},"after"," the first paint, and that is a decision about ",[19,45,47],{"href":46},"\u002Fcore-web-vitals-measurement\u002Freducing-cumulative-layout-shift-cls\u002F","CLS"," and brand fidelity.",[50,51,53],"h2",{"id":52},"rapid-diagnosis-which-question-are-you-actually-answering","Rapid Diagnosis: Which Question Are You Actually Answering?",[55,56,57,69,78,88],"ul",{},[58,59,60,68],"li",{},[61,62,63,64,67],"strong",{},"Is your text LCP still slow with ",[30,65,66],{},"swap"," in place?"," Then the display value is not your problem — look at discovery and transfer, not display.",[58,70,71,77],{},[61,72,73,74,76],{},"Did CLS rise when you adopted ",[30,75,66],{},"?"," You are choosing between matching the fallback's metrics or refusing the late swap altogether.",[58,79,80,83,84,87],{},[61,81,82],{},"How often does the font arrive within ~100ms on a cold cache?"," Check the field distribution of font response times. If it is rarely, ",[30,85,86],{},"optional"," means most first-time visitors never see your typeface.",[58,89,90,93],{},[61,91,92],{},"Would a reader notice the fallback?"," A display face with distinctive letterforms is worth protecting; a neutral UI sans that differs from Arial by 3% is not.",[50,95,97],{"id":96},"the-comparison","The Comparison",[99,100,101,119],"table",{},[102,103,104],"thead",{},[105,106,107,111,115],"tr",{},[108,109,110],"th",{},"Axis",[108,112,113],{},[30,114,66],{},[108,116,117],{},[30,118,86],{},[120,121,122,134,145,156,167,178,189],"tbody",{},[105,123,124,128,131],{},[125,126,127],"td",{},"Block period",[125,129,130],{},"~0ms — text paints immediately",[125,132,133],{},"~100ms",[105,135,136,139,142],{},[125,137,138],{},"Late font behaviour",[125,140,141],{},"Swapped in whenever it arrives",[125,143,144],{},"Ignored for this page view",[105,146,147,150,153],{},[125,148,149],{},"Layout shift risk",[125,151,152],{},"High without metric overrides",[125,154,155],{},"None after first paint",[105,157,158,161,164],{},[125,159,160],{},"Brand fidelity, cold cache",[125,162,163],{},"Always eventually correct",[125,165,166],{},"Often falls back entirely",[105,168,169,172,175],{},[125,170,171],{},"Brand fidelity, warm cache",[125,173,174],{},"Correct",[125,176,177],{},"Correct (font is already cached)",[105,179,180,183,186],{},[125,181,182],{},"Works well with preload",[125,184,185],{},"Optional",[125,187,188],{},"Effectively required",[105,190,191,194,197],{},[125,192,193],{},"Best for",[125,195,196],{},"Body copy and headings with tuned fallbacks",[125,198,199],{},"Decorative or secondary faces",[201,202,209,210,217,218,217,222,217,226,217,235,217,242,217,246,217,254,217,261,217,266,217,270,217,277,217,282,217,287,217,291,217,296,217,301,217,304,217,309,217,314,217,318,217,322,217,326,217],"svg",{"xmlns":203,"viewBox":204,"width":205,"role":206,"ariaLabel":207,"style":208},"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","0 0 760 264","100%","img","Two timelines: swap paints the fallback then swaps the font in at 1.4 seconds causing a shift, while optional paints the fallback and keeps it because the font missed the 100 millisecond window","height:auto;max-width:760px;display:block;margin:1.75rem auto;font-family:inherit;color:var(--fp-svg-ink)","\n  ",[211,212],"rect",{"className":213,"x":215,"y":215,"width":205,"height":205,"fill":216},[214],"svg-canvas","0","#ffffff"," ",[219,220,221],"title",{},"What each value does when the font is late",[223,224,225],"desc",{},"With swap the late font is applied at 1.4 seconds and produces a layout shift; with optional the same late font is not applied at all, so the page stays visually stable in the fallback.",[211,227],{"x":228,"y":228,"width":229,"height":230,"rx":231,"fill":232,"stroke":233,"style":234},"1","758","262","10","none","currentColor","stroke-opacity:0.18",[236,237,241],"text",{"x":238,"y":239,"fill":233,"style":240},"24","32","font-size:16px;font-weight:700","Same slow font, two outcomes",[236,243,66],{"x":238,"y":244,"fill":233,"style":245},"76","font-size:12px;font-weight:700",[211,247],{"x":248,"y":249,"width":250,"height":239,"rx":251,"fill":252,"stroke":252,"style":253},"100","58","120","4","#0466c8","fill-opacity:0.16;stroke-opacity:0.5",[236,255,260],{"x":256,"y":257,"fill":233,"style":258,"textAnchor":259},"160","79","font-size:11px;","middle","fallback painted",[211,262],{"x":263,"y":249,"width":264,"height":239,"rx":251,"fill":233,"stroke":233,"style":265},"220","240","fill-opacity:0.05;stroke-opacity:0.28",[236,267,269],{"x":268,"y":257,"fill":233,"style":258,"textAnchor":259},"340","reading in the fallback",[211,271],{"x":272,"y":249,"width":273,"height":239,"rx":251,"fill":274,"stroke":275,"style":276},"460","260","#ffc300","#b8860b","fill-opacity:0.28",[236,278,281],{"x":279,"y":257,"fill":233,"style":280,"textAnchor":259},"590","font-size:11px;font-weight:700;","web font applied",[283,284],"line",{"x1":272,"y1":285,"x2":272,"y2":249,"stroke":275,"strokeWidth":286},"46","2",[236,288,290],{"x":272,"y":289,"fill":275,"style":280,"textAnchor":259},"42","1.4s — shift here",[236,292,295],{"x":238,"y":293,"fill":233,"style":294},"106","font-size:11px;fill-opacity:0.75","Brand typography always wins; layout stability depends on tuned fallback metrics.",[283,297],{"x1":238,"y1":298,"x2":299,"y2":298,"stroke":233,"style":300},"128","736","stroke-opacity:0.2",[236,302,86],{"x":238,"y":303,"fill":233,"style":245},"176",[211,305],{"x":248,"y":306,"width":307,"height":239,"rx":251,"fill":233,"stroke":233,"style":308},"158","40","fill-opacity:0.14;stroke-opacity:0.4",[236,310,313],{"x":250,"y":311,"fill":233,"style":312,"textAnchor":259},"179","font-size:10px;","100ms",[211,315],{"x":316,"y":306,"width":317,"height":239,"rx":251,"fill":252,"stroke":252,"style":253},"140","580",[236,319,321],{"x":320,"y":311,"fill":233,"style":258,"textAnchor":259},"430","fallback painted — and kept for the whole page view",[236,323,325],{"x":238,"y":324,"fill":233,"style":294},"212","Zero shift, guaranteed; the visitor may never see your typeface on a cold cache.",[236,327,330],{"x":238,"y":328,"fill":233,"style":329},"244","font-size:11.5px;font-style:italic;fill-opacity:0.85","Preloading moves the decision: it makes optional's 100ms window winnable often enough to be worth taking.",[50,332,334],{"id":333},"root-cause-analysis-why-teams-pick-wrong","Root Cause Analysis: Why Teams Pick Wrong",[15,336,337,340,341,343,344,346],{},[61,338,339],{},"1. Treating it as an LCP setting."," Both values eliminate the block period, so both fix invisible text. Choosing ",[30,342,86],{}," \"for LCP\" over ",[30,345,66],{}," buys nothing measurable on that metric — the difference is entirely in what happens afterwards.",[15,348,349,217,355,357,358,360],{},[61,350,351,352,354],{},"2. Adopting ",[30,353,86],{}," to avoid doing the metric work.",[30,356,86],{}," does remove font-driven CLS for free, but it pays for it in brand fidelity on precisely the visits that matter most: new users on slow connections. Tuned overrides plus ",[30,359,66],{}," gets both, at the cost of half an hour of measurement.",[15,362,363,369],{},[61,364,365,366,368],{},"3. Using ",[30,367,86],{}," without a preload."," With no preload the font almost never wins the ~100ms race on a cold cache, so first-time visitors effectively never receive it — while you still pay to download it in the background for next time.",[15,371,372,375,376,379,380,383],{},[61,373,374],{},"4. Applying one value site-wide."," A brand display face on the hero and an icon font in the toolbar have opposite requirements. ",[30,377,378],{},"font-display"," is a per-",[30,381,382],{},"@font-face"," descriptor for a reason.",[50,385,387],{"id":386},"step-by-step-resolution-choosing-per-face","Step-by-Step Resolution: Choosing Per Face",[15,389,390,396],{},[61,391,392,393,395],{},"1. Default body and heading faces to ",[30,394,66],{}," with matched fallback metrics."," This is the configuration that satisfies both metrics at once.",[398,399,404],"pre",{"className":400,"code":401,"language":402,"meta":403,"style":403},"language-css shiki shiki-themes github-light-high-contrast github-dark-high-contrast github-light-high-contrast","@font-face {\n  font-family: \"Inter\"; src: url(\"\u002Ffonts\u002Finter-latin.woff2\") format(\"woff2\");\n  font-display: swap; font-weight: 100 900;\n}\n@font-face {\n  font-family: \"Inter Fallback\"; src: local(\"Arial\");\n  size-adjust: 107.4%; ascent-override: 90.2%; descent-override: 22.5%;\n}\nbody { font-family: \"Inter\", \"Inter Fallback\", sans-serif; }\n\u002F* trade-off: only correct once the overrides are measured. Shipping swap with\n   an untuned fallback trades an LCP win for a CLS regression. *\u002F\n","css","",[30,405,406,417,462,487,493,500,526,566,571,601,608],{"__ignoreMap":403},[407,408,410,413],"span",{"class":283,"line":409},1,[407,411,382],{"class":412},"sPARh",[407,414,416],{"class":415},"saISM"," {\n",[407,418,420,424,427,431,434,437,439,442,445,448,451,454,456,459],{"class":283,"line":419},2,[407,421,423],{"class":422},"sPXB4","  font-family",[407,425,426],{"class":415},": ",[407,428,430],{"class":429},"sZ8jY","\"Inter\"",[407,432,433],{"class":415},"; ",[407,435,436],{"class":422},"src",[407,438,426],{"class":415},[407,440,441],{"class":422},"url",[407,443,444],{"class":415},"(",[407,446,447],{"class":429},"\"\u002Ffonts\u002Finter-latin.woff2\"",[407,449,450],{"class":415},") ",[407,452,453],{"class":422},"format",[407,455,444],{"class":415},[407,457,458],{"class":429},"\"woff2\"",[407,460,461],{"class":415},");\n",[407,463,465,468,470,472,474,477,479,481,484],{"class":283,"line":464},3,[407,466,467],{"class":422},"  font-display",[407,469,426],{"class":415},[407,471,66],{"class":422},[407,473,433],{"class":415},[407,475,476],{"class":422},"font-weight",[407,478,426],{"class":415},[407,480,248],{"class":422},[407,482,483],{"class":422}," 900",[407,485,486],{"class":415},";\n",[407,488,490],{"class":283,"line":489},4,[407,491,492],{"class":415},"}\n",[407,494,496,498],{"class":283,"line":495},5,[407,497,382],{"class":412},[407,499,416],{"class":415},[407,501,503,505,507,510,512,514,516,519,521,524],{"class":283,"line":502},6,[407,504,423],{"class":422},[407,506,426],{"class":415},[407,508,509],{"class":429},"\"Inter Fallback\"",[407,511,433],{"class":415},[407,513,436],{"class":422},[407,515,426],{"class":415},[407,517,518],{"class":422},"local",[407,520,444],{"class":415},[407,522,523],{"class":429},"\"Arial\"",[407,525,461],{"class":415},[407,527,529,532,534,537,540,542,545,547,550,552,554,557,559,562,564],{"class":283,"line":528},7,[407,530,531],{"class":422},"  size-adjust",[407,533,426],{"class":415},[407,535,536],{"class":422},"107.4",[407,538,539],{"class":412},"%",[407,541,433],{"class":415},[407,543,544],{"class":422},"ascent-override",[407,546,426],{"class":415},[407,548,549],{"class":422},"90.2",[407,551,539],{"class":412},[407,553,433],{"class":415},[407,555,556],{"class":422},"descent-override",[407,558,426],{"class":415},[407,560,561],{"class":422},"22.5",[407,563,539],{"class":412},[407,565,486],{"class":415},[407,567,569],{"class":283,"line":568},8,[407,570,492],{"class":415},[407,572,574,578,581,584,586,588,591,593,595,598],{"class":283,"line":573},9,[407,575,577],{"class":576},"sZBmE","body",[407,579,580],{"class":415}," { ",[407,582,583],{"class":422},"font-family",[407,585,426],{"class":415},[407,587,430],{"class":429},[407,589,590],{"class":415},", ",[407,592,509],{"class":429},[407,594,590],{"class":415},[407,596,597],{"class":422},"sans-serif",[407,599,600],{"class":415},"; }\n",[407,602,604],{"class":283,"line":603},10,[407,605,607],{"class":606},"sjfSM","\u002F* trade-off: only correct once the overrides are measured. Shipping swap with\n",[407,609,611],{"class":283,"line":610},11,[407,612,613],{"class":606},"   an untuned fallback trades an LCP win for a CLS regression. *\u002F\n",[15,615,616,617,620],{},"Expected outcome: text paints at first paint, and the later swap moves nothing measurable — residual CLS under ",[30,618,619],{},"0.005",".",[15,622,623,629],{},[61,624,625,626,628],{},"2. Use ",[30,627,86],{}," for faces you cannot or will not tune."," A secondary display face used in one pull quote is not worth a measurement session.",[398,631,633],{"className":400,"code":632,"language":402,"meta":403,"style":403},"@font-face {\n  font-family: \"Playfair Display\";\n  src: url(\"\u002Ffonts\u002Fplayfair-latin.woff2\") format(\"woff2\");\n  font-display: optional;\n}\n\u002F* trade-off: on a cold cache this face will usually not render at all. That is\n   the point — but confirm the fallback is typographically acceptable, because\n   for many visitors it IS the design. *\u002F\n",[30,634,635,641,652,676,686,690,695,700],{"__ignoreMap":403},[407,636,637,639],{"class":283,"line":409},[407,638,382],{"class":412},[407,640,416],{"class":415},[407,642,643,645,647,650],{"class":283,"line":419},[407,644,423],{"class":422},[407,646,426],{"class":415},[407,648,649],{"class":429},"\"Playfair Display\"",[407,651,486],{"class":415},[407,653,654,657,659,661,663,666,668,670,672,674],{"class":283,"line":464},[407,655,656],{"class":422},"  src",[407,658,426],{"class":415},[407,660,441],{"class":422},[407,662,444],{"class":415},[407,664,665],{"class":429},"\"\u002Ffonts\u002Fplayfair-latin.woff2\"",[407,667,450],{"class":415},[407,669,453],{"class":422},[407,671,444],{"class":415},[407,673,458],{"class":429},[407,675,461],{"class":415},[407,677,678,680,682,684],{"class":283,"line":489},[407,679,467],{"class":422},[407,681,426],{"class":415},[407,683,86],{"class":422},[407,685,486],{"class":415},[407,687,688],{"class":283,"line":495},[407,689,492],{"class":415},[407,691,692],{"class":283,"line":502},[407,693,694],{"class":606},"\u002F* trade-off: on a cold cache this face will usually not render at all. That is\n",[407,696,697],{"class":283,"line":528},[407,698,699],{"class":606},"   the point — but confirm the fallback is typographically acceptable, because\n",[407,701,702],{"class":283,"line":568},[407,703,704],{"class":606},"   for many visitors it IS the design. *\u002F\n",[15,706,707],{},"Expected outcome: zero shift contribution from this face, at the price of inconsistent typography on first visits.",[15,709,710,716],{},[61,711,712,713,715],{},"3. Pair ",[30,714,86],{}," with a preload when the face matters."," The preload is what makes the short window winnable.",[398,718,722],{"className":719,"code":720,"language":721,"meta":403,"style":403},"language-html shiki shiki-themes github-light-high-contrast github-dark-high-contrast github-light-high-contrast","\u003Clink rel=\"preload\" as=\"font\" type=\"font\u002Fwoff2\" crossorigin\n      href=\"\u002Ffonts\u002Fplayfair-latin.woff2\">\n\u003C!-- trade-off: you are now spending critical-path priority on a face you have\n     also declared non-essential. Only do this for a face that is genuinely\n     part of the above-the-fold design. -->\n","html",[30,723,724,760,772,777,782],{"__ignoreMap":403},[407,725,726,729,732,735,738,741,744,746,749,752,754,757],{"class":283,"line":409},[407,727,728],{"class":415},"\u003C",[407,730,731],{"class":576},"link",[407,733,734],{"class":422}," rel",[407,736,737],{"class":415},"=",[407,739,740],{"class":429},"\"preload\"",[407,742,743],{"class":422}," as",[407,745,737],{"class":415},[407,747,748],{"class":429},"\"font\"",[407,750,751],{"class":422}," type",[407,753,737],{"class":415},[407,755,756],{"class":429},"\"font\u002Fwoff2\"",[407,758,759],{"class":422}," crossorigin\n",[407,761,762,765,767,769],{"class":283,"line":419},[407,763,764],{"class":422},"      href",[407,766,737],{"class":415},[407,768,665],{"class":429},[407,770,771],{"class":415},">\n",[407,773,774],{"class":283,"line":464},[407,775,776],{"class":606},"\u003C!-- trade-off: you are now spending critical-path priority on a face you have\n",[407,778,779],{"class":283,"line":489},[407,780,781],{"class":606},"     also declared non-essential. Only do this for a face that is genuinely\n",[407,783,784],{"class":283,"line":495},[407,785,786],{"class":606},"     part of the above-the-fold design. -->\n",[15,788,789],{},"Expected outcome: on typical connections the font arrives inside the window and is used, with the guarantee that a slow connection silently falls back instead of shifting.",[15,791,792,798],{},[61,793,794,795,797],{},"4. Keep ",[30,796,32],{}," for icon fonts only."," An icon font's fallback is a blank box or a wrong glyph, and its render area is fixed, so a short block period is genuinely the least-bad option. Better still, replace icon fonts with inline SVG and remove the question.",[50,800,802],{"id":801},"verification","Verification",[15,804,805,806,809],{},"Test both cold and warm. On a cold cache with a throttled connection, confirm which face actually rendered — ",[30,807,808],{},"document.fonts.check('1em Playfair Display')"," tells you whether the browser used it. Then reload warm and confirm the branded face appears.",[15,811,812],{},"Measure the two metrics separately, because the values affect them differently:",[398,814,818],{"className":815,"code":816,"language":817,"meta":403,"style":403},"language-javascript shiki shiki-themes github-light-high-contrast github-dark-high-contrast github-light-high-contrast","\u002F\u002F Did the font get used, and did anything move afterwards?\naddEventListener('load', () => {\n  console.log('branded face used:', document.fonts.check('1em \"Playfair Display\"'));\n});\nnew PerformanceObserver((l) => {\n  for (const e of l.getEntries()) if (!e.hadRecentInput && e.value > 0.001)\n    console.log('shift', e.value.toFixed(4), 'at', Math.round(e.startTime));\n}).observe({ type: 'layout-shift', buffered: true });\n","javascript",[30,819,820,825,844,871,876,897,949,986],{"__ignoreMap":403},[407,821,822],{"class":283,"line":409},[407,823,824],{"class":606},"\u002F\u002F Did the font get used, and did anything move afterwards?\n",[407,826,827,831,833,836,839,842],{"class":283,"line":419},[407,828,830],{"class":829},"smZ65","addEventListener",[407,832,444],{"class":415},[407,834,835],{"class":429},"'load'",[407,837,838],{"class":415},", () ",[407,840,841],{"class":412},"=>",[407,843,416],{"class":415},[407,845,846,849,852,854,857,860,863,865,868],{"class":283,"line":464},[407,847,848],{"class":415},"  console.",[407,850,851],{"class":829},"log",[407,853,444],{"class":415},[407,855,856],{"class":429},"'branded face used:'",[407,858,859],{"class":415},", document.fonts.",[407,861,862],{"class":829},"check",[407,864,444],{"class":415},[407,866,867],{"class":429},"'1em \"Playfair Display\"'",[407,869,870],{"class":415},"));\n",[407,872,873],{"class":283,"line":489},[407,874,875],{"class":415},"});\n",[407,877,878,881,884,887,891,893,895],{"class":283,"line":495},[407,879,880],{"class":412},"new",[407,882,883],{"class":829}," PerformanceObserver",[407,885,886],{"class":415},"((",[407,888,890],{"class":889},"sQw3B","l",[407,892,450],{"class":415},[407,894,841],{"class":412},[407,896,416],{"class":415},[407,898,899,902,905,908,911,914,917,920,923,926,928,931,934,937,940,943,946],{"class":283,"line":502},[407,900,901],{"class":412},"  for",[407,903,904],{"class":415}," (",[407,906,907],{"class":412},"const",[407,909,910],{"class":422}," e",[407,912,913],{"class":412}," of",[407,915,916],{"class":415}," l.",[407,918,919],{"class":829},"getEntries",[407,921,922],{"class":415},"()) ",[407,924,925],{"class":412},"if",[407,927,904],{"class":415},[407,929,930],{"class":412},"!",[407,932,933],{"class":415},"e.hadRecentInput ",[407,935,936],{"class":412},"&&",[407,938,939],{"class":415}," e.value ",[407,941,942],{"class":412},">",[407,944,945],{"class":422}," 0.001",[407,947,948],{"class":415},")\n",[407,950,951,954,956,958,961,964,967,969,971,974,977,980,983],{"class":283,"line":528},[407,952,953],{"class":415},"    console.",[407,955,851],{"class":829},[407,957,444],{"class":415},[407,959,960],{"class":429},"'shift'",[407,962,963],{"class":415},", e.value.",[407,965,966],{"class":829},"toFixed",[407,968,444],{"class":415},[407,970,251],{"class":422},[407,972,973],{"class":415},"), ",[407,975,976],{"class":429},"'at'",[407,978,979],{"class":415},", Math.",[407,981,982],{"class":829},"round",[407,984,985],{"class":415},"(e.startTime));\n",[407,987,988,991,994,997,1000,1003,1006],{"class":283,"line":568},[407,989,990],{"class":415},"}).",[407,992,993],{"class":829},"observe",[407,995,996],{"class":415},"({ type: ",[407,998,999],{"class":429},"'layout-shift'",[407,1001,1002],{"class":415},", buffered: ",[407,1004,1005],{"class":422},"true",[407,1007,1008],{"class":415}," });\n",[15,1010,1011,1012,1014,1015,1017,1018,1021,1022,1024,1025,1028],{},"Expect ",[30,1013,66],{}," with tuned overrides to show the face used and no shifts above noise. Expect ",[30,1016,86],{}," on a cold, throttled load to show the face ",[40,1019,1020],{},"not"," used and no shifts at all. Either is a pass; a ",[30,1023,66],{}," configuration that shows a shift above ",[30,1026,1027],{},"0.01"," means the overrides are not doing their job.",[50,1030,1032],{"id":1031},"faq","FAQ",[1034,1035,1038,1042],"details",{"className":1036},[1037],"faq-item",[1039,1040,1041],"summary",{},"Does font-display: optional improve LCP compared to swap?",[15,1043,1044,1045,1047],{},"Not meaningfully. Both have a block period at or near zero, so text paints at essentially the same moment; ",[30,1046,86],{},"'s ~100ms block is short enough to be invisible in most measurements. If you are choosing between them to move LCP, you are optimising the wrong variable — look at discovery time and transfer size instead.",[1034,1049,1051,1054],{"className":1050},[1037],[1039,1052,1053],{},"Can I use different values for different weights of the same family?",[15,1055,1056,1057,1059,1060,1062,1063,1065,1066,1068],{},"Yes, and it is often the right answer. ",[30,1058,378],{}," is a descriptor on each ",[30,1061,382],{}," rule, so the 400 weight used for body copy can be ",[30,1064,66],{}," while a 900 display weight used only in a hero is ",[30,1067,86],{},". Keep the fallback stack consistent across weights so the tuned metrics still apply.",[1034,1070,1072,1075],{"className":1071},[1037],[1039,1073,1074],{},"Which one should a content-heavy site default to?",[15,1076,1077,1079,1080,1082],{},[30,1078,66],{}," with measured fallback metrics. Long-form reading is where typography actually matters, so silently dropping the face on first visits is a real product cost, and the CLS risk is fully solvable with overrides. Reserve ",[30,1081,86],{}," for faces whose absence a reader would not notice.",[1034,1084,1086,1089],{"className":1085},[1037],[1039,1087,1088],{},"Does the choice matter for repeat visitors?",[15,1090,1091],{},"Not at all, which is why it is easy to under-estimate. On a warm cache the font is available immediately, so every display value produces the same result and the difference is invisible to anyone testing on their own machine. The entire decision is about first-time visitors on cold caches — precisely the population least represented in a developer's day-to-day experience and most represented in a search-driven audience.",[1034,1093,1095,1098],{"className":1094},[1037],[1039,1096,1097],{},"How do I decide if the fallback is acceptable?",[15,1099,1100,1101,1103,1104,1106],{},"Look at the page rendered entirely in the fallback, at the size and weight it actually uses, and ask whether it reads as your product. Block the font file in DevTools and screenshot the result. For a neutral UI sans the answer is usually yes, and ",[30,1102,86],{}," becomes attractive; for a distinctive brand face the answer is usually no, and the measurement work behind ",[30,1105,66],{}," is justified. Make the call from the screenshot rather than from the principle.",[1034,1108,1110,1113],{"className":1109},[1037],[1039,1111,1112],{},"What about variable fonts with multiple axes?",[15,1114,1115,1116,1118,1119,1121],{},"The display value applies per ",[30,1117,382],{},", and a variable font is one face, so a single decision covers every weight it produces. That is an advantage: with static faces you can end up with ",[30,1120,66],{}," on the regular weight and a forgotten default on the bold, which produces an inconsistent paint. If you ship a variable font, check that no leftover static declarations remain in the stylesheet competing with it.",[50,1123,1125],{"id":1124},"related","Related",[55,1127,1128,1133,1143],{},[58,1129,1130,1132],{},[19,1131,22],{"href":21}," — the surrounding pipeline: discovery, subsetting and budgets.",[58,1134,1135,1139,1140,1142],{},[19,1136,1138],{"href":1137},"\u002Fcore-web-vitals-measurement\u002Ffont-loading-and-text-rendering-performance\u002Ffixing-cls-from-web-font-swap\u002F","Fixing CLS from web font swap"," — how to derive the overrides that make ",[30,1141,66],{}," safe.",[58,1144,1145,1149],{},[19,1146,1148],{"href":1147},"\u002Fcore-web-vitals-measurement\u002Ffont-loading-and-text-rendering-performance\u002Fpreloading-google-fonts-without-blocking-render\u002F","Preloading Google Fonts without blocking render"," — make the arrival window winnable for third-party faces.",[1151,1152,1154],"script",{"type":1153},"application\u002Fld+json","\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"HowTo\",\n  \"name\": \"Choose between font-display swap and optional\",\n  \"description\": \"Decide per typeface whether a late web font should be swapped in or dropped, based on layout-shift risk, brand fidelity and whether the fallback metrics are tuned.\",\n  \"step\": [\n    { \"@type\": \"HowToStep\", \"position\": 1, \"name\": \"Default to swap with tuned metrics\", \"text\": \"Use font-display swap for body and heading faces alongside a metric-matched local fallback.\", \"url\": \"https:\u002F\u002Ffrontend-performance.com\u002Fcore-web-vitals-measurement\u002Ffont-loading-and-text-rendering-performance\u002Ffont-display-swap-vs-optional-for-lcp\u002F#step-by-step-resolution-choosing-per-face\" },\n    { \"@type\": \"HowToStep\", \"position\": 2, \"name\": \"Use optional for untuned faces\", \"text\": \"Apply font-display optional to secondary or decorative faces you will not measure.\", \"url\": \"https:\u002F\u002Ffrontend-performance.com\u002Fcore-web-vitals-measurement\u002Ffont-loading-and-text-rendering-performance\u002Ffont-display-swap-vs-optional-for-lcp\u002F#step-by-step-resolution-choosing-per-face\" },\n    { \"@type\": \"HowToStep\", \"position\": 3, \"name\": \"Preload optional faces that matter\", \"text\": \"Pair optional with a preload so the short availability window is winnable on typical connections.\", \"url\": \"https:\u002F\u002Ffrontend-performance.com\u002Fcore-web-vitals-measurement\u002Ffont-loading-and-text-rendering-performance\u002Ffont-display-swap-vs-optional-for-lcp\u002F#step-by-step-resolution-choosing-per-face\" },\n    { \"@type\": \"HowToStep\", \"position\": 4, \"name\": \"Verify cold and warm\", \"text\": \"Check document.fonts.check to see which face rendered and observe layout shifts on both cache states.\", \"url\": \"https:\u002F\u002Ffrontend-performance.com\u002Fcore-web-vitals-measurement\u002Ffont-loading-and-text-rendering-performance\u002Ffont-display-swap-vs-optional-for-lcp\u002F#verification\" }\n  ]\n}\n",[1151,1156,1157],{"type":1153},"\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"TechArticle\",\n  \"headline\": \"font-display: swap vs optional — Which One Should Your Fonts Use?\",\n  \"description\": \"A per-face decision matrix comparing font-display swap and optional on paint timing, layout shift risk and brand fidelity.\",\n  \"datePublished\": \"2026-08-01\",\n  \"dateModified\": \"2026-08-01\",\n  \"author\": { \"@type\": \"Organization\", \"name\": \"frontend-performance.com\" },\n  \"publisher\": { \"@type\": \"Organization\", \"name\": \"frontend-performance.com\" },\n  \"mainEntityOfPage\": { \"@type\": \"WebPage\", \"@id\": \"https:\u002F\u002Ffrontend-performance.com\u002Fcore-web-vitals-measurement\u002Ffont-loading-and-text-rendering-performance\u002Ffont-display-swap-vs-optional-for-lcp\u002F\" }\n}\n",[1151,1159,1160],{"type":1153},"\n{\n  \"@context\": \"https:\u002F\u002Fschema.org\",\n  \"@type\": \"BreadcrumbList\",\n  \"itemListElement\": [\n    { \"@type\": \"ListItem\", \"position\": 1, \"name\": \"Home\", \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002F\" },\n    { \"@type\": \"ListItem\", \"position\": 2, \"name\": \"Core Web Vitals & Measurement\", \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fcore-web-vitals-measurement\u002F\" },\n    { \"@type\": \"ListItem\", \"position\": 3, \"name\": \"Font Loading & Text Rendering Performance\", \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fcore-web-vitals-measurement\u002Ffont-loading-and-text-rendering-performance\u002F\" },\n    { \"@type\": \"ListItem\", \"position\": 4, \"name\": \"font-display: swap vs optional for LCP\", \"item\": \"https:\u002F\u002Ffrontend-performance.com\u002Fcore-web-vitals-measurement\u002Ffont-loading-and-text-rendering-performance\u002Ffont-display-swap-vs-optional-for-lcp\u002F\" }\n  ]\n}\n",[1162,1163,1164],"style",{},"html pre.shiki code .sPARh, html code.shiki .sPARh{--shiki-default:#A0111F;--shiki-dark:#FF9492;--shiki-light:#A0111F}html pre.shiki code .saISM, html code.shiki .saISM{--shiki-default:#0E1116;--shiki-dark:#F0F3F6;--shiki-light:#0E1116}html pre.shiki code .sPXB4, html code.shiki .sPXB4{--shiki-default:#023B95;--shiki-dark:#91CBFF;--shiki-light:#023B95}html pre.shiki code .sZ8jY, html code.shiki .sZ8jY{--shiki-default:#032563;--shiki-dark:#ADDCFF;--shiki-light:#032563}html pre.shiki code .sZBmE, html code.shiki .sZBmE{--shiki-default:#024C1A;--shiki-dark:#72F088;--shiki-light:#024C1A}html pre.shiki code .sjfSM, html code.shiki .sjfSM{--shiki-default:#66707B;--shiki-dark:#BDC4CC;--shiki-light:#66707B}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);}html pre.shiki code .smZ65, html code.shiki .smZ65{--shiki-default:#622CBC;--shiki-dark:#DBB7FF;--shiki-light:#622CBC}html pre.shiki code .sQw3B, html code.shiki .sQw3B{--shiki-default:#702C00;--shiki-dark:#FFB757;--shiki-light:#702C00}",{"title":403,"searchDepth":419,"depth":419,"links":1166},[1167,1168,1169,1170,1171,1172,1173],{"id":52,"depth":419,"text":53},{"id":96,"depth":419,"text":97},{"id":333,"depth":419,"text":334},{"id":386,"depth":419,"text":387},{"id":801,"depth":419,"text":802},{"id":1031,"depth":419,"text":1032},{"id":1124,"depth":419,"text":1125},"Both values paint text fast. They differ on whether the font is allowed to arrive late — and that difference is a CLS decision, not an LCP one.","md",{"slug":1177,"type":1178,"breadcrumb":1179,"datePublished":1187,"dateModified":1187},"font-display-swap-vs-optional-for-lcp","article",[1180,1183,1184,1185],{"name":1181,"url":1182},"Home","\u002F",{"name":27,"url":26},{"name":22,"url":21},{"name":5,"url":1186},"\u002Fcore-web-vitals-measurement\u002Ffont-loading-and-text-rendering-performance\u002Ffont-display-swap-vs-optional-for-lcp\u002F","2026-08-01",true,"\u002Fcore-web-vitals-measurement\u002Ffont-loading-and-text-rendering-performance\u002Ffont-display-swap-vs-optional-for-lcp",{"title":1191,"description":1192},"font-display: swap vs optional — Which Is Better for LCP?","A decision matrix for font-display swap versus optional: text paint timing, layout shift risk, brand fidelity, and which one wins for headings, body copy and icons.","core-web-vitals-measurement\u002Ffont-loading-and-text-rendering-performance\u002Ffont-display-swap-vs-optional-for-lcp\u002Findex","Qb9pDsL7eO7FfFq38hV9o9Y24UF6dHunvfr0C934C08",[1196,1200],{"title":1197,"path":1198,"stem":1199,"children":-1},"Fixing CLS from Web Font Swap","\u002Fcore-web-vitals-measurement\u002Ffont-loading-and-text-rendering-performance\u002Ffixing-cls-from-web-font-swap","core-web-vitals-measurement\u002Ffont-loading-and-text-rendering-performance\u002Ffixing-cls-from-web-font-swap\u002Findex",{"title":1201,"path":1202,"stem":1203,"children":-1},"Preloading Google Fonts Without Blocking Render","\u002Fcore-web-vitals-measurement\u002Ffont-loading-and-text-rendering-performance\u002Fpreloading-google-fonts-without-blocking-render","core-web-vitals-measurement\u002Ffont-loading-and-text-rendering-performance\u002Fpreloading-google-fonts-without-blocking-render\u002Findex",1785622406686]