From b5e7d39846c3e056baf8c4d51b58dfd55483917d Mon Sep 17 00:00:00 2001 From: rg755421 Date: Thu, 1 Oct 2026 09:35:40 +0545 Subject: [PATCH 1/3] Fix - Redundant Font Awesome stylesheets loaded alongside all.min.css all.min.css already contains every rule and @font-face that solid, regular and brands contain, so those three stylesheets were duplicate requests on every page. v4-shims stays: the theme's markup uses v4 class names (fa fa-*), which only the shim maps. Same fix as Flash. Co-Authored-By: Claude Opus 5.5 (1M context) Same fix as themegrill/accelerate-pro#83. --- inc/functions.php | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/inc/functions.php b/inc/functions.php index 608aad0..6f910ac 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -85,21 +85,6 @@ function accelerate_scripts_styles_method() { 'file' => '/all', 'version' => '6.7.2', ), - array( - 'handle' => 'font-awesome-solid', - 'file' => '/solid', - 'version' => '6.7.2', - ), - array( - 'handle' => 'font-awesome-regular', - 'file' => '/regular', - 'version' => '6.7.2', - ), - array( - 'handle' => 'font-awesome-brands', - 'file' => '/brands', - 'version' => '6.7.2', - ), ); foreach ( $font_awesome_styles as $style ) { From 63f136e2a392bf118a3ccd640a802f2b37a51f8f Mon Sep 17 00:00:00 2001 From: rg755421 Date: Thu, 1 Oct 2026 09:54:46 +0545 Subject: [PATCH 2/3] Test - Guard Font Awesome loading only all + v4-shims, with icons still rendering Replaces the quarantined ACCELERATE-004 spec: asserts exactly all + v4-shims (minified or unminified) and that a solid and a regular v4 icon in the post meta render from a loaded Font Awesome face. Fails on develop (3 extra stylesheets); the glyph check fails if all.css is missing. Co-Authored-By: Claude Opus 5.5 (1M context) --- .../font-awesome-single-bundle.spec.ts | 46 ++++++++++++------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/tests/e2e/specs/performance/font-awesome-single-bundle.spec.ts b/tests/e2e/specs/performance/font-awesome-single-bundle.spec.ts index adb1590..4aee296 100644 --- a/tests/e2e/specs/performance/font-awesome-single-bundle.spec.ts +++ b/tests/e2e/specs/performance/font-awesome-single-bundle.spec.ts @@ -3,30 +3,42 @@ import { test, expect } from "@playwright/test"; /** * @area assets * @tier fresh - * @source accelerate-free-pro-senior-dev-audit.html#ACCELERATE-004 - * @why inc/functions.php:76-113 enqueues 5 overlapping Font Awesome - * stylesheets (v4-shims, all, solid, regular, brands) unconditionally - * on every page, even though `all.css` already contains solid+regular+ - * brands. Lighthouse measured this + Google Fonts as ~two-thirds of the - * homepage's byte weight. Only one `/fontawesome/css/*.css` request - * should be needed. + * @guards themegrill/accelerate-pro#83 ACCELERATE-004 + * @source accelerate-free-pro-senior-dev-audit.html#ACCELERATE-004; themegrill/flash#120 (same fix) + * @why inc/functions.php enqueued v4-shims, all, solid, regular and brands on + * every page, and `all` already contains every rule and @font-face of the + * other three. v4-shims stays: the theme's markup uses v4 class names + * (`fa fa-*`) that only the shim maps, so the target is exactly two, not + * one. Asserts `all` + the shim (minified or, with SCRIPT_DEBUG, not), and + * that a solid and a regular v4 icon in the post meta still render from a + * loaded Font Awesome face. */ -// Quarantined: ACCELERATE-004 is not fixed yet. Drop `.fixme` in the PR that fixes it. -test.fixme("only one Font Awesome stylesheet loads per page @assets @performance @fresh", async ({ +test("Font Awesome loads only the full bundle and the v4 shim, and icons still render @assets @performance @fresh", async ({ page, }) => { - const fontAwesomeRequests: string[] = []; + const requested = new Set(); page.on("request", (req) => { - if (/\/fontawesome\/css\//.test(req.url())) { - fontAwesomeRequests.push(req.url()); - } + const m = req.url().match(/\/fontawesome\/css\/([a-z0-9-]+?)(?:\.min)?\.css/); + if (m) requested.add(m[1]); }); await page.goto("/"); await page.waitForLoadState("networkidle"); + expect([...requested].sort(), "Font Awesome stylesheets requested").toEqual(["all", "v4-shims"]); - expect( - fontAwesomeRequests.length, - `expected exactly 1 Font Awesome stylesheet request, got ${fontAwesomeRequests.length}: ${fontAwesomeRequests.join(", ")} (ACCELERATE-004)`, - ).toBe(1); + // fa-user is solid (900); fa-calendar-o only exists through the v4 shim, as regular (400). + const meta = page.locator(".entry-meta").first(); + test.skip(!(await meta.count()), "no post on the homepage to carry the meta icons"); + for (const icon of ["fa-user", "fa-calendar-o"]) { + const el = meta.locator(`i.fa.${icon}`); + await expect(el, `${icon} is missing from the post meta`).toHaveCount(1); + const rendered = await el.evaluate(async (e) => { + await document.fonts.ready; + const cs = getComputedStyle(e, "::before"); + const glyph = cs.content.replace(/^["']|["']$/g, ""); + return { glyph, family: cs.fontFamily, loaded: glyph !== "" && glyph !== "none" && document.fonts.check(`${cs.fontWeight} 16px ${cs.fontFamily}`, glyph) }; + }); + expect(rendered.family, `${icon} font family`).toContain("Font Awesome 6 Free"); + expect(rendered.loaded, `${icon} glyph "${rendered.glyph}" has no loaded font face`).toBe(true); + } }); From d62f3f35c249397270fc4e7cd1e3994c7b63d6d9 Mon Sep 17 00:00:00 2001 From: rg755421 Date: Thu, 1 Oct 2026 10:04:36 +0545 Subject: [PATCH 3/3] Test - Catch duplicate Font Awesome requests and probe icons independent of site content Copilot review: a Set hid a stylesheet requested twice (or both all.css and all.min.css), and the icon check depended on the homepage having a post. Requests are now kept as a list, so a duplicate fails; a v4 solid, regular and brand icon are added to the page and must each load a Font Awesome face, which also covers brands.min.css, one of the removed files. Co-Authored-By: Claude Opus 5.5 (1M context) --- .../font-awesome-single-bundle.spec.ts | 52 ++++++++++++------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/tests/e2e/specs/performance/font-awesome-single-bundle.spec.ts b/tests/e2e/specs/performance/font-awesome-single-bundle.spec.ts index 4aee296..1cbf066 100644 --- a/tests/e2e/specs/performance/font-awesome-single-bundle.spec.ts +++ b/tests/e2e/specs/performance/font-awesome-single-bundle.spec.ts @@ -8,37 +8,49 @@ import { test, expect } from "@playwright/test"; * @why inc/functions.php enqueued v4-shims, all, solid, regular and brands on * every page, and `all` already contains every rule and @font-face of the * other three. v4-shims stays: the theme's markup uses v4 class names - * (`fa fa-*`) that only the shim maps, so the target is exactly two, not - * one. Asserts `all` + the shim (minified or, with SCRIPT_DEBUG, not), and - * that a solid and a regular v4 icon in the post meta still render from a - * loaded Font Awesome face. + * (`fa fa-*`) that only the shim maps, so the target is two, not one. + * Asserts each of `all` and the shim is requested exactly once (minified + * or, with SCRIPT_DEBUG, not), and that a v4 solid, regular and brand icon + * still resolve to a loaded Font Awesome face. The probe icons are added to + * the page, so this does not depend on what content the site has. */ test("Font Awesome loads only the full bundle and the v4 shim, and icons still render @assets @performance @fresh", async ({ page, }) => { - const requested = new Set(); + const requested: string[] = []; page.on("request", (req) => { const m = req.url().match(/\/fontawesome\/css\/([a-z0-9-]+?)(?:\.min)?\.css/); - if (m) requested.add(m[1]); + if (m) requested.push(m[1]); }); await page.goto("/"); await page.waitForLoadState("networkidle"); - expect([...requested].sort(), "Font Awesome stylesheets requested").toEqual(["all", "v4-shims"]); + // An array, not a Set: the same file requested twice must fail too. + expect(requested.sort(), "Font Awesome stylesheets requested").toEqual(["all", "v4-shims"]); - // fa-user is solid (900); fa-calendar-o only exists through the v4 shim, as regular (400). - const meta = page.locator(".entry-meta").first(); - test.skip(!(await meta.count()), "no post on the homepage to carry the meta icons"); - for (const icon of ["fa-user", "fa-calendar-o"]) { - const el = meta.locator(`i.fa.${icon}`); - await expect(el, `${icon} is missing from the post meta`).toHaveCount(1); - const rendered = await el.evaluate(async (e) => { - await document.fonts.ready; - const cs = getComputedStyle(e, "::before"); + // One v4 class name per style the removed stylesheets used to cover. + const probes = { "fa-user": "Font Awesome 6 Free", "fa-calendar-o": "Font Awesome 6 Free", "fa-facebook": "Font Awesome 6 Brands" }; + for (const [icon, family] of Object.entries(probes)) { + const rendered = await page.evaluate(async (cls) => { + const el = document.createElement("i"); + el.className = `fa ${cls}`; + document.body.append(el); + const cs = getComputedStyle(el, "::before"); const glyph = cs.content.replace(/^["']|["']$/g, ""); - return { glyph, family: cs.fontFamily, loaded: glyph !== "" && glyph !== "none" && document.fonts.check(`${cs.fontWeight} 16px ${cs.fontFamily}`, glyph) }; - }); - expect(rendered.family, `${icon} font family`).toContain("Font Awesome 6 Free"); - expect(rendered.loaded, `${icon} glyph "${rendered.glyph}" has no loaded font face`).toBe(true); + // Read now: the computed style is live and empties once the element is removed. + const family = cs.fontFamily; + const font = `${cs.fontWeight} 16px ${family}`; + let faces: string[] = []; + try { + if (glyph && glyph !== "none") faces = (await document.fonts.load(font, glyph)).map((f) => f.family); + } catch { + faces = []; + } + el.remove(); + return { glyph, family, faces }; + }, icon); + expect(rendered.glyph, `${icon} has no glyph`).not.toMatch(/^(none)?$/); + expect(rendered.family, `${icon} font family`).toContain(family); + expect(rendered.faces.length, `${icon} glyph has no loaded font face`).toBeGreaterThan(0); } });