From bb33626f3806fbde5ecdfb3e65e99669c99eae71 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 30 Sep 2026 08:16:19 +0300 Subject: [PATCH] ci(perf): the interaction first-frame ceiling sits above the 1.78 level (#692) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The full workflow's 7-sample median of firstStableRenderMs for large-house-interaction-v1 was about 2790 ms across the 1.77 line and about 2920 ms at v1.78.0 (7d4d75bd: 2925.0; the neighbouring run of the same SHA read 3144.8). The 3000 ms ceiling sat 2.7 % above the level and failed on runner noise; #689's 3-sample smoke read 3002.4. - hardMaxMs 3000 → 3400 in the full profile and its smoke twin (one number, #473 AC4): +16 % over the 1.78 level, +8 % over the worst run. The base-relative ratio and noise allowance are unchanged. - README: the series and the reasoning; the test pins the number and the series points. Issue: #692 User-Visible: no Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd --- demo/performance/README.md | 11 +++++++++++ .../performance/budgets-interaction-smoke.json | 2 +- .../budgets-large-house-interaction.json | 2 +- test/performance-budget.test.mjs | 18 ++++++++++++++++++ 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/demo/performance/README.md b/demo/performance/README.md index 0b93832a..c2a0f271 100644 --- a/demo/performance/README.md +++ b/demo/performance/README.md @@ -99,6 +99,17 @@ still below the known failed pre-optimization result (3501.5 ms). This aggregate is a catastrophic guard; the full workflow's base-relative comparison remains the detector for smaller regressions. +Its `firstStableRenderMs` ceiling is 3400 ms (#692). The full workflow's +7-sample median on the hosted runner was about 2790 ms across the 1.77 line +(2769.0 on 09-21, 2838.2 on 09-23, 2777.3 and 2801.7 on `c392ad3a`) and about +2920 ms at v1.78.0 (`7d4d75bd`: 2925.0, 2925.2 as the base). Two runs of that +one SHA differed by 7.5 % (3144.8 vs 2925.0), so the former 3000 ms ceiling +sat 2.7 % above the level and failed on noise — the 3-sample smoke of #689 +read 3002.4 ms. 3400 ms is +16 % over the 1.78 level and +8 % over the worst +run in the series; the base-relative comparison of the full workflow is +unchanged and remains the detector for smaller regressions. The +4.5 % step +between 1.77 and 1.78.0 is not attributed here. + The isometric `spaceSwitchMs` ceiling is 2200 ms, shared by the smoke, the full isometric profile and its Stage 3 dense twin (#675). The metric is one cold floor switch that builds the second floor's 2.5D geometry, so it grows with diff --git a/demo/performance/budgets-interaction-smoke.json b/demo/performance/budgets-interaction-smoke.json index cdcc7aff..0ae8e069 100644 --- a/demo/performance/budgets-interaction-smoke.json +++ b/demo/performance/budgets-interaction-smoke.json @@ -9,7 +9,7 @@ }, "firstStableRenderMs": { "stat": "median", - "hardMaxMs": 3000 + "hardMaxMs": 3400 }, "interactionSeriesMs": { "stat": "median", diff --git a/demo/performance/budgets-large-house-interaction.json b/demo/performance/budgets-large-house-interaction.json index 9b85f748..929f985d 100644 --- a/demo/performance/budgets-large-house-interaction.json +++ b/demo/performance/budgets-large-house-interaction.json @@ -13,7 +13,7 @@ "stat": "median", "maxRegressionRatio": 0.3, "noiseAllowanceMs": 250, - "hardMaxMs": 3000 + "hardMaxMs": 3400 }, "interactionSeriesMs": { "stat": "median", diff --git a/test/performance-budget.test.mjs b/test/performance-budget.test.mjs index d44b6b50..4229e823 100644 --- a/test/performance-budget.test.mjs +++ b/test/performance-budget.test.mjs @@ -251,6 +251,24 @@ for (const [smokeName, fullName] of [ }); } +test('#692 первый стабильный кадр interaction: потолок над уровнем 1.78 с запасом на шум раннера', () => { + const smoke = readBudget('budgets-interaction-smoke.json'); + const full = readBudget('budgets-large-house-interaction.json'); + const ceiling = full.timings.firstStableRenderMs.hardMaxMs; + assert.equal(ceiling, 3400); + assert.equal(smoke.timings.firstStableRenderMs.hardMaxMs, ceiling, 'смок = полный профиль (#473 AC4)'); + // Медианы полного профиля (7 образцов) из performance.yml: линия 1.77 и v1.78.0. + const level177 = [2769.0, 2838.2, 2777.3, 2801.7]; + const level178 = [2925.0, 2925.2]; + const worst = 3144.8; // тот же SHA v1.78.0, соседний прогон — шум раннера до 7,5 % + for (const median of [...level177, ...level178, worst]) assert.ok(median < ceiling, `${median} краснеет на ${ceiling}`); + assert.ok(ceiling >= Math.max(...level178) * 1.15, 'запас над уровнем 1.78 не меньше 15 %'); + assert.ok(ceiling <= Math.max(...level178) * 1.2, 'и не больше 20 %: потолок остаётся гардом'); + // Относительное сравнение полного профиля не ослаблено. + assert.equal(full.timings.firstStableRenderMs.maxRegressionRatio, 0.3); + assert.equal(full.timings.firstStableRenderMs.noiseAllowanceMs, 250); +}); + test('interaction aggregate keeps hosted-runner headroom without weakening component gates (#483)', () => { const smoke = readBudget('budgets-interaction-smoke.json'); const full = readBudget('budgets-large-house-interaction.json');