From 2f5e0ad75f495db164ec7049afee04d309995194 Mon Sep 17 00:00:00 2001 From: Peter Hedenskog Date: Tue, 12 May 2026 14:31:03 +0200 Subject: [PATCH] Surface style recalculation work in the page-x-ray diff MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sitespeed.io / browsertime HARs include the count of elements the browser re-styled and the time it spent doing so before FCP and LCP — a real lever for regression hunting that today doesn't show up anywhere in compare. Render the four numbers under the existing Render blocking section so a slow paint caused by an exploding style scope is one glance away from the rest of the metric deltas. Depends on the pagexray release that adds renderBlocking.recalculateStyle; the bundled pagexray.min.js will be bumped in a follow-up once that release ships. Co-authored-by: Claude Opus 4.7 (1M context) noreply@anthropic.com --- public/js/compare/templates.js | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/public/js/compare/templates.js b/public/js/compare/templates.js index 7cbf715..daf9601 100644 --- a/public/js/compare/templates.js +++ b/public/js/compare/templates.js @@ -232,6 +232,35 @@ function pageXrayTemplate(d) { '' + p1.renderBlocking.in_body_parser_blocking + '' + '' + p2.renderBlocking.in_body_parser_blocking + '' + diffCell(p1.renderBlocking.in_body_parser_blocking, p2.renderBlocking.in_body_parser_blocking) + ''; + + // Style recalculation before FCP / LCP. Sitespeed.io / browsertime + // captures how many elements the browser re-styled and how long it + // took on its way to each paint milestone — both are "lower is + // better", so the existing diff colouring applies. Guarded so a + // plain Chrome HAR (no recalculateStyle) doesn't render four empty + // rows. + const rs1 = p1.renderBlocking.recalculateStyle; + const rs2 = p2.renderBlocking.recalculateStyle; + if (rs1 && rs2) { + function recalcRow(label, a, b, formatter) { + return '' + h(label) + '' + + '' + (formatter ? formatter(a) : a) + '' + + '' + (formatter ? formatter(b) : b) + '' + + diffCell(a, b, formatter) + ''; + } + if (rs1.beforeFCP && rs2.beforeFCP) { + html += recalcRow('Style recalc elements (before FCP)', + rs1.beforeFCP.elements, rs2.beforeFCP.elements); + html += recalcRow('Style recalc duration (before FCP)', + rs1.beforeFCP.durationInMillis, rs2.beforeFCP.durationInMillis, formatTime); + } + if (rs1.beforeLCP && rs2.beforeLCP) { + html += recalcRow('Style recalc elements (before LCP)', + rs1.beforeLCP.elements, rs2.beforeLCP.elements); + html += recalcRow('Style recalc duration (before LCP)', + rs1.beforeLCP.durationInMillis, rs2.beforeLCP.durationInMillis, formatTime); + } + } } if (p1.visualMetrics) {