<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[PeakSpire]]></title><description><![CDATA[PeakSpire]]></description><link>https://peakspire-ca.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Sat, 07 Nov 2026 12:35:55 GMT</lastBuildDate><atom:link href="https://peakspire-ca.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[What 97 Ottawa small-business websites taught us about web-font performance]]></title><description><![CDATA[I fix slow websites for a living. My agency is in Ottawa, and most of my clients are trades and home services: plumbers, electricians, HVAC, roofers…]]></description><link>https://peakspire-ca.hashnode.dev/what-97-ottawa-small-business-websites-taught-us-about-web-font-performance</link><guid isPermaLink="true">https://peakspire-ca.hashnode.dev/what-97-ottawa-small-business-websites-taught-us-about-web-font-performance</guid><category><![CDATA[webdev]]></category><category><![CDATA[performance]]></category><category><![CDATA[fonts]]></category><category><![CDATA[WordPress]]></category><dc:creator><![CDATA[PeakSpire]]></dc:creator><pubDate>Sun, 01 Nov 2026 16:12:48 GMT</pubDate><content:encoded><![CDATA[<p>I fix slow websites for a living. My agency is in Ottawa, and most of my clients are trades and home services: plumbers, electricians, HVAC, roofers, cleaners. Early in 2026 I got tired of guessing what slow means in this market, so I measured it.</p>
<h2>The dataset</h2>
<p>In March 2026 I ran Google PageSpeed mobile audits on 97 Ottawa-area service business websites. The set was sourced from public directories, so it represents businesses that list publicly rather than a formal census of the city. Every vertical I serve was in there: plumbing, electrical, HVAC, roofing, landscaping, painting, tree work, cleaning.</p>
<p>The median mobile score was 66 out of 100. Five sites finished at a perfect 100, and ten of the 97 reached 90 or better. At the other end, two sites scored 13 and 0. The median Largest Contentful Paint across the census was 6.3 seconds. Every score is published here: <a href="https://peakspire.ca/ottawa-website-benchmarks/">https://peakspire.ca/ottawa-website-benchmarks/</a></p>
<p>Two slices matter for this post. The five plumber homepages in the set scored 43, 46, 53, 67 and 73, a median of 53. And in October 2026 I re-ran the exercise for Ottawa pest control companies: seven local sites, mobile scores from 20 to 83, median 65, with two of the seven below 50.</p>
<p>A median of 66 is not a scandal, it is a description. Half of these sites load like it is 2015 on a phone.</p>
<h2>What the waterfalls kept showing</h2>
<p>One honest caveat first: the census tracks PageSpeed scores and opportunity flags, not font statistics specifically. I will not invent a percentage of sites with font sins. What I can tell you is what I see when I open the network waterfall on the slow half of this set, over and over.</p>
<p><strong>Fonts hiding at the end of the waterfall.</strong> The browser has to fetch the HTML, fetch the stylesheet, parse the stylesheet, only then discover the WOFF2 URL, and fetch that too. That is two extra round trips on a phone network before real text renders. A preload link removes both.</p>
<p><strong>Missing font-display descriptors.</strong> Plenty of hand-rolled @font-face rules set no font-display value at all. The default behavior holds text back while the font downloads. On a throttled mobile connection that is seconds of invisible headings staring back at a homeowner with a burst pipe.</p>
<p><strong>The flash, handled badly.</strong> When the fallback stack does not match the web font metrics, text renders twice: fallback first, then a visible shift when the real font lands. It is ugly, and it moves layout after someone has already started reading.</p>
<p><strong>Remote Google Fonts where local WOFF2 would do.</strong> That is two more origins to resolve and negotiate TLS with, usually without a preconnect hint. There is also a 2022 German regional court ruling that embedding Google Fonts without consent can breach GDPR, which matters if you sell into Europe, or if you simply dislike shipping a visitor IP address to a third party for a font you could self-host. WordPress themes that bundle their own CSS still point at <a href="http://fonts.googleapis.com">fonts.googleapis.com</a> more often than you would think.</p>
<p>To be clear about scale: in the audit exports, 50 of the 97 sites were flagged for unused JavaScript and 48 carried redirect chains. Fonts are rarely the whole problem. But they are the part that paints your words, they are cheap to fix, and they are usually fixed wrong.</p>
<h2>The fix pattern</h2>
<p>The whole fix is three moves and one habit.</p>
<p>Preload the local WOFF2 files the page actually uses. A preload link in the head tells the browser: fetch this font now, in parallel with everything else, before any stylesheet parsing blocks it. One line per weight, with crossorigin set, and the waterfall problem disappears.</p>
<p>Set font-display: swap on every @font-face rule. Swap shows fallback text immediately and swaps the web font in when it lands. The text is always readable. On a slow connection the reader gets words instantly instead of a blank gap.</p>
<p>Match the fallback stack metrics to the web font. When size, line height, and letter spacing of the fallback roughly match the real font, the swap shift shrinks from a layout jump to a non-event.</p>
<p>The habit: test on a throttled phone profile every time. Desktop Chrome on fibre hides all three problems. A mid tier Android on a congested cell tower exposes every one of them.</p>
<h2>Why I ended up writing a plugin</h2>
<p>I build WordPress sites, so I kept applying the same three moves by hand on every build. Then I checked what the existing plugins do. The popular ones either cache Google Fonts locally without preloading theme bundled files, or they preload everything including fonts the page never uses. So I wrote Font Speed Fix, a small WordPress plugin now in review at the <a href="http://wordpress.org">wordpress.org</a> directory: it discovers local WOFF2 fonts from theme and plugin stylesheets, preloads the ones the page uses, injects font-display swap, and locks its scans so a burst of traffic cannot stampede the font discovery. The plugin page and source are at <a href="https://github.com/sirajahmadzai/font-speed-fix">https://github.com/sirajahmadzai/font-speed-fix</a></p>
<p>I am not claiming fonts are why Ottawa service sites score 66. The census says the heap is bigger: unused JavaScript, redirect chains, unoptimized images. Fonts are just the piece I can fix before lunch, and the piece nobody should get wrong in 2026.</p>
<h2>The numbers, again</h2>
<p>If you run a service business in Ottawa, the honest summary is: half the local market loads slowly on phones, almost nobody hits 90, and the fixes are known. The whole dataset is at <a href="https://peakspire.ca/ottawa-website-benchmarks/">https://peakspire.ca/ottawa-website-benchmarks/</a> and the map pack calculator for pricing the traffic side is at <a href="https://peakspire.ca/map-pack-value-calculator/">https://peakspire.ca/map-pack-value-calculator/</a></p>
<p>Questions about the method or the data, I am happy to answer them.</p>
<p>Originally published at <a href="https://dev.to/peakspire/what-97-ottawa-small-business-websites-taught-us-about-web-font-performance-189g">https://dev.to/peakspire/what-97-ottawa-small-business-websites-taught-us-about-web-font-performance-189g</a></p>
]]></content:encoded></item></channel></rss>