- Shipped
- August 19, 2026 at 7:59 PM UTC
- Author
- Kamo
- Commit
- 525e81c
LCP was 4.4 s, and its breakdown said where: 120 ms to first byte, 290 ms of load delay, 390 ms actually downloading the image — and then 1,810 ms of "element render delay". The picture had finished arriving and simply could not be painted. The homepage ships 1,482 DOM elements, over the threshold Lighthouse fails "optimize DOM size" at, and every one of them was being laid out and painted during the initial render, while the LCP element waited its turn behind eight sections nobody had scrolled to. `content-visibility: auto` on every section except `#home` lets the browser skip layout and paint for those subtrees until they approach the viewport. The elements still exist — in the HTML, to search engines, to in-page anchors, to find-in-page, and to the IntersectionObserver JumpToBar runs — they are just not rasterised before anyone can see them. Two things make it safe here rather than generally: every section is already `position: relative` and `overflow: hidden`, so the implied containment changes nothing about how their absolutely positioned backgrounds resolve, and `contain-intrinsic-size` uses the `auto` keyword, so the placeholder height only applies before a section's first render and the browser remembers the real one after. The forced reflow the report attributed to a specific file was PreviewBanner. It read `offsetHeight` right after hydration and wrote `document.body.style .paddingTop`, which invalidates layout for the entire document. The write was also redundant — `body { padding-top: var(--banner-h) }` already reserves the space from first paint. A ResizeObserver reports the height from `borderBoxSize`, which the browser has already computed when the callback runs, so nothing is forced. borderBoxSize rather than contentRect on purpose: the banner carries `padding: 6px 16px` on small screens, and reserving the content height alone would leave the copy sitting 12px under the banner. theme.kamocrm.com gets its preconnect back, which the report asks for by name at 300 ms of LCP. Demoting it to dns-prefetch was wrong: the images do go through this origin's optimizer now, but DynamicMetaLoader still fetches the org's theme stylesheet from that host at runtime, and that is a render-affecting request on the critical path. Analytics stays a dns-prefetch — the tracker is lazyOnload, so nothing before the load event touches it. The hero background drops to quality 40: 21.9 KB to 12.8 KB, which is what the image audit was asking for. Measured through the brightness(0.21) it is composited at, 50 -> 40 moves 1.09% of pixels by more than 8/255 and holds 40.7 dB. Quality 30 was tried and rejected at 3.20%. The section backdrops stay at 75, and this is the second time measurement has said so. At the reduced width they now request, dropping to 50 is *worse* than it was at full width — 11.30% of pixels shift versus 6.60% — because at lower resolution each compression block covers more of what you see. Resolution and quality reductions do not stack on a photograph; one or the other. The HLS playlists are immutable for a year now, live and in the job manifest, which closes the last cache-lifetime item. That moves a cost rather than removing it, so `HERO_HLS_SRC` carries a `?v=` that has to be bumped on a re-encode; both files say so, because otherwise a re-encode will look like the job silently did nothing.