3.19 Avoid preloading fonts that has color transparent
Is your feature request related to a problem? Please describe. Currently, we preload transparent color font, we shouldn't.
Describe the solution you'd like Avoid preloading transparent fonts
Additional context
- Slack discussion https://group-onecom.slack.com/archives/C08F4LZB2QG/p1748606239118999
- Test page https://new.rocketlabsqa.ovh/preloadfonts_withinvisiblefonts, used markup
.transparent-display-custom {
font-family: 'CustomFont2';
color: transparent; /* Makes the text invisible */
}
Acceptance Criteria
- This exclusion applies exclusively to preloaded fonts
- If any of these property patterns are detected on an element eligible for font preloading, the element should be excluded:
- color: transparent;
- color: rgba(#, #, #, 0); (any combination with the last parameter = 0)
- color: hsla(#, #, #, 0); (any combination with the last parameter = 0)
- color: #$$$$$$00; (the last 2 digit for 8-digit hex colors = 00)
- filter: opacity(0);
We need to cover all text transparency properties:
color: transparent;
color: rgba(#, #, #, 0);
color: hsla(#, #, #, 0);
color: #$$$$$$00;
And:
filter: opacity(0);
Details here In particular, those new exclusions should be for Preloaded fonts only, not other beacon features.
Added acceptance criteria.
We need to update AC to handle cases like zero width zero height + invisible https://group-onecom.slack.com/archives/C08F4LZB2QG/p1749036177043369
Scope a solution
⚠ This has nothing to do with WP Rocket in terms of codebase. But more likely the rocket-scripts.
In the BeaconPreloadFonts class, we currently have a function isElementVisible, which we could modify to handle these new cases. Here is the proposed modification:
isElementVisible(element) {
const style = window.getComputedStyle(element);
const rect = element.getBoundingClientRect();
// Exclude elements with transparent text properties
if (this.hasTransparentText(element)) {
return false;
}
return !(style.display === 'none' ||
style.visibility === 'hidden' ||
style.opacity === '0' ||
rect.width === 0 ||
rect.height === 0);
}
/**
* Checks if an element has transparent text properties.
*
* This method checks for specific CSS properties that make text invisible,
* such as `color: transparent`, `color: rgba(..., 0)`, `color: hsla(..., 0)`,
* `color: #...00` (8-digit hex with alpha = 0), and `filter: opacity(0)`.
*
* @param {Element} element - The element to check.
* @returns {boolean} True if the element has transparent text properties, false otherwise.
*/
hasTransparentText(element) {
const style = window.getComputedStyle(element);
// Check for `color: transparent`
if (style.color === 'transparent') {
return true;
}
// Check for `color: rgba(..., 0)`
const rgbaMatch = style.color.match(/rgba\(\d+, \d+, \d+, 0\)/);
if (rgbaMatch) {
return true;
}
// Check for `color: hsla(..., 0)`
const hslaMatch = style.color.match(/hsla\(\d+, \d+%, \d+%, 0\)/);
if (hslaMatch) {
return true;
}
// Check for `color: #...00` (8-digit hex with alpha = 0)
const hexMatch = style.color.match(/#[0-9a-fA-F]{6}00/);
if (hexMatch) {
return true;
}
// Check for `filter: opacity(0)`
if (style.filter.includes('opacity(0)')) {
return true;
}
return false;
}
Efforts
S
LGTM
Related Test Plan: https://wpmediaqa.testrail.io/index.php?/runs/view/1047
this has been reviewed by @jeawhanlee , I'll send it to in progress until we create a pull request with ported changes here in WPR repo.