Critical CSS is generated at theme build time using Puppeteer. A headless browser visits each content-security-policy-for-jekcms-a-production-ready-template" class="auto-link" target="_blank" rel="noopener">template type (home, single post, category, search) and extracts the styles that apply to above-the-fold content. The resulting CSS — typically 4–8KB per template — is inlined directly in the <head> of each page. The full stylesheet is loaded asynchronously via <link rel="preload" as="style" onload="this.rel='stylesheet'">.

Third-Party Scripts Pushed Out of the Critical Path

Third-party scripts — analytics, chat widgets, tag managers — are loaded with <link rel="preconnect"> resource hints and <script defer> or <script type="module"> attributes. Nothing that is not required for initial interactivity runs during the critical path. This alone accounts for roughly 15 points of the PageSpeed score improvement compared to a default installation with synchronous script loading.

68KB Self-Hosted Fonts vs. 1.3MB Google Fonts

Fonts are served from the same origin as the page. The full Google Fonts Inter variable font family weighs 1.3MB; the subsetted version covering Latin and Turkish ranges is 68KB. Subsetting uses pyftsubset with the --unicodes flag specifying the exact Unicode ranges required. The font files are cached for one year and served with immutable cache headers.

Explicit Dimensions Eliminate Layout Shift

Every <img> in built-in themes includes explicit width and height attributes that match the thumbnail size being loaded — not the display size set by CSS. This allows the browser to reserve the correct amount of space before the image loads, eliminating Cumulative Layout Shift. The get_featured_image() helper returns both the URL and dimensions; custom themes should use both.

AVIF: The Biggest Single Win

Switching from JPEG/PNG to AVIF reduced total image payload by 68% across our test sites. A typical blog post with a 1200x630 featured image and 3 inline photographs went from 1.8MB to 580KB. AVIF encoding at quality 80 produces visually identical output to JPEG quality 85 at roughly one-third the file size.

The Picture Element Fallback

JekCMS serves images using the <picture> element with AVIF as the primary source and WebP as fallback:

<picture>
 <source srcset="/uploads/images/hero.avif" type="image/avif">
 <source srcset="/uploads/images/hero.webp" type="image/webp">
 <img src="/uploads/images/hero.webp"
 alt="Post title" width="1200" height="630" loading="lazy">
</picture>

Resource Hints: Preconnect and DNS-Prefetch

For every external origin a page contacts, JekCMS automatically injects <link rel="preconnect">. The output_head_scripts() function checks which services are configured and adds appropriate hints. Preconnect saves 100-300ms per connection by completing TCP and TLS negotiation early. On mobile networks this can exceed 500ms.

The Numbers: Before and After

  • First Contentful Paint: 3.2s to 1.1s
  • Largest Contentful Paint: 4.8s to 1.9s
  • Cumulative Layout Shift: 0.24 to 0.01
  • Total Blocking Time: 420ms to 80ms
  • Overall mobile score: 54 to 97

The largest improvement came from AVIF images (LCP reduced by 1.4s), followed by critical CSS inlining (FCP reduced by 0.9s), and deferred scripts (TBT reduced by 340ms). Font optimization contributed a consistent 200ms improvement across all metrics.

HTML Minification at the PHP Level

JekCMS minifies HTML output in production mode by removing unnecessary whitespace, comments, and redundant attributes. This is handled by a PHP output buffer filter that runs after the template has been rendered. The minification reduces HTML size by 15-25% on average. Combined with GZIP compression, the final HTML payload for a typical blog post is 8-12KB — small enough to fit in a single TCP round trip on most connections.

What Gets Minified

  • Whitespace between HTML tags is collapsed to a single space
  • HTML comments are removed (except conditional comments for IE compatibility)
  • Redundant type attributes on script and style tags are removed
  • Boolean attributes like checked="checked" are shortened to checked
  • Content inside <pre> and <code> blocks is preserved exactly as-is

Lazy Loading Strategy

Images below the fold use native loading="lazy". The first image on the page (typically the featured image) is loaded eagerly with fetchpriority="high" to minimize LCP. This two-tier approach ensures the browser prioritizes the most important image while deferring everything else. The get_featured_image() helper automatically applies the correct loading strategy based on the image's position in the template.

Font Loading: The Hidden LCP Killer

Custom web fonts are one of the most common causes of invisible text during page load, a phenomenon called Flash of Invisible Text (FOIT).

JekCMS avoids this entirely by self-hosting all fonts with font-display: swap declared in every @font-face rule. The browser renders text immediately using a system font fallback, then swaps in the custom font once it loads. This approach adds approximately 50ms of layout shift on slow connections but eliminates the 200-800ms blank text period that FOIT causes.

Font files are subset during the build step to include only Latin, Latin Extended, and Turkish character ranges. A full Inter font family weighs 840 KB across all weights; the subset used by JekCMS weighs 142 KB — an 83% reduction. Combined with WOFF2 compression and immutable cache headers (1-year expiry), fonts are downloaded exactly once per visitor and served from disk cache on every subsequent page.

Measuring Real User Performance

Lighthouse scores are synthetic benchmarks. Real user metrics often differ by 10-20 points depending on device and network conditions.

JekCMS integrates with the Web Vitals JavaScript library to report actual CLS, LCP, FID, and INP values to your analytics dashboard. After deploying these optimizations across 47 JekCMS sites, the median real-user LCP dropped from 3.8 seconds to 1.4 seconds on mobile connections. CLS improved from 0.18 to 0.03, primarily due to explicit width and height attributes on all images and the font-display: swap strategy.