Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- CLS Improvement Recommendations.
- Background: CLS score is currently at 71% (Poor). Detailed analysis confirmed that the degradation occurs specifically in the Android WebView environment — primarily traffic coming from the Facebook in-app browser. Chrome, Safari, and Opera are unaffected because their browsers maintain a persistent font cache across sessions. Android WebView runs in an isolated process with no access to that shared cache, meaning Google Fonts are fetched from the network on every single visit. Combined with render-blocking scripts that delay font requests, users consistently see layout shifts before fonts arrive.
- Two root causes were identified and confirmed via PerformanceObserver measurement.
- Fix 1 — Self-host web fonts with font-display: swap (Highest Priority)
- Why: Google Fonts are loaded from fonts.googleapis.com and fonts.gstatic.com. In Chrome and Safari these are cached between sessions and load instantly. In Android WebView (Facebook in-app browser) this cache doesn't exist - every page view requires a full round-trip to Google's servers: DNS resolution → connection → CSS fetch → a second round-trip for the actual .woff2 files. By the time fonts arrive, the page is already visible to the user with a system fallback font. When the web fonts swap in, the H1 headline changes from 3 lines to 2 lines, causing a ~20px layout shift (CLS value: 0.014 — this is 82% of the total measured CLS).
- What to do: Download and self-host the following font families currently loaded from Google Fonts:
- PT Sans — weights: 400, 400italic, 700italic, 700
- Lato — weights: 300, 400, 700, 900
- Ubuntu — weights: 300, 400, 500, 700
- Tools for generating self-hosted packages: google-webfonts-helper.herokuapp.com or fontsource.org.
- Place the .woff2 files on the same domain (e.g. /fonts/) and declare each @font-face with font-display: swap. Example for Lato Bold:
- @font-face {
- font-family: 'Lato';
- font-style: normal;
- font-weight: 700;
- font-display: swap;
- src: url('/fonts/lato-700.woff2') format('woff2');
- }
- Remove the existing <link> to fonts.googleapis.com from the <head> once self-hosting is in place.
- Optional but recommended — add a metric-compatible fallback font using size-adjust so that the layout does not shift even when the web font is not yet loaded:
- @font-face {
- font-family: 'Lato-fallback';
- src: local('Roboto'), local('Arial');
- font-weight: 700;
- size-adjust: 97%;
- ascent-override: 99%;
- descent-override: 22%;
- }
- Then in the heading CSS: font-family: 'Lato', 'Lato-fallback', sans-serif; — this makes the fallback and the web font occupy the same height, so the swap produces zero layout shift.
- Fix 2 — Add font-display: swap to FontAwesome (Medium Priority)
- Why: The self-hosted FontAwesome font (fontawesome-webfont.woff) loads at ~3890ms with no font-display declaration, which defaults to block behavior. This causes icons to be invisible until the font arrives and may contribute to secondary layout shifts.
- What to do: Locate the @font-face declaration for FontAwesome in the site's CSS (file: css_JkdeNoJmSZ4d_...css) and add font-display: swap:
- @font-face {
- font-family: 'FontAwesome';
- font-display: swap; /* add this line */
- src: url('...fontawesome-webfont.woff2') format('woff2'),
- url('...fontawesome-webfont.woff') format('woff');
- }
- Fix 3 — Eliminate render-blocking JavaScript (Medium Priority)
- Why: There are currently 8 render-blocking tasks loaded in <head> without async or defer. These scripts hold up the browser's HTML parser and delay the discovery and loading of web fonts. The total blocking time measured is up to ~464ms per script. In a fast browser on a good connection this is tolerable; in Android WebView on a mobile network it directly extends the FOUT window and worsens CLS.
- The following scripts are blocking the main thread on every page load:
- File: Block duration
- jquery.min.js (http://ajax.googleapis.com/)
- ~365ms
- bootstrap.min.js (http://cdn.jsdelivr.net/)
- ~464ms
- js_aczm2rRgH_...Co.js (http://novagente.pt/)
- ~342ms
- js_Xk8TsyNfILci...O4.js (http://novagente.pt/)
- ~350ms
- js_6uMVSUgDf9l...U.js (http://novagente.pt/)
- ~353ms
- js_HMpo5_qEBJg...g.js (http://novagente.pt/)
- ~353ms
- js_9AO-H4BaoI7...o.js (http://novagente.pt/)
- ~362ms
- js_oYVKp-cluFZ...w.js (http://novagente.pt/)
- ~418ms
- What to do: These scripts need to be loaded non-blocking. Add async or defer to each of them — the appropriate attribute depends on whether each script has dependencies on others (your developer will know which applies in each case). This change needs to be evaluated carefully to avoid breaking functionality, but the goal is straightforward: none of these scripts should be blocking the main thread during initial page render.
- Expected outcome: Fixes 1 and 2 together directly eliminate the two confirmed CLS sources (FOUT on Lato and PT Sans), which account for 100% of the measured layout shifts. Fix 3 reduces the FOUT window as a complementary measure. Combined, these changes should move the CLS score from 71% to 80%+ for the Android WebView segment.
Advertisement