Forced reflow flag in google page speed fix

Maybe foe the next release?

The error:

A forced reflow occurs when JavaScript queries geometric properties (such as offsetWidth) after styles have been invalidated by a change to the DOM state. This can result in poor performance. Learn more about forced reflows and possible mitigations.Unscored
Top function call
Total reflow time
…site/cs-classic.7.8.8.js?ver=7.8.8:2:36526(ohlalab.com.mx)

What’s causing the forced reflow

Forced reflow happens when JS reads layout properties ( offsetWidth , offsetHeight , getBoundingClientRect ) immediately after writing to the DOM/styles, forcing the browser to recalculate layout mid-script. The file has three main offenders :

1. getOuterHeight function (likely near character 36526):

// Writes styles...t.style.display = "block"t.style.position = "absolute"t.style.visibility = "hidden"// Then immediately reads layout → FORCED REFLOWMath.max(0, e, t.scrollHeight, t.offsetHeight)

2. inner-wrap behavior:

r.append(i)i.offsetHeight  // reads layout right after DOM mutation → FORCED REFLOW

(This is intentional — it flushes styles before removing a class to trigger CSS transitions.)

3. lockMotion function:

t.style.setProperty("transition", "none", "important")t.offsetHeight  // intentional flush to force style recalc

the getOuterHeight / inner-wrap functions are the culprits. The fix needs to come from them by batching DOM reads before writes.

I took the liberty of fixing this using claude code (sorry :S) on my own site

Fix Location Change
getOuterHeight char ~11055 Removed pre-write layout read; single cssText write then one read
inner-wrap char ~47128 Replaced i.offsetHeight flush with requestAnimationFrame
lockMotion char ~30183 Replaced t.offsetHeight flush with requestAnimationFrame
iteration 1: getBoundingClientRect() → style.setProperty()  ← reflowiteration 2: getBoundingClientRect() → style.setProperty()  ← reflow againiteration 3: ...repeat

The fix — two separate passes:

pass 1: collect ALL getBoundingClientRect() results  ← one read batchpass 2: apply ALL style.setProperty() calls          ← one write batch

This is the intersect/parallax scroll animation — the one that sets CSS custom property values

Fix Location What it was
Collapse open ~60966 Same accordion animation pattern as x.js — also embedded in cs-classic
Collapse close ~61151 Same accordion close pattern
Opacity flush ~84685 offsetHeight used to flush opacity:0 style before removing it (animation trick)

and in x.js:

Fix Location What it did
Collapse open animation char ~2721 Flushed class changes before setting height — replaced with requestAnimationFrame
Collapse close animation char ~2904 Flushed height before animating to 0 — replaced with requestAnimationFrame
Ot / lockMotion char ~19802 Same flush trick as cs-classic.js — replaced with requestAnimationFrame

And it has significantly helped things in google, from 99ms → 58ms → 24ms → 8ms of forced reflow time across these fixes. That’s a 92% reduction