diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2de42af9a..f6b94add1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,6 +10,28 @@ concurrency: cancel-in-progress: true jobs: + docs_compatibility: + name: test (docs compatibility browser contracts) + runs-on: ubuntu-24.04 + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v4 + with: + version: 11.1.3 + - uses: actions/setup-node@v4 + with: + node-version-file: .node-version + cache: pnpm + - run: pnpm install --frozen-lockfile + - run: pnpm --dir docs install --frozen-lockfile + - run: pnpm exec playwright install --with-deps chromium + - name: Docs and stable browser work ceilings + working-directory: docs + env: + NEXT_DIST_DIR: .next-check + run: pnpm check + native_macos: name: build (macOS arm64 native packages) runs-on: macos-15 @@ -599,13 +621,14 @@ jobs: # Retain the pre-matrix "test" check for branch protection and badges. It # passes only when every matrix shard and independent integration job does. test: - needs: [tests, bootstrap, linux_host_clang, ts7_parity, llvm_artifacts_linux_x64, llvm_artifacts_macos_arm64, llvm_artifacts_macos_x64, windows_cli, llvm_artifacts_windows_x64] + needs: [docs_compatibility, tests, bootstrap, linux_host_clang, ts7_parity, llvm_artifacts_linux_x64, llvm_artifacts_macos_arm64, llvm_artifacts_macos_x64, windows_cli, llvm_artifacts_windows_x64] # A superseded run must release its concurrency slot immediately. if: ${{ !cancelled() }} runs-on: ubuntu-latest steps: - name: All lanes green run: | + test "${{ needs.docs_compatibility.result }}" = success test "${{ needs.tests.result }}" = success test "${{ needs.bootstrap.result }}" = success test "${{ needs.linux_host_clang.result }}" = success diff --git a/docs/package.json b/docs/package.json index b7ad3426a..361b663d5 100644 --- a/docs/package.json +++ b/docs/package.json @@ -10,7 +10,9 @@ "start": "next start", "typecheck": "tsc --noEmit", "compat:check": "pnpm --dir .. node-compat:check", - "check": "pnpm compat:check && pnpm typecheck && pnpm build" + "test:compatibility": "pnpm --dir .. exec playwright test --config docs/playwright.config.ts", + "bench:compatibility": "SCRIPTC_DOCS_BENCH=1 pnpm test:compatibility", + "check": "pnpm compat:check && pnpm typecheck && pnpm build && pnpm test:compatibility" }, "dependencies": { "@mdx-js/loader": "^3", diff --git a/docs/playwright.config.ts b/docs/playwright.config.ts new file mode 100644 index 000000000..c16d40940 --- /dev/null +++ b/docs/playwright.config.ts @@ -0,0 +1,23 @@ +import { defineConfig } from "@playwright/test"; + +const url = process.env.SCRIPTC_DOCS_URL ?? "http://127.0.0.1:3108"; + +export default defineConfig({ + testDir: "../tests/browser", + testMatch: process.env.SCRIPTC_DOCS_BENCH === "1" ? "compatibility.bench.ts" : "compatibility.test.ts", + outputDir: "node_modules/.cache/compatibility-browser", + workers: 1, + retries: 0, + reporter: "line", + use: { + baseURL: url, + viewport: { width: 1440, height: 1000 }, + launchOptions: process.env.SCRIPTC_BROWSER_PATH ? { executablePath: process.env.SCRIPTC_BROWSER_PATH } : {}, + }, + webServer: process.env.SCRIPTC_DOCS_URL ? undefined : { + command: "node node_modules/next/dist/bin/next start --port 3108", + url, + reuseExistingServer: false, + timeout: 30_000, + }, +}); diff --git a/docs/src/components/node-compatibility-matrix.tsx b/docs/src/components/node-compatibility-matrix.tsx index 2720fb560..d51e762ab 100644 --- a/docs/src/components/node-compatibility-matrix.tsx +++ b/docs/src/components/node-compatibility-matrix.tsx @@ -4,7 +4,7 @@ // empty after an edit. // @refresh reset -import { useEffect, useMemo, useState } from "react"; +import { memo, useEffect, useMemo, useState } from "react"; import compatibilityMeta from "@/generated/node-v24-compatibility-meta.json"; type Status = @@ -76,17 +76,19 @@ const stabilityStyles: Record = { 3: "border-gray-alpha-500 bg-gray-alpha-100 text-gray-900", }; -function StatusBadge({ status, detail, verification }: { status: Status; detail?: string; verification?: Verification }) { +const StatusBadge = memo(function StatusBadge({ status, detail, verification }: { status: Status; detail?: string; verification?: Verification }) { + const [hovered, setHovered] = useState(false); + const [focused, setFocused] = useState(false); const tooltip = verification ? `${detail ?? ""}${detail ? "\n\n" : ""}Verification: ${verification.label}. ${verification.detail}` : detail; return ( - + setHovered(true)} onMouseLeave={() => setHovered(false)} onFocus={() => setFocused(true)} onBlur={() => setFocused(false)}> {labels[status]} - {tooltip ? ( + {tooltip && (hovered || focused) ? ( {detail ? {detail} : null} {verification ? Verification: {verification.label}. {verification.detail} : null} @@ -94,22 +96,26 @@ function StatusBadge({ status, detail, verification }: { status: Status; detail? ) : null} ); -} +}); -function StabilityBadge({ stability }: { stability: NodeStability }) { +const StabilityBadge = memo(function StabilityBadge({ stability }: { stability: NodeStability }) { + const [hovered, setHovered] = useState(false); + const [focused, setFocused] = useState(false); if (stability === null) return —; const detail = `Node.js Stability ${stability.index}: ${stability.text}${stability.inherited ? " (inherited from the nearest parent section)" : ""}`; return ( - + setHovered(true)} onMouseLeave={() => setHovered(false)} onFocus={() => setFocused(true)} onBlur={() => setFocused(false)}> {stability.index} - - {detail} - + {(hovered || focused) ? ( + + {detail} + + ) : null} ); -} +}); function statusCounts(rows: Row[], tier: "static" | "dynamic") { return rows.reduce>( diff --git a/internal/performance/compatibility-lookup.md b/internal/performance/compatibility-lookup.md new file mode 100644 index 000000000..b1afb789e --- /dev/null +++ b/internal/performance/compatibility-lookup.md @@ -0,0 +1,64 @@ +# Compatibility lookup: hill-climbing record + +## Scope and checkpoints + +This is a lab-only optimization of the compatibility-assessment journey: open `/compatibility`, type an API name, and inspect its static/dynamic status and verification details. Returning developers plausibly repeat this lookup, but there is no goal-attempt usage data; neither its frequency nor its share of user activity is established. Screening found multi-second browser stalls during ordinary search prefixes, so the hill is browser rendering rather than compiler execution or server throughput. + +The target is a reduction in input-to-usable-result latency greater than measurement noise, with all results, independent tier filters, expansion, hover details, keyboard access, and table geometry preserved. The user supplied no time limit. The work budget stayed within one coherent journey: three bottleneck experiments, two retained changes, a complete-journey before/after comparison, and correctness/regression gates. The retained scope includes no deployment, compatibility-status changes, pagination, or virtualization. + +## Workload and measurement + +The baseline is commit `2069684`, using the generated Node 24.15.0 public census: 3,662 rows. Production Next.js builds ran on an Apple M3 arm64 host, Darwin 25.6.0, Node 24.15.0, with Chrome for Testing 154.0.8037.57 and a 1440×1000 viewport. Each phase has nine attempts, measured separately at normal CPU speed and Chromium's 4× CPU throttle. The throttle is a constrained-CPU simulation, not a measurement on a physical phone. OS caches were not flushed and no network throttle was applied. + +The browser captures the actual input/click event and records completion after two animation-frame callbacks, allowing a paint opportunity. This is a browser-side usable-result proxy, not a physical display measurement. The complete lookup types `readFile` sequentially without an added typing delay and measures from its first input to the final matching result. Automation scheduling between keystrokes remains in that journey interval. Untimed assertions compare every displayed label against an independent oracle over the published census, so omitting or showing stale results cannot masquerade as a speedup. + +The server delivers prebuilt HTML and the unchanged static census. Navigation/data Resource Timing is saved separately from input/render samples; these local response intervals include transport and are not pure server CPU measurements. There are no server-code changes or claimed network gains. The result checks, screenshots, and V8 render-count instrumentation run outside latency measurements. A run contending with orphaned native-test workers was discarded; the retained matched runs were isolated from those workers. + +## Complete-journey results + +| CPU profile | Sequential `readFile` p50 before → after | Sample p95 before → after | p50 reduction | +| --- | --- | --- | --- | +| Normal | 1,087.7 → 514.2 ms | 1,491.0 → 556.9 ms | 52.7% | +| 4× throttle | 3,799.8 → 1,972.4 ms | 4,644.6 → 2,101.2 ms | 48.1% | + +With nine attempts, the reported nearest-rank sample p95 is the maximum sample; it is not a population p95 estimate. The final broad `r` prefix is 357.0 ms p50 normally and 1,351.4 ms at 4× throttle. Expanding the entire census is 307.8 and 1,274.7 ms respectively. Exact samples, environment, resource timings, and each experiment's before/after evidence are in [results.json](./compatibility-lookup/results.json). + +## Experiments and counter validation + +1. **Retained: mount tooltip content only while a badge is hovered or focused.** Expanded-table elements fell from 90,922 to 58,649 with all 3,662 rows retained. In the matched first experiment, the broad-prefix p50 fell from 643.5 to 304.3 ms normally and from 3,014.7 to 1,396.2 ms at 4× throttle. Reduced DOM work therefore accompanied a substantial wall-clock reduction on the same workload; the element count was not adopted merely because it was easy to count. +2. **Retained: memoize unchanged status and stability badges.** The `r` → `re` interval previously called the status renderer 6,128 times; it now records zero calls for retained badges. The matched pair reduced that interval's p50 from 93.8 to 82.1 ms normally and from 382.8 to 349.1 ms at 4× throttle. A deterministic 10,000-resample median-difference bootstrap over those nine-sample sets (LCG seed 42, independent resampling of before/after samples) gave positive 95% intervals of approximately 2.7–20.6 and 15.9–67.3 ms. This is supporting lab evidence, not a field guarantee. The production change is two React memo wrappers; no custom comparator or cache invalidation policy was added. +3. **Rejected: CSS `content-visibility` on table rows/cells.** Row containment gave no useful improvement. Cell containment reduced layout work but changed total table height from about 210,587 to 67,864 px in the broad-prefix experiment, changing scroll geometry. That apparent speedup was not retained. + +## Correctness, visuals, and ratchets + +Browser tests were established before optimization: the old implementation failed the no-hidden-tooltip guard and later failed the retained-render ceiling with 6,128 calls. The existing search/filter path passed its independent census comparison before changes. The final four browser contracts cover all-row reachability, search/tier filters/reset, status and stability render counts, full tooltip text, and overlapping pointer/keyboard focus lifetimes. They pass with both the measurement browser and Playwright's bundled Chromium 153.0.8010.12. + +The docs gate now runs these contracts after drift checking, TypeScript checking, and the production build. A required CI job installs Chromium and runs the gate. Stable ceilings are zero tooltip nodes in an inactive expanded matrix, at most `17 × census rows + 500` document elements, and at most 16 retained-renderer calls per badge kind during `r` → `re`. V8 may omit zero-call functions; a subsequent actual hover must produce calls in the same renderer, proving the counter is live. Wall-clock timing remains a benchmark/monitoring result, never a noisy CI assertion. + +Settled tooltip content and table dimensions match before/after on desktop and a 390×844 viewport. The desktop tooltip screenshot is pixel-identical; mobile differs in 92 of 912,600 color channels. The mobile tooltip's clipping is pre-existing and unchanged. Review [desktop before](./compatibility-lookup/before-desktop.png), [desktop after](./compatibility-lookup/after-desktop.png), [mobile before](./compatibility-lookup/before-mobile.png), and [mobile after](./compatibility-lookup/after-mobile.png). These stills do not establish transient animation timing; hover/focus transitions should also be checked during field verification. + +## Reproduce + +Use the repository-pinned Node 24.15.0 and root pnpm 11.1.3 (the docs workspace selects pnpm 10.23.0). Install both workspaces and the test browser: + +```bash +pnpm install --frozen-lockfile +pnpm --dir docs install --frozen-lockfile +pnpm exec playwright install chromium +``` + +From `docs/`, use a separate production output directory so a running development server is not disturbed: + +```bash +NEXT_DIST_DIR=.next-check pnpm check +mkdir -p /tmp/scriptc-hill +NEXT_DIST_DIR=.next-check SCRIPTC_DOCS_RESULT=/tmp/scriptc-hill/journey-after.json pnpm bench:compatibility +``` + +The benchmark normally starts and stops its own production server on port 3108. `SCRIPTC_DOCS_URL` explicitly selects an existing server instead. `SCRIPTC_BROWSER_PATH` selects an installed Chromium executable; set it to the same browser revision as the baseline for timing comparisons. `SCRIPTC_DOCS_ITERATIONS` controls repetitions. Do not compare runs sharing cores with native builds/tests. The browser contracts use the root Playwright dependency, while docs dependencies remain in the standalone workspace. + +## Validation and stopping point + +Workspace build, compatibility drift checking, strict TypeScript checking of the browser tests, and the complete docs gate pass. Sandbox preflight failed because the Vercel session expired. The prescribed local plain/sanitized fallback ran with four workers on `2069684`; it is not green. The plain lane passed 7,267 tests and failed one: Zig COFF dry-run cache conformance (`ENOENT` scanning the cache `bin` directory) after 34.7 s under load. The same test passed in 5.9 s in an isolated one-worker rerun, so it is an undiagnosed intermittent failure. The sanitized lane failed eight tests, all because the sanitizer runtime wrote `No external symbolizers found … Is PATH set?` to stderr where byte-exact stderr was expected. The fork-IPC fixture reproduces this deterministically in isolation: it spawns its child with an environment lacking `PATH`, and the self-hosting cases deliberately run without Node on `PATH`. This patch changes no compiler, runtime, or harness code. Upstream CI's macOS 15 `san` shards passed on the same base commit, so the symbolizer failures are attributed to this Darwin 25.6 host, not to this patch. The branch was then rebased onto `0845c7f`; frozen installs and the complete docs gate pass there. + +The optimization loop stops after the two demonstrated, low-complexity wins. Remaining cost is mounting/layout of thousands of real table rows; a substantially different browsing or virtualization design would need a separate accessibility/UX decision rather than an unmeasured complexity increase. No rollout flag was added for this lifecycle-only patch, and no deployment or push was performed. Field checks remain pending: compare input-to-answer/interaction latency by build, browser, device class, and result cardinality under comparable conditions; verify labels, filtering, keyboard details, scrolling, and tooltip transitions alongside latency; use the authorized deployment/revert process if a regression appears. diff --git a/internal/performance/compatibility-lookup/after-desktop.png b/internal/performance/compatibility-lookup/after-desktop.png new file mode 100644 index 000000000..539c2d098 Binary files /dev/null and b/internal/performance/compatibility-lookup/after-desktop.png differ diff --git a/internal/performance/compatibility-lookup/after-mobile.png b/internal/performance/compatibility-lookup/after-mobile.png new file mode 100644 index 000000000..5a6876691 Binary files /dev/null and b/internal/performance/compatibility-lookup/after-mobile.png differ diff --git a/internal/performance/compatibility-lookup/before-desktop.png b/internal/performance/compatibility-lookup/before-desktop.png new file mode 100644 index 000000000..539c2d098 Binary files /dev/null and b/internal/performance/compatibility-lookup/before-desktop.png differ diff --git a/internal/performance/compatibility-lookup/before-mobile.png b/internal/performance/compatibility-lookup/before-mobile.png new file mode 100644 index 000000000..6cff38074 Binary files /dev/null and b/internal/performance/compatibility-lookup/before-mobile.png differ diff --git a/internal/performance/compatibility-lookup/results.json b/internal/performance/compatibility-lookup/results.json new file mode 100644 index 000000000..5187bbf0c --- /dev/null +++ b/internal/performance/compatibility-lookup/results.json @@ -0,0 +1,3112 @@ +{ + "status": "lab-only; no production deployment or real-user measurements", + "sourceCommit": "2069684", + "window": "single local optimization session", + "workload": "published Node 24.15.0 compatibility census; production Next.js build; local HTTP; nine attempts per phase/CPU profile", + "timing": "browser input capture to two requestAnimationFrame callbacks; sequential readFile typing measured from first input to final result; untimed assertions check every displayed label", + "workCounters": { + "allRows": 3662, + "elementsBefore": 90922, + "elementsAfter": 58649, + "retainedStatusRendersBefore": 6128, + "retainedStatusRendersAfter": 0, + "guard": { + "hiddenTooltips": 0, + "maxElementsPerRow": 17, + "elementAllowance": 500, + "maxRetainedRendererCalls": 16, + "positiveHoverControl": true + } + }, + "experiments": [ + { + "name": "lazy tooltip DOM", + "before": "original", + "after": "lazyTooltips", + "retained": true + }, + { + "name": "memoize unchanged badges", + "before": "beforeMemo", + "after": "afterMemo", + "retained": true + }, + { + "name": "content-visibility on table rows/cells", + "retained": false, + "reason": "rows gave no useful gain; cells reduced layout cost but changed table height and scroll geometry" + } + ], + "visual": { + "desktopTooltipPixelDifferences": 0, + "mobileTooltipDifferentChannels": 92, + "mobileTooltipTotalChannels": 912600, + "tableDimensionsAndTooltipTextEqual": true + }, + "runs": { + "original": { + "environment": { + "node": "v24.15.0", + "browser": "154.0.8037.57", + "platform": "darwin", + "os": "25.6.0", + "arch": "arm64", + "cpu": "Apple M3", + "viewport": { + "width": 1440, + "height": 1000 + }, + "baseURL": "http://localhost:3107", + "censusRows": 3662 + }, + "summaries": [ + { + "throttle": 1, + "phase": "prefix-r", + "n": 9, + "p50_ms": 643.5, + "p95_ms": 674.5, + "elements": 89169, + "rows": 3592 + }, + { + "throttle": 1, + "phase": "readFile", + "n": 9, + "p50_ms": 58.199999928474426, + "p95_ms": 60.89999997615814, + "elements": 301, + "rows": 6 + }, + { + "throttle": 1, + "phase": "clear", + "n": 9, + "p50_ms": 24.40000009536743, + "p95_ms": 29.700000047683716, + "elements": 1617, + "rows": 55 + }, + { + "throttle": 1, + "phase": "expand-all", + "n": 9, + "p50_ms": 584.8999999761581, + "p95_ms": 613.7000000476837, + "elements": 90922, + "rows": 3662 + }, + { + "throttle": 1, + "phase": "collapse-all", + "n": 9, + "p50_ms": 61.700000047683716, + "p95_ms": 63.200000047683716, + "elements": 1617, + "rows": 55 + }, + { + "throttle": 4, + "phase": "prefix-r", + "n": 9, + "p50_ms": 3014.7000000476837, + "p95_ms": 3464.600000023842, + "elements": 89169, + "rows": 3592 + }, + { + "throttle": 4, + "phase": "readFile", + "n": 9, + "p50_ms": 259.7000000476837, + "p95_ms": 313.59999990463257, + "elements": 301, + "rows": 6 + }, + { + "throttle": 4, + "phase": "clear", + "n": 9, + "p50_ms": 49.10000002384186, + "p95_ms": 53.10000002384186, + "elements": 1617, + "rows": 55 + }, + { + "throttle": 4, + "phase": "expand-all", + "n": 9, + "p50_ms": 2401.3000000715256, + "p95_ms": 2446.2000000476837, + "elements": 90922, + "rows": 3662 + }, + { + "throttle": 4, + "phase": "collapse-all", + "n": 9, + "p50_ms": 266.7999999523163, + "p95_ms": 371.7000000476837, + "elements": 1617, + "rows": 55 + } + ], + "samples": { + "1x/prefix-r": { + "rows": 3592, + "elements": 89169, + "ms": [ + 651.6000000238419, + 667.3999999761581, + 614.3000000715256, + 674.5, + 643.5, + 641.5, + 631.7999999523163, + 646.6000000238419, + 621.3000000715256 + ] + }, + "1x/readFile": { + "rows": 6, + "elements": 301, + "ms": [ + 60.10000002384186, + 56.699999928474426, + 58.300000071525574, + 58.199999928474426, + 60.89999997615814, + 60.89999997615814, + 55.60000002384186, + 56.699999928474426, + 56.5 + ] + }, + "1x/clear": { + "rows": 55, + "elements": 1617, + "ms": [ + 17.5, + 29.700000047683716, + 26.399999976158142, + 21.199999928474426, + 26.600000023841858, + 24.40000009536743, + 23, + 25.199999928474426, + 21.899999976158142 + ] + }, + "1x/expand-all": { + "rows": 3662, + "elements": 90922, + "ms": [ + 613.7000000476837, + 563.7000000476837, + 566.7000000476837, + 584.8999999761581, + 587, + 585, + 574.4000000953674, + 595.6000000238419, + 581.8000000715256 + ] + }, + "1x/collapse-all": { + "rows": 55, + "elements": 1617, + "ms": [ + 58.89999997615814, + 62.39999997615814, + 63.200000047683716, + 62.89999997615814, + 59.39999997615814, + 55.10000002384186, + 61.700000047683716, + 59.09999990463257, + 62.699999928474426 + ] + }, + "4x/prefix-r": { + "rows": 3592, + "elements": 89169, + "ms": [ + 2535.7000000476837, + 2856.2000000476837, + 3014.7000000476837, + 3070, + 2671.5999999046326, + 2822.1999999284744, + 3464.600000023842, + 3439.6999999284744, + 3355.4000000953674 + ] + }, + "4x/readFile": { + "rows": 6, + "elements": 301, + "ms": [ + 267.7000000476837, + 253.5, + 253.20000004768372, + 247.89999997615814, + 241.5, + 259.7000000476837, + 299.7999999523163, + 313.59999990463257, + 305.60000002384186 + ] + }, + "4x/clear": { + "rows": 55, + "elements": 1617, + "ms": [ + 51.39999997615814, + 47.60000002384186, + 51.299999952316284, + 52.699999928474426, + 44.39999997615814, + 45.10000002384186, + 46.09999990463257, + 53.10000002384186, + 49.10000002384186 + ] + }, + "4x/expand-all": { + "rows": 3662, + "elements": 90922, + "ms": [ + 2409.399999976158, + 2401.3000000715256, + 2411.8000000715256, + 2314, + 2360.100000023842, + 2417.6999999284744, + 2347.7000000476837, + 2446.2000000476837, + 2373.2000000476837 + ] + }, + "4x/collapse-all": { + "rows": 55, + "elements": 1617, + "ms": [ + 272.39999997615814, + 273.5, + 254.80000007152557, + 239.70000004768372, + 248.5, + 371.7000000476837, + 266.7999999523163, + 308.60000002384186, + 250.80000007152557 + ] + } + }, + "loads": [ + { + "throttle": 1, + "navigation": { + "name": "http://localhost:3107/compatibility", + "entryType": "navigation", + "startTime": 0, + "duration": 63, + "navigationId": 6789, + "initiatorType": "navigation", + "deliveryType": "", + "nextHopProtocol": "http/1.1", + "renderBlockingStatus": "non-blocking", + "contentType": "text/html", + "contentEncoding": "gzip", + "workerStart": 0, + "workerRouterEvaluationStart": 0, + "workerCacheLookupStart": 0, + "workerMatchedSourceType": "", + "workerFinalSourceType": "", + "redirectStart": 0, + "redirectEnd": 0, + "fetchStart": 0.5, + "domainLookupStart": 0.5, + "domainLookupEnd": 0.5, + "connectStart": 0.5, + "secureConnectionStart": 0, + "connectEnd": 0.5, + "requestStart": 1.1999999284744263, + "responseStart": 7.199999928474426, + "firstInterimResponseStart": 0, + "finalResponseHeadersStart": 7.199999928474426, + "responseEnd": 7.599999904632568, + "transferSize": 4976, + "encodedBodySize": 4676, + "decodedBodySize": 20336, + "responseStatus": 200, + "serverTiming": [], + "unloadEventStart": 0, + "unloadEventEnd": 0, + "domInteractive": 32.699999928474426, + "domContentLoadedEventStart": 32.799999952316284, + "domContentLoadedEventEnd": 32.799999952316284, + "domComplete": 63, + "loadEventStart": 63, + "loadEventEnd": 63, + "type": "navigate", + "redirectCount": 0, + "activationStart": 0, + "criticalCHRestart": 0, + "notRestoredReasons": null, + "confidence": { + "randomizedTriggerRate": 0.4994798, + "value": "low" + } + }, + "data": [ + { + "name": "http://localhost:3107/compatibility/data?v=b9e39038b2832f02e54b", + "entryType": "resource", + "startTime": 79.59999990463257, + "duration": 7, + "navigationId": 6789, + "initiatorType": "fetch", + "deliveryType": "", + "nextHopProtocol": "http/1.1", + "renderBlockingStatus": "non-blocking", + "contentType": "application/json", + "contentEncoding": "", + "workerStart": 0, + "workerRouterEvaluationStart": 0, + "workerCacheLookupStart": 0, + "workerMatchedSourceType": "", + "workerFinalSourceType": "", + "redirectStart": 0, + "redirectEnd": 0, + "fetchStart": 79.59999990463257, + "domainLookupStart": 79.59999990463257, + "domainLookupEnd": 79.59999990463257, + "connectStart": 79.59999990463257, + "secureConnectionStart": 0, + "connectEnd": 79.59999990463257, + "requestStart": 79.89999997615814, + "responseStart": 81.39999997615814, + "firstInterimResponseStart": 0, + "finalResponseHeadersStart": 81.39999997615814, + "responseEnd": 86.59999990463257, + "transferSize": 2247670, + "encodedBodySize": 2247370, + "decodedBodySize": 2247370, + "responseStatus": 200, + "serverTiming": [] + } + ] + }, + { + "throttle": 4, + "navigation": { + "name": "http://localhost:3107/compatibility", + "entryType": "navigation", + "startTime": 0, + "duration": 73.39999997615814, + "navigationId": 2543, + "initiatorType": "navigation", + "deliveryType": "cache", + "nextHopProtocol": "", + "renderBlockingStatus": "non-blocking", + "contentType": "text/html", + "contentEncoding": "gzip", + "workerStart": 0, + "workerRouterEvaluationStart": 0, + "workerCacheLookupStart": 0, + "workerMatchedSourceType": "", + "workerFinalSourceType": "", + "redirectStart": 0, + "redirectEnd": 0, + "fetchStart": 0.19999992847442627, + "domainLookupStart": 0.19999992847442627, + "domainLookupEnd": 0.19999992847442627, + "connectStart": 0.19999992847442627, + "secureConnectionStart": 0, + "connectEnd": 0.19999992847442627, + "requestStart": 1.1999999284744263, + "responseStart": 9.600000023841858, + "firstInterimResponseStart": 0, + "finalResponseHeadersStart": 9.600000023841858, + "responseEnd": 9.899999976158142, + "transferSize": 300, + "encodedBodySize": 4676, + "decodedBodySize": 20336, + "responseStatus": 200, + "serverTiming": [], + "unloadEventStart": 14.399999976158142, + "unloadEventEnd": 14.399999976158142, + "domInteractive": 32.699999928474426, + "domContentLoadedEventStart": 32.699999928474426, + "domContentLoadedEventEnd": 32.699999928474426, + "domComplete": 73.39999997615814, + "loadEventStart": 73.39999997615814, + "loadEventEnd": 73.39999997615814, + "type": "navigate", + "redirectCount": 0, + "activationStart": 0, + "criticalCHRestart": 0, + "notRestoredReasons": null, + "confidence": { + "randomizedTriggerRate": 0.4994798, + "value": "high" + } + }, + "data": [ + { + "name": "http://localhost:3107/compatibility/data?v=b9e39038b2832f02e54b", + "entryType": "resource", + "startTime": 103.19999992847443, + "duration": 51.200000047683716, + "navigationId": 2543, + "initiatorType": "fetch", + "deliveryType": "", + "nextHopProtocol": "http/1.1", + "renderBlockingStatus": "non-blocking", + "contentType": "application/json", + "contentEncoding": "", + "workerStart": 0, + "workerRouterEvaluationStart": 0, + "workerCacheLookupStart": 0, + "workerMatchedSourceType": "", + "workerFinalSourceType": "", + "redirectStart": 0, + "redirectEnd": 0, + "fetchStart": 103.19999992847443, + "domainLookupStart": 103.19999992847443, + "domainLookupEnd": 103.19999992847443, + "connectStart": 103.19999992847443, + "secureConnectionStart": 0, + "connectEnd": 103.19999992847443, + "requestStart": 103.60000002384186, + "responseStart": 123.29999995231628, + "firstInterimResponseStart": 0, + "finalResponseHeadersStart": 123.29999995231628, + "responseEnd": 154.39999997615814, + "transferSize": 2247670, + "encodedBodySize": 2247370, + "decodedBodySize": 2247370, + "responseStatus": 200, + "serverTiming": [] + } + ] + } + ] + }, + "lazyTooltips": { + "environment": { + "node": "v24.15.0", + "browser": "154.0.8037.57", + "platform": "darwin", + "os": "25.6.0", + "arch": "arm64", + "cpu": "Apple M3", + "viewport": { + "width": 1440, + "height": 1000 + }, + "baseURL": "http://localhost:3107", + "censusRows": 3662 + }, + "summaries": [ + { + "throttle": 1, + "phase": "prefix-r", + "n": 9, + "p50_ms": 304.3000000715256, + "p95_ms": 397, + "elements": 57526, + "rows": 3592 + }, + { + "throttle": 1, + "phase": "readFile", + "n": 9, + "p50_ms": 33.89999997615814, + "p95_ms": 44.799999952316284, + "elements": 247, + "rows": 6 + }, + { + "throttle": 1, + "phase": "clear", + "n": 9, + "p50_ms": 21.300000071525574, + "p95_ms": 27.200000047683716, + "elements": 1131, + "rows": 55 + }, + { + "throttle": 1, + "phase": "expand-all", + "n": 9, + "p50_ms": 316.60000002384186, + "p95_ms": 344.60000002384186, + "elements": 58649, + "rows": 3662 + }, + { + "throttle": 1, + "phase": "collapse-all", + "n": 9, + "p50_ms": 36, + "p95_ms": 40.60000002384186, + "elements": 1131, + "rows": 55 + }, + { + "throttle": 4, + "phase": "prefix-r", + "n": 9, + "p50_ms": 1396.2000000476837, + "p95_ms": 1482.5, + "elements": 57526, + "rows": 3592 + }, + { + "throttle": 4, + "phase": "readFile", + "n": 9, + "p50_ms": 145.39999997615814, + "p95_ms": 168.10000002384186, + "elements": 247, + "rows": 6 + }, + { + "throttle": 4, + "phase": "clear", + "n": 9, + "p50_ms": 30.100000023841858, + "p95_ms": 33.10000002384186, + "elements": 1131, + "rows": 55 + }, + { + "throttle": 4, + "phase": "expand-all", + "n": 9, + "p50_ms": 1245.1000000238419, + "p95_ms": 1415.8999999761581, + "elements": 58649, + "rows": 3662 + }, + { + "throttle": 4, + "phase": "collapse-all", + "n": 9, + "p50_ms": 153.39999997615814, + "p95_ms": 170.90000009536743, + "elements": 1131, + "rows": 55 + } + ], + "samples": { + "1x/prefix-r": { + "rows": 3592, + "elements": 57526, + "ms": [ + 349.5, + 302, + 332.2999999523163, + 397, + 331.10000002384186, + 304.10000002384186, + 304.3000000715256, + 297.2999999523163, + 300.40000009536743 + ] + }, + "1x/readFile": { + "rows": 6, + "elements": 247, + "ms": [ + 37.60000002384186, + 36.60000002384186, + 44.799999952316284, + 32.300000071525574, + 32.700000047683716, + 31.699999928474426, + 32.800000071525574, + 33.89999997615814, + 37.5 + ] + }, + "1x/clear": { + "rows": 55, + "elements": 1131, + "ms": [ + 16.399999976158142, + 22.700000047683716, + 16.800000071525574, + 27.200000047683716, + 25.100000023841858, + 17.200000047683716, + 21.300000071525574, + 18.5, + 26.199999928474426 + ] + }, + "1x/expand-all": { + "rows": 3662, + "elements": 58649, + "ms": [ + 335.89999997615814, + 318.2000000476837, + 316.60000002384186, + 326, + 303, + 286.60000002384186, + 344.60000002384186, + 276.39999997615814, + 284.2999999523163 + ] + }, + "1x/collapse-all": { + "rows": 55, + "elements": 1131, + "ms": [ + 35.300000071525574, + 36.5, + 36, + 40.60000002384186, + 36.89999997615814, + 38.700000047683716, + 33.699999928474426, + 33.5, + 33.89999997615814 + ] + }, + "4x/prefix-r": { + "rows": 3592, + "elements": 57526, + "ms": [ + 1313.5, + 1482.5, + 1374.5, + 1365.1999999284744, + 1396.2000000476837, + 1443, + 1396.2000000476837, + 1395.3999999761581, + 1437.1000000238419 + ] + }, + "4x/readFile": { + "rows": 6, + "elements": 247, + "ms": [ + 168.10000002384186, + 136.70000004768372, + 147.20000004768372, + 136.60000002384186, + 142.89999997615814, + 145.39999997615814, + 145.39999997615814, + 141.80000007152557, + 145.89999997615814 + ] + }, + "4x/clear": { + "rows": 55, + "elements": 1131, + "ms": [ + 27.5, + 33.10000002384186, + 29.899999976158142, + 30, + 32.299999952316284, + 30.100000023841858, + 31.199999928474426, + 29.399999976158142, + 32.40000009536743 + ] + }, + "4x/expand-all": { + "rows": 3662, + "elements": 58649, + "ms": [ + 1210.6000000238419, + 1195.6999999284744, + 1291.6000000238419, + 1230.3999999761581, + 1415.8999999761581, + 1288.8999999761581, + 1318.3999999761581, + 1222.8999999761581, + 1245.1000000238419 + ] + }, + "4x/collapse-all": { + "rows": 55, + "elements": 1131, + "ms": [ + 149.69999992847443, + 145.20000004768372, + 156.39999997615814, + 170.90000009536743, + 161.89999997615814, + 170.90000009536743, + 153.39999997615814, + 152.39999997615814, + 152.89999997615814 + ] + } + }, + "loads": [ + { + "throttle": 1, + "navigation": { + "name": "http://localhost:3107/compatibility", + "entryType": "navigation", + "startTime": 0, + "duration": 60.799999952316284, + "navigationId": 4817, + "initiatorType": "navigation", + "deliveryType": "", + "nextHopProtocol": "http/1.1", + "renderBlockingStatus": "non-blocking", + "contentType": "text/html", + "contentEncoding": "gzip", + "workerStart": 0, + "workerRouterEvaluationStart": 0, + "workerCacheLookupStart": 0, + "workerMatchedSourceType": "", + "workerFinalSourceType": "", + "redirectStart": 0, + "redirectEnd": 0, + "fetchStart": 0.6999999284744263, + "domainLookupStart": 0.6999999284744263, + "domainLookupEnd": 0.6999999284744263, + "connectStart": 0.6999999284744263, + "secureConnectionStart": 0, + "connectEnd": 0.6999999284744263, + "requestStart": 1.5, + "responseStart": 4.100000023841858, + "firstInterimResponseStart": 0, + "finalResponseHeadersStart": 4.100000023841858, + "responseEnd": 4.5, + "transferSize": 5021, + "encodedBodySize": 4721, + "decodedBodySize": 20336, + "responseStatus": 200, + "serverTiming": [], + "unloadEventStart": 0, + "unloadEventEnd": 0, + "domInteractive": 24.5, + "domContentLoadedEventStart": 24.5, + "domContentLoadedEventEnd": 24.5, + "domComplete": 60.799999952316284, + "loadEventStart": 60.799999952316284, + "loadEventEnd": 60.799999952316284, + "type": "navigate", + "redirectCount": 0, + "activationStart": 0, + "criticalCHRestart": 0, + "notRestoredReasons": null, + "confidence": { + "randomizedTriggerRate": 0.4994798, + "value": "low" + } + }, + "data": [ + { + "name": "http://localhost:3107/compatibility/data?v=b9e39038b2832f02e54b", + "entryType": "resource", + "startTime": 80.60000002384186, + "duration": 7.5, + "navigationId": 4817, + "initiatorType": "fetch", + "deliveryType": "", + "nextHopProtocol": "http/1.1", + "renderBlockingStatus": "non-blocking", + "contentType": "application/json", + "contentEncoding": "", + "workerStart": 0, + "workerRouterEvaluationStart": 0, + "workerCacheLookupStart": 0, + "workerMatchedSourceType": "", + "workerFinalSourceType": "", + "redirectStart": 0, + "redirectEnd": 0, + "fetchStart": 80.60000002384186, + "domainLookupStart": 80.60000002384186, + "domainLookupEnd": 80.60000002384186, + "connectStart": 80.60000002384186, + "secureConnectionStart": 0, + "connectEnd": 80.60000002384186, + "requestStart": 80.89999997615814, + "responseStart": 83.89999997615814, + "firstInterimResponseStart": 0, + "finalResponseHeadersStart": 83.89999997615814, + "responseEnd": 88.10000002384186, + "transferSize": 2247670, + "encodedBodySize": 2247370, + "decodedBodySize": 2247370, + "responseStatus": 200, + "serverTiming": [] + } + ] + }, + { + "throttle": 4, + "navigation": { + "name": "http://localhost:3107/compatibility", + "entryType": "navigation", + "startTime": 0, + "duration": 70.79999995231628, + "navigationId": 3268, + "initiatorType": "navigation", + "deliveryType": "cache", + "nextHopProtocol": "", + "renderBlockingStatus": "non-blocking", + "contentType": "text/html", + "contentEncoding": "gzip", + "workerStart": 0, + "workerRouterEvaluationStart": 0, + "workerCacheLookupStart": 0, + "workerMatchedSourceType": "", + "workerFinalSourceType": "", + "redirectStart": 0, + "redirectEnd": 0, + "fetchStart": 0.2999999523162842, + "domainLookupStart": 0.2999999523162842, + "domainLookupEnd": 0.2999999523162842, + "connectStart": 0.2999999523162842, + "secureConnectionStart": 0, + "connectEnd": 0.2999999523162842, + "requestStart": 1.1999999284744263, + "responseStart": 4.5, + "firstInterimResponseStart": 0, + "finalResponseHeadersStart": 4.5, + "responseEnd": 4.799999952316284, + "transferSize": 300, + "encodedBodySize": 4721, + "decodedBodySize": 20336, + "responseStatus": 200, + "serverTiming": [], + "unloadEventStart": 12.699999928474426, + "unloadEventEnd": 12.699999928474426, + "domInteractive": 31.799999952316284, + "domContentLoadedEventStart": 31.799999952316284, + "domContentLoadedEventEnd": 31.799999952316284, + "domComplete": 70.79999995231628, + "loadEventStart": 70.79999995231628, + "loadEventEnd": 70.79999995231628, + "type": "navigate", + "redirectCount": 0, + "activationStart": 0, + "criticalCHRestart": 0, + "notRestoredReasons": null, + "confidence": { + "randomizedTriggerRate": 0.4994798, + "value": "high" + } + }, + "data": [ + { + "name": "http://localhost:3107/compatibility/data?v=b9e39038b2832f02e54b", + "entryType": "resource", + "startTime": 99.39999997615814, + "duration": 27.399999976158142, + "navigationId": 3268, + "initiatorType": "fetch", + "deliveryType": "", + "nextHopProtocol": "http/1.1", + "renderBlockingStatus": "non-blocking", + "contentType": "application/json", + "contentEncoding": "", + "workerStart": 0, + "workerRouterEvaluationStart": 0, + "workerCacheLookupStart": 0, + "workerMatchedSourceType": "", + "workerFinalSourceType": "", + "redirectStart": 0, + "redirectEnd": 0, + "fetchStart": 99.39999997615814, + "domainLookupStart": 99.39999997615814, + "domainLookupEnd": 99.39999997615814, + "connectStart": 99.39999997615814, + "secureConnectionStart": 0, + "connectEnd": 99.39999997615814, + "requestStart": 100.19999992847443, + "responseStart": 103.59999990463257, + "firstInterimResponseStart": 0, + "finalResponseHeadersStart": 103.59999990463257, + "responseEnd": 126.79999995231628, + "transferSize": 2247670, + "encodedBodySize": 2247370, + "decodedBodySize": 2247370, + "responseStatus": 200, + "serverTiming": [] + } + ] + } + ] + }, + "beforeMemo": { + "environment": { + "node": "v24.15.0", + "browser": "154.0.8037.57", + "platform": "darwin", + "os": "25.6.0", + "arch": "arm64", + "cpu": "Apple M3", + "viewport": { + "width": 1440, + "height": 1000 + }, + "baseURL": "http://localhost:3107", + "censusRows": 3662 + }, + "summaries": [ + { + "throttle": 1, + "phase": "prefix-r", + "n": 9, + "p50_ms": 330, + "p95_ms": 387.3000000715256, + "elements": 57526, + "rows": 3592 + }, + { + "throttle": 1, + "phase": "prefix-re", + "n": 9, + "p50_ms": 93.80000007152557, + "p95_ms": 104.89999997615814, + "elements": 49068, + "rows": 3061 + }, + { + "throttle": 1, + "phase": "readFile", + "n": 9, + "p50_ms": 33.60000002384186, + "p95_ms": 38.299999952316284, + "elements": 247, + "rows": 6 + }, + { + "throttle": 1, + "phase": "clear", + "n": 9, + "p50_ms": 20, + "p95_ms": 29.800000071525574, + "elements": 1131, + "rows": 55 + }, + { + "throttle": 1, + "phase": "expand-all", + "n": 9, + "p50_ms": 304.10000002384186, + "p95_ms": 321.6999999284744, + "elements": 58649, + "rows": 3662 + }, + { + "throttle": 1, + "phase": "collapse-all", + "n": 9, + "p50_ms": 35.90000009536743, + "p95_ms": 37.5, + "elements": 1131, + "rows": 55 + }, + { + "throttle": 4, + "phase": "prefix-r", + "n": 9, + "p50_ms": 1378.2999999523163, + "p95_ms": 1461.4000000953674, + "elements": 57526, + "rows": 3592 + }, + { + "throttle": 4, + "phase": "prefix-re", + "n": 9, + "p50_ms": 382.7999999523163, + "p95_ms": 449.1999999284744, + "elements": 49068, + "rows": 3061 + }, + { + "throttle": 4, + "phase": "readFile", + "n": 9, + "p50_ms": 140.89999997615814, + "p95_ms": 146.89999997615814, + "elements": 247, + "rows": 6 + }, + { + "throttle": 4, + "phase": "clear", + "n": 9, + "p50_ms": 27.799999952316284, + "p95_ms": 34.799999952316284, + "elements": 1131, + "rows": 55 + }, + { + "throttle": 4, + "phase": "expand-all", + "n": 9, + "p50_ms": 1221.3000000715256, + "p95_ms": 1296.6000000238419, + "elements": 58649, + "rows": 3662 + }, + { + "throttle": 4, + "phase": "collapse-all", + "n": 9, + "p50_ms": 155.60000002384186, + "p95_ms": 171.20000004768372, + "elements": 1131, + "rows": 55 + } + ], + "samples": { + "1x/prefix-r": { + "rows": 3592, + "elements": 57526, + "ms": [ + 337.40000009536743, + 296, + 294.2000000476837, + 387.3000000715256, + 296.60000002384186, + 313.89999997615814, + 330, + 340.7000000476837, + 337.89999997615814 + ] + }, + "1x/prefix-re": { + "rows": 3061, + "elements": 49068, + "ms": [ + 104.69999992847443, + 93.80000007152557, + 104.89999997615814, + 87.09999990463257, + 99.79999995231628, + 93, + 91.70000004768372, + 96.09999990463257, + 85.39999997615814 + ] + }, + "1x/readFile": { + "rows": 6, + "elements": 247, + "ms": [ + 33.299999952316284, + 33.60000002384186, + 38.299999952316284, + 34.40000009536743, + 34, + 32.299999952316284, + 33.299999952316284, + 33.700000047683716, + 32.200000047683716 + ] + }, + "1x/clear": { + "rows": 55, + "elements": 1131, + "ms": [ + 20, + 18.199999928474426, + 27.800000071525574, + 29.800000071525574, + 16.399999976158142, + 18.40000009536743, + 21.59999990463257, + 24.100000023841858, + 17.5 + ] + }, + "1x/expand-all": { + "rows": 3662, + "elements": 58649, + "ms": [ + 321.6999999284744, + 301.39999997615814, + 321.2000000476837, + 302, + 300.40000009536743, + 306.2999999523163, + 311.2999999523163, + 304.10000002384186, + 289.60000002384186 + ] + }, + "1x/collapse-all": { + "rows": 55, + "elements": 1131, + "ms": [ + 34.299999952316284, + 34, + 33.799999952316284, + 36.09999990463257, + 37.5, + 37, + 35.699999928474426, + 36.5, + 35.90000009536743 + ] + }, + "4x/prefix-r": { + "rows": 3592, + "elements": 57526, + "ms": [ + 1418.2000000476837, + 1406.5, + 1351.7000000476837, + 1324, + 1449.5, + 1351.6999999284744, + 1350.2000000476837, + 1378.2999999523163, + 1461.4000000953674 + ] + }, + "4x/prefix-re": { + "rows": 3061, + "elements": 49068, + "ms": [ + 402.39999997615814, + 386.60000002384186, + 382.7999999523163, + 372, + 417.6999999284744, + 369.10000002384186, + 377.6999999284744, + 379.90000009536743, + 449.1999999284744 + ] + }, + "4x/readFile": { + "rows": 6, + "elements": 247, + "ms": [ + 146.89999997615814, + 141.89999997615814, + 138.80000007152557, + 137.60000002384186, + 141.70000004768372, + 136.69999992847443, + 141.69999992847443, + 140, + 140.89999997615814 + ] + }, + "4x/clear": { + "rows": 55, + "elements": 1131, + "ms": [ + 34.799999952316284, + 27.299999952316284, + 27.100000023841858, + 27.299999952316284, + 27.100000023841858, + 27.799999952316284, + 33.699999928474426, + 28.40000009536743, + 29 + ] + }, + "4x/expand-all": { + "rows": 3662, + "elements": 58649, + "ms": [ + 1275.2999999523163, + 1197.7999999523163, + 1225.3999999761581, + 1181.9000000953674, + 1221.3000000715256, + 1207.8000000715256, + 1198.2999999523163, + 1260.5, + 1296.6000000238419 + ] + }, + "4x/collapse-all": { + "rows": 55, + "elements": 1131, + "ms": [ + 171.20000004768372, + 149.89999997615814, + 145.60000002384186, + 160.60000002384186, + 153.5, + 158.39999997615814, + 154.39999997615814, + 166.19999992847443, + 155.60000002384186 + ] + } + }, + "loads": [ + { + "throttle": 1, + "navigation": { + "name": "http://localhost:3107/compatibility", + "entryType": "navigation", + "startTime": 0, + "duration": 100.39999997615814, + "navigationId": 3595, + "initiatorType": "navigation", + "deliveryType": "", + "nextHopProtocol": "http/1.1", + "renderBlockingStatus": "non-blocking", + "contentType": "text/html", + "contentEncoding": "gzip", + "workerStart": 0, + "workerRouterEvaluationStart": 0, + "workerCacheLookupStart": 0, + "workerMatchedSourceType": "", + "workerFinalSourceType": "", + "redirectStart": 0, + "redirectEnd": 0, + "fetchStart": 0.5, + "domainLookupStart": 0.5, + "domainLookupEnd": 0.5, + "connectStart": 0.5, + "secureConnectionStart": 0, + "connectEnd": 0.5, + "requestStart": 1.600000023841858, + "responseStart": 13, + "firstInterimResponseStart": 0, + "finalResponseHeadersStart": 13, + "responseEnd": 13.600000023841858, + "transferSize": 5021, + "encodedBodySize": 4721, + "decodedBodySize": 20336, + "responseStatus": 200, + "serverTiming": [], + "unloadEventStart": 0, + "unloadEventEnd": 0, + "domInteractive": 66.79999995231628, + "domContentLoadedEventStart": 66.79999995231628, + "domContentLoadedEventEnd": 66.79999995231628, + "domComplete": 100.39999997615814, + "loadEventStart": 100.39999997615814, + "loadEventEnd": 100.39999997615814, + "type": "navigate", + "redirectCount": 0, + "activationStart": 0, + "criticalCHRestart": 0, + "notRestoredReasons": null, + "confidence": { + "randomizedTriggerRate": 0.4994798, + "value": "low" + } + }, + "data": [ + { + "name": "http://localhost:3107/compatibility/data?v=b9e39038b2832f02e54b", + "entryType": "resource", + "startTime": 124.10000002384186, + "duration": 64.5, + "navigationId": 3595, + "initiatorType": "fetch", + "deliveryType": "", + "nextHopProtocol": "http/1.1", + "renderBlockingStatus": "non-blocking", + "contentType": "application/json", + "contentEncoding": "", + "workerStart": 0, + "workerRouterEvaluationStart": 0, + "workerCacheLookupStart": 0, + "workerMatchedSourceType": "", + "workerFinalSourceType": "", + "redirectStart": 0, + "redirectEnd": 0, + "fetchStart": 124.10000002384186, + "domainLookupStart": 124.10000002384186, + "domainLookupEnd": 124.10000002384186, + "connectStart": 124.10000002384186, + "secureConnectionStart": 0, + "connectEnd": 124.10000002384186, + "requestStart": 128.70000004768372, + "responseStart": 175.29999995231628, + "firstInterimResponseStart": 0, + "finalResponseHeadersStart": 175.29999995231628, + "responseEnd": 188.60000002384186, + "transferSize": 2247670, + "encodedBodySize": 2247370, + "decodedBodySize": 2247370, + "responseStatus": 200, + "serverTiming": [] + } + ] + }, + { + "throttle": 4, + "navigation": { + "name": "http://localhost:3107/compatibility", + "entryType": "navigation", + "startTime": 0, + "duration": 60.200000047683716, + "navigationId": 1051, + "initiatorType": "navigation", + "deliveryType": "cache", + "nextHopProtocol": "", + "renderBlockingStatus": "non-blocking", + "contentType": "text/html", + "contentEncoding": "gzip", + "workerStart": 0, + "workerRouterEvaluationStart": 0, + "workerCacheLookupStart": 0, + "workerMatchedSourceType": "", + "workerFinalSourceType": "", + "redirectStart": 0, + "redirectEnd": 0, + "fetchStart": 0.20000004768371582, + "domainLookupStart": 0.20000004768371582, + "domainLookupEnd": 0.20000004768371582, + "connectStart": 0.20000004768371582, + "secureConnectionStart": 0, + "connectEnd": 0.20000004768371582, + "requestStart": 2.600000023841858, + "responseStart": 3.700000047683716, + "firstInterimResponseStart": 0, + "finalResponseHeadersStart": 3.700000047683716, + "responseEnd": 3.8000000715255737, + "transferSize": 300, + "encodedBodySize": 4721, + "decodedBodySize": 20336, + "responseStatus": 200, + "serverTiming": [], + "unloadEventStart": 9.800000071525574, + "unloadEventEnd": 9.800000071525574, + "domInteractive": 28.800000071525574, + "domContentLoadedEventStart": 28.800000071525574, + "domContentLoadedEventEnd": 28.899999976158142, + "domComplete": 60.200000047683716, + "loadEventStart": 60.200000047683716, + "loadEventEnd": 60.200000047683716, + "type": "navigate", + "redirectCount": 0, + "activationStart": 0, + "criticalCHRestart": 0, + "notRestoredReasons": null, + "confidence": { + "randomizedTriggerRate": 0.4994798, + "value": "low" + } + }, + "data": [ + { + "name": "http://localhost:3107/compatibility/data?v=b9e39038b2832f02e54b", + "entryType": "resource", + "startTime": 68.60000002384186, + "duration": 29.299999952316284, + "navigationId": 1051, + "initiatorType": "fetch", + "deliveryType": "", + "nextHopProtocol": "http/1.1", + "renderBlockingStatus": "non-blocking", + "contentType": "application/json", + "contentEncoding": "", + "workerStart": 0, + "workerRouterEvaluationStart": 0, + "workerCacheLookupStart": 0, + "workerMatchedSourceType": "", + "workerFinalSourceType": "", + "redirectStart": 0, + "redirectEnd": 0, + "fetchStart": 68.60000002384186, + "domainLookupStart": 68.60000002384186, + "domainLookupEnd": 68.60000002384186, + "connectStart": 68.60000002384186, + "secureConnectionStart": 0, + "connectEnd": 68.60000002384186, + "requestStart": 68.89999997615814, + "responseStart": 70.60000002384186, + "firstInterimResponseStart": 0, + "finalResponseHeadersStart": 70.60000002384186, + "responseEnd": 97.89999997615814, + "transferSize": 2247670, + "encodedBodySize": 2247370, + "decodedBodySize": 2247370, + "responseStatus": 200, + "serverTiming": [] + } + ] + } + ] + }, + "afterMemo": { + "environment": { + "node": "v24.15.0", + "browser": "154.0.8037.57", + "platform": "darwin", + "os": "25.6.0", + "arch": "arm64", + "cpu": "Apple M3", + "viewport": { + "width": 1440, + "height": 1000 + }, + "baseURL": "http://127.0.0.1:3108", + "censusRows": 3662 + }, + "summaries": [ + { + "throttle": 1, + "phase": "prefix-r", + "n": 9, + "p50_ms": 319.7999999523163, + "p95_ms": 382.60000002384186, + "elements": 57526, + "rows": 3592 + }, + { + "throttle": 1, + "phase": "prefix-re", + "n": 9, + "p50_ms": 82.10000002384186, + "p95_ms": 100.39999997615814, + "elements": 49068, + "rows": 3061 + }, + { + "throttle": 1, + "phase": "readFile", + "n": 9, + "p50_ms": 32.700000047683716, + "p95_ms": 40.89999997615814, + "elements": 247, + "rows": 6 + }, + { + "throttle": 1, + "phase": "clear", + "n": 9, + "p50_ms": 22.5, + "p95_ms": 33.299999952316284, + "elements": 1131, + "rows": 55 + }, + { + "throttle": 1, + "phase": "expand-all", + "n": 9, + "p50_ms": 301, + "p95_ms": 352.89999997615814, + "elements": 58649, + "rows": 3662 + }, + { + "throttle": 1, + "phase": "collapse-all", + "n": 9, + "p50_ms": 39.200000047683716, + "p95_ms": 42.10000002384186, + "elements": 1131, + "rows": 55 + }, + { + "throttle": 4, + "phase": "prefix-r", + "n": 9, + "p50_ms": 1368.2000000476837, + "p95_ms": 1448.3999999761581, + "elements": 57526, + "rows": 3592 + }, + { + "throttle": 4, + "phase": "prefix-re", + "n": 9, + "p50_ms": 349.10000002384186, + "p95_ms": 410.2999999523163, + "elements": 49068, + "rows": 3061 + }, + { + "throttle": 4, + "phase": "readFile", + "n": 9, + "p50_ms": 141.5, + "p95_ms": 150.5, + "elements": 247, + "rows": 6 + }, + { + "throttle": 4, + "phase": "clear", + "n": 9, + "p50_ms": 31.399999976158142, + "p95_ms": 32.700000047683716, + "elements": 1131, + "rows": 55 + }, + { + "throttle": 4, + "phase": "expand-all", + "n": 9, + "p50_ms": 1254.5, + "p95_ms": 1286, + "elements": 58649, + "rows": 3662 + }, + { + "throttle": 4, + "phase": "collapse-all", + "n": 9, + "p50_ms": 152.20000004768372, + "p95_ms": 169.69999992847443, + "elements": 1131, + "rows": 55 + } + ], + "samples": { + "1x/prefix-r": { + "rows": 3592, + "elements": 57526, + "ms": [ + 334.7999999523163, + 311, + 315.39999997615814, + 310.10000002384186, + 382.60000002384186, + 289.3000000715256, + 322.3000000715256, + 319.7999999523163, + 328 + ] + }, + "1x/prefix-re": { + "rows": 3061, + "elements": 49068, + "ms": [ + 91.10000002384186, + 84.10000002384186, + 86.39999997615814, + 100.39999997615814, + 79.79999995231628, + 77.79999995231628, + 79.30000007152557, + 79.10000002384186, + 82.10000002384186 + ] + }, + "1x/readFile": { + "rows": 6, + "elements": 247, + "ms": [ + 37.10000002384186, + 34.39999997615814, + 37, + 40.89999997615814, + 31.700000047683716, + 31.200000047683716, + 31.5, + 31.600000023841858, + 32.700000047683716 + ] + }, + "1x/clear": { + "rows": 55, + "elements": 1131, + "ms": [ + 18, + 20, + 17.899999976158142, + 33.299999952316284, + 30.600000023841858, + 22.5, + 18.399999976158142, + 27.100000023841858, + 24.899999976158142 + ] + }, + "1x/expand-all": { + "rows": 3662, + "elements": 58649, + "ms": [ + 352.89999997615814, + 305.8000000715256, + 289.7999999523163, + 289.1999999284744, + 300.89999997615814, + 299.3000000715256, + 301, + 302.89999997615814, + 301.7000000476837 + ] + }, + "1x/collapse-all": { + "rows": 55, + "elements": 1131, + "ms": [ + 35.39999997615814, + 34.699999928474426, + 33.800000071525574, + 34, + 40, + 39.60000002384186, + 39.200000047683716, + 41.200000047683716, + 42.10000002384186 + ] + }, + "4x/prefix-r": { + "rows": 3592, + "elements": 57526, + "ms": [ + 1353.3000000715256, + 1369.7000000476837, + 1425.1000000238419, + 1344.1000000238419, + 1330.7999999523163, + 1409.7000000476837, + 1448.3999999761581, + 1361.6999999284744, + 1368.2000000476837 + ] + }, + "4x/prefix-re": { + "rows": 3061, + "elements": 49068, + "ms": [ + 319.3000000715256, + 349.10000002384186, + 349.40000009536743, + 345.5, + 340.7000000476837, + 339.59999990463257, + 410.2999999523163, + 364.7999999523163, + 361.8000000715256 + ] + }, + "4x/readFile": { + "rows": 6, + "elements": 247, + "ms": [ + 142.5, + 141.80000007152557, + 140.20000004768372, + 150.5, + 139, + 137.20000004768372, + 141.5, + 143.19999992847443, + 132 + ] + }, + "4x/clear": { + "rows": 55, + "elements": 1131, + "ms": [ + 32.40000009536743, + 28.200000047683716, + 31.600000023841858, + 31.399999976158142, + 26.800000071525574, + 32.700000047683716, + 29.100000023841858, + 30.700000047683716, + 32.200000047683716 + ] + }, + "4x/expand-all": { + "rows": 3662, + "elements": 58649, + "ms": [ + 1220.7000000476837, + 1275.5, + 1199.7999999523163, + 1223.2000000476837, + 1286, + 1259.2000000476837, + 1254.5, + 1209.8999999761581, + 1273.6000000238419 + ] + }, + "4x/collapse-all": { + "rows": 55, + "elements": 1131, + "ms": [ + 152.20000004768372, + 159.80000007152557, + 144.29999995231628, + 151.5, + 169.69999992847443, + 157.60000002384186, + 147.60000002384186, + 150.39999997615814, + 152.79999995231628 + ] + } + }, + "loads": [ + { + "throttle": 1, + "navigation": { + "name": "http://127.0.0.1:3108/compatibility", + "entryType": "navigation", + "startTime": 0, + "duration": 69.5, + "navigationId": 7307, + "initiatorType": "navigation", + "deliveryType": "", + "nextHopProtocol": "http/1.1", + "renderBlockingStatus": "non-blocking", + "contentType": "text/html", + "contentEncoding": "gzip", + "workerStart": 0, + "workerRouterEvaluationStart": 0, + "workerCacheLookupStart": 0, + "workerMatchedSourceType": "", + "workerFinalSourceType": "", + "redirectStart": 0, + "redirectEnd": 0, + "fetchStart": 0.5, + "domainLookupStart": 0.5, + "domainLookupEnd": 0.5, + "connectStart": 0.5, + "secureConnectionStart": 0, + "connectEnd": 0.5, + "requestStart": 1.2999999523162842, + "responseStart": 8.299999952316284, + "firstInterimResponseStart": 0, + "finalResponseHeadersStart": 8.299999952316284, + "responseEnd": 8.600000023841858, + "transferSize": 5021, + "encodedBodySize": 4721, + "decodedBodySize": 20336, + "responseStatus": 200, + "serverTiming": [], + "unloadEventStart": 0, + "unloadEventEnd": 0, + "domInteractive": 38.299999952316284, + "domContentLoadedEventStart": 38.299999952316284, + "domContentLoadedEventEnd": 38.299999952316284, + "domComplete": 69.5, + "loadEventStart": 69.5, + "loadEventEnd": 69.5, + "type": "navigate", + "redirectCount": 0, + "activationStart": 0, + "criticalCHRestart": 0, + "notRestoredReasons": null, + "confidence": { + "randomizedTriggerRate": 0.4994798, + "value": "low" + } + }, + "data": [ + { + "name": "http://127.0.0.1:3108/compatibility/data?v=b9e39038b2832f02e54b", + "entryType": "resource", + "startTime": 85.70000004768372, + "duration": 28.699999928474426, + "navigationId": 7307, + "initiatorType": "fetch", + "deliveryType": "", + "nextHopProtocol": "http/1.1", + "renderBlockingStatus": "non-blocking", + "contentType": "application/json", + "contentEncoding": "", + "workerStart": 0, + "workerRouterEvaluationStart": 0, + "workerCacheLookupStart": 0, + "workerMatchedSourceType": "", + "workerFinalSourceType": "", + "redirectStart": 0, + "redirectEnd": 0, + "fetchStart": 85.70000004768372, + "domainLookupStart": 85.70000004768372, + "domainLookupEnd": 85.70000004768372, + "connectStart": 85.70000004768372, + "secureConnectionStart": 0, + "connectEnd": 85.70000004768372, + "requestStart": 85.89999997615814, + "responseStart": 113, + "firstInterimResponseStart": 0, + "finalResponseHeadersStart": 113, + "responseEnd": 114.39999997615814, + "transferSize": 2247670, + "encodedBodySize": 2247370, + "decodedBodySize": 2247370, + "responseStatus": 200, + "serverTiming": [] + } + ] + }, + { + "throttle": 4, + "navigation": { + "name": "http://127.0.0.1:3108/compatibility", + "entryType": "navigation", + "startTime": 0, + "duration": 66.40000009536743, + "navigationId": 9677, + "initiatorType": "navigation", + "deliveryType": "cache", + "nextHopProtocol": "", + "renderBlockingStatus": "non-blocking", + "contentType": "text/html", + "contentEncoding": "gzip", + "workerStart": 0, + "workerRouterEvaluationStart": 0, + "workerCacheLookupStart": 0, + "workerMatchedSourceType": "", + "workerFinalSourceType": "", + "redirectStart": 0, + "redirectEnd": 0, + "fetchStart": 0.30000007152557373, + "domainLookupStart": 0.30000007152557373, + "domainLookupEnd": 0.30000007152557373, + "connectStart": 0.30000007152557373, + "secureConnectionStart": 0, + "connectEnd": 0.30000007152557373, + "requestStart": 1, + "responseStart": 3.9000000953674316, + "firstInterimResponseStart": 0, + "finalResponseHeadersStart": 3.9000000953674316, + "responseEnd": 4.100000023841858, + "transferSize": 300, + "encodedBodySize": 4721, + "decodedBodySize": 20336, + "responseStatus": 200, + "serverTiming": [], + "unloadEventStart": 9.600000023841858, + "unloadEventEnd": 9.600000023841858, + "domInteractive": 28.5, + "domContentLoadedEventStart": 28.5, + "domContentLoadedEventEnd": 28.600000023841858, + "domComplete": 66.30000007152557, + "loadEventStart": 66.40000009536743, + "loadEventEnd": 66.40000009536743, + "type": "navigate", + "redirectCount": 0, + "activationStart": 0, + "criticalCHRestart": 0, + "notRestoredReasons": null, + "confidence": { + "randomizedTriggerRate": 0.4994798, + "value": "high" + } + }, + "data": [ + { + "name": "http://127.0.0.1:3108/compatibility/data?v=b9e39038b2832f02e54b", + "entryType": "resource", + "startTime": 92.60000002384186, + "duration": 19.800000071525574, + "navigationId": 9677, + "initiatorType": "fetch", + "deliveryType": "", + "nextHopProtocol": "http/1.1", + "renderBlockingStatus": "non-blocking", + "contentType": "application/json", + "contentEncoding": "", + "workerStart": 0, + "workerRouterEvaluationStart": 0, + "workerCacheLookupStart": 0, + "workerMatchedSourceType": "", + "workerFinalSourceType": "", + "redirectStart": 0, + "redirectEnd": 0, + "fetchStart": 92.60000002384186, + "domainLookupStart": 92.60000002384186, + "domainLookupEnd": 92.60000002384186, + "connectStart": 92.60000002384186, + "secureConnectionStart": 0, + "connectEnd": 92.60000002384186, + "requestStart": 93.40000009536743, + "responseStart": 96.60000002384186, + "firstInterimResponseStart": 0, + "finalResponseHeadersStart": 96.60000002384186, + "responseEnd": 112.40000009536743, + "transferSize": 2247670, + "encodedBodySize": 2247370, + "decodedBodySize": 2247370, + "responseStatus": 200, + "serverTiming": [] + } + ] + } + ] + }, + "journeyBefore": { + "environment": { + "node": "v24.15.0", + "browser": "154.0.8037.57", + "platform": "darwin", + "os": "25.6.0", + "arch": "arm64", + "cpu": "Apple M3", + "viewport": { + "width": 1440, + "height": 1000 + }, + "baseURL": "http://127.0.0.1:3108", + "censusRows": 3662 + }, + "summaries": [ + { + "throttle": 1, + "phase": "prefix-r", + "n": 9, + "p50_ms": 679.1000000238419, + "p95_ms": 1217.1000000238419, + "elements": 89169, + "rows": 3592 + }, + { + "throttle": 1, + "phase": "prefix-re", + "n": 9, + "p50_ms": 181.79999995231628, + "p95_ms": 340.39999997615814, + "elements": 76026, + "rows": 3061 + }, + { + "throttle": 1, + "phase": "readFile", + "n": 9, + "p50_ms": 57.700000047683716, + "p95_ms": 108.60000002384186, + "elements": 301, + "rows": 6 + }, + { + "throttle": 1, + "phase": "clear", + "n": 9, + "p50_ms": 25, + "p95_ms": 32.699999928474426, + "elements": 1617, + "rows": 55 + }, + { + "throttle": 1, + "phase": "expand-all", + "n": 9, + "p50_ms": 641.5, + "p95_ms": 919.2000000476837, + "elements": 90922, + "rows": 3662 + }, + { + "throttle": 1, + "phase": "collapse-all", + "n": 9, + "p50_ms": 63, + "p95_ms": 184.69999992847443, + "elements": 1617, + "rows": 55 + }, + { + "throttle": 1, + "phase": "typed-readFile", + "n": 9, + "p50_ms": 1087.7000000476837, + "p95_ms": 1491, + "elements": 301, + "rows": 6 + }, + { + "throttle": 4, + "phase": "prefix-r", + "n": 9, + "p50_ms": 2635.5, + "p95_ms": 3768.6999999284744, + "elements": 89169, + "rows": 3592 + }, + { + "throttle": 4, + "phase": "prefix-re", + "n": 9, + "p50_ms": 796.4000000953674, + "p95_ms": 962.8000000715256, + "elements": 76026, + "rows": 3061 + }, + { + "throttle": 4, + "phase": "readFile", + "n": 9, + "p50_ms": 256.8000000715256, + "p95_ms": 319.2000000476837, + "elements": 301, + "rows": 6 + }, + { + "throttle": 4, + "phase": "clear", + "n": 9, + "p50_ms": 47.10000002384186, + "p95_ms": 62.300000071525574, + "elements": 1617, + "rows": 55 + }, + { + "throttle": 4, + "phase": "expand-all", + "n": 9, + "p50_ms": 2554.7000000476837, + "p95_ms": 4195.699999928474, + "elements": 90922, + "rows": 3662 + }, + { + "throttle": 4, + "phase": "collapse-all", + "n": 9, + "p50_ms": 286.7000000476837, + "p95_ms": 400.5, + "elements": 1617, + "rows": 55 + }, + { + "throttle": 4, + "phase": "typed-readFile", + "n": 9, + "p50_ms": 3799.7999999523163, + "p95_ms": 4644.600000023842, + "elements": 301, + "rows": 6 + } + ], + "samples": { + "1x/prefix-r": { + "rows": 3592, + "elements": 89169, + "ms": [ + 750.6000000238419, + 641.6000000238419, + 643.7000000476837, + 748.7000000476837, + 1217.1000000238419, + 679.1000000238419, + 637.1000000238419, + 660.7999999523163, + 754.6000000238419 + ] + }, + "1x/prefix-re": { + "rows": 3061, + "elements": 76026, + "ms": [ + 203.10000002384186, + 204.60000002384186, + 181.79999995231628, + 191.60000002384186, + 340.39999997615814, + 161.90000009536743, + 164.29999995231628, + 163.30000007152557, + 170.30000007152557 + ] + }, + "1x/readFile": { + "rows": 6, + "elements": 301, + "ms": [ + 57.700000047683716, + 56.800000071525574, + 61.700000047683716, + 108.60000002384186, + 64.60000002384186, + 56.90000009536743, + 56.5, + 58.10000002384186, + 53.699999928474426 + ] + }, + "1x/clear": { + "rows": 55, + "elements": 1617, + "ms": [ + 25, + 23.5, + 23.800000071525574, + 28, + 32.699999928474426, + 22.399999976158142, + 26.700000047683716, + 30.40000009536743, + 18 + ] + }, + "1x/expand-all": { + "rows": 3662, + "elements": 90922, + "ms": [ + 641.5, + 602.1000000238419, + 618, + 919.2000000476837, + 692.4000000953674, + 624.6999999284744, + 590, + 692.7000000476837, + 665.1999999284744 + ] + }, + "1x/collapse-all": { + "rows": 55, + "elements": 1617, + "ms": [ + 57.799999952316284, + 62.60000002384186, + 63, + 184.69999992847443, + 76.29999995231628, + 57.60000002384186, + 64.10000002384186, + 65.70000004768372, + 58.10000002384186 + ] + }, + "1x/typed-readFile": { + "rows": 6, + "elements": 301, + "ms": [ + 1023, + 1154.7999999523163, + 1491, + 1254.5999999046326, + 1077, + 1087.7000000476837, + 1119, + 1028.6999999284744, + 978.3000000715256 + ] + }, + "4x/prefix-r": { + "rows": 3592, + "elements": 89169, + "ms": [ + 2461.6999999284744, + 2568.600000023842, + 2678, + 2785, + 3768.6999999284744, + 2471.2999999523163, + 2635.5, + 2530.399999976158, + 3098.100000023842 + ] + }, + "4x/prefix-re": { + "rows": 3061, + "elements": 76026, + "ms": [ + 818.6000000238419, + 715, + 871.1999999284744, + 776.2999999523163, + 796.4000000953674, + 751.7000000476837, + 715.0999999046326, + 803.1999999284744, + 962.8000000715256 + ] + }, + "4x/readFile": { + "rows": 6, + "elements": 301, + "ms": [ + 270.10000002384186, + 241.39999997615814, + 283.10000002384186, + 256.8000000715256, + 236.69999992847443, + 252.29999995231628, + 250.89999997615814, + 276.7999999523163, + 319.2000000476837 + ] + }, + "4x/clear": { + "rows": 55, + "elements": 1617, + "ms": [ + 46.59999990463257, + 53, + 51.60000002384186, + 44.89999997615814, + 47.10000002384186, + 43.299999952316284, + 46.39999997615814, + 50, + 62.300000071525574 + ] + }, + "4x/expand-all": { + "rows": 3662, + "elements": 90922, + "ms": [ + 2510.5, + 2492.2000000476837, + 3003.7999999523163, + 3294.2000000476837, + 2383.2000000476837, + 2665.7000000476837, + 2239.5, + 2554.7000000476837, + 4195.699999928474 + ] + }, + "4x/collapse-all": { + "rows": 55, + "elements": 1617, + "ms": [ + 299.60000002384186, + 281.60000002384186, + 283.60000002384186, + 346, + 294.1999999284744, + 280.2999999523163, + 249.30000007152557, + 286.7000000476837, + 400.5 + ] + }, + "4x/typed-readFile": { + "rows": 6, + "elements": 301, + "ms": [ + 4216.5, + 3799.7999999523163, + 3494.399999976158, + 4269.799999952316, + 4215.5, + 3413.7999999523163, + 3730.1999999284744, + 3526.600000023842, + 4644.600000023842 + ] + } + }, + "loads": [ + { + "throttle": 1, + "usable_ms": 213.5, + "navigation": { + "name": "http://127.0.0.1:3108/compatibility", + "entryType": "navigation", + "startTime": 0, + "duration": 121, + "navigationId": 352, + "initiatorType": "navigation", + "deliveryType": "", + "nextHopProtocol": "http/1.1", + "renderBlockingStatus": "non-blocking", + "contentType": "text/html", + "contentEncoding": "gzip", + "workerStart": 0, + "workerRouterEvaluationStart": 0, + "workerCacheLookupStart": 0, + "workerMatchedSourceType": "", + "workerFinalSourceType": "", + "redirectStart": 0, + "redirectEnd": 0, + "fetchStart": 0.5, + "domainLookupStart": 0.5, + "domainLookupEnd": 0.5, + "connectStart": 0.5, + "secureConnectionStart": 0, + "connectEnd": 0.5, + "requestStart": 1.600000023841858, + "responseStart": 10.800000071525574, + "firstInterimResponseStart": 0, + "finalResponseHeadersStart": 10.800000071525574, + "responseEnd": 11.5, + "transferSize": 5022, + "encodedBodySize": 4722, + "decodedBodySize": 20336, + "responseStatus": 200, + "serverTiming": [], + "unloadEventStart": 0, + "unloadEventEnd": 0, + "domInteractive": 63.700000047683716, + "domContentLoadedEventStart": 63.700000047683716, + "domContentLoadedEventEnd": 63.700000047683716, + "domComplete": 121, + "loadEventStart": 121, + "loadEventEnd": 121, + "type": "navigate", + "redirectCount": 0, + "activationStart": 0, + "criticalCHRestart": 0, + "notRestoredReasons": null, + "confidence": { + "randomizedTriggerRate": 0.4994798, + "value": "low" + } + }, + "data": [ + { + "name": "http://127.0.0.1:3108/compatibility/data?v=b9e39038b2832f02e54b", + "entryType": "resource", + "startTime": 146.90000009536743, + "duration": 33.299999952316284, + "navigationId": 352, + "initiatorType": "fetch", + "deliveryType": "", + "nextHopProtocol": "http/1.1", + "renderBlockingStatus": "non-blocking", + "contentType": "application/json", + "contentEncoding": "", + "workerStart": 0, + "workerRouterEvaluationStart": 0, + "workerCacheLookupStart": 0, + "workerMatchedSourceType": "", + "workerFinalSourceType": "", + "redirectStart": 0, + "redirectEnd": 0, + "fetchStart": 146.90000009536743, + "domainLookupStart": 146.90000009536743, + "domainLookupEnd": 146.90000009536743, + "connectStart": 146.90000009536743, + "secureConnectionStart": 0, + "connectEnd": 146.90000009536743, + "requestStart": 147.20000004768372, + "responseStart": 178.90000009536743, + "firstInterimResponseStart": 0, + "finalResponseHeadersStart": 178.90000009536743, + "responseEnd": 180.20000004768372, + "transferSize": 2247670, + "encodedBodySize": 2247370, + "decodedBodySize": 2247370, + "responseStatus": 200, + "serverTiming": [] + } + ] + }, + { + "throttle": 4, + "usable_ms": 243.89999997615814, + "navigation": { + "name": "http://127.0.0.1:3108/compatibility", + "entryType": "navigation", + "startTime": 0, + "duration": 72.39999997615814, + "navigationId": 9481, + "initiatorType": "navigation", + "deliveryType": "cache", + "nextHopProtocol": "", + "renderBlockingStatus": "non-blocking", + "contentType": "text/html", + "contentEncoding": "gzip", + "workerStart": 0, + "workerRouterEvaluationStart": 0, + "workerCacheLookupStart": 0, + "workerMatchedSourceType": "", + "workerFinalSourceType": "", + "redirectStart": 0, + "redirectEnd": 0, + "fetchStart": 0.5, + "domainLookupStart": 0.5, + "domainLookupEnd": 0.5, + "connectStart": 0.5, + "secureConnectionStart": 0, + "connectEnd": 0.5, + "requestStart": 1.2000000476837158, + "responseStart": 9.5, + "firstInterimResponseStart": 0, + "finalResponseHeadersStart": 9.5, + "responseEnd": 9.700000047683716, + "transferSize": 300, + "encodedBodySize": 4722, + "decodedBodySize": 20336, + "responseStatus": 200, + "serverTiming": [], + "unloadEventStart": 14.300000071525574, + "unloadEventEnd": 14.300000071525574, + "domInteractive": 34.200000047683716, + "domContentLoadedEventStart": 34.200000047683716, + "domContentLoadedEventEnd": 34.300000071525574, + "domComplete": 72.30000007152557, + "loadEventStart": 72.39999997615814, + "loadEventEnd": 72.39999997615814, + "type": "navigate", + "redirectCount": 0, + "activationStart": 0, + "criticalCHRestart": 0, + "notRestoredReasons": null, + "confidence": { + "randomizedTriggerRate": 0.4994798, + "value": "high" + } + }, + "data": [ + { + "name": "http://127.0.0.1:3108/compatibility/data?v=b9e39038b2832f02e54b", + "entryType": "resource", + "startTime": 100.39999997615814, + "duration": 23, + "navigationId": 9481, + "initiatorType": "fetch", + "deliveryType": "", + "nextHopProtocol": "http/1.1", + "renderBlockingStatus": "non-blocking", + "contentType": "application/json", + "contentEncoding": "", + "workerStart": 0, + "workerRouterEvaluationStart": 0, + "workerCacheLookupStart": 0, + "workerMatchedSourceType": "", + "workerFinalSourceType": "", + "redirectStart": 0, + "redirectEnd": 0, + "fetchStart": 100.39999997615814, + "domainLookupStart": 100.39999997615814, + "domainLookupEnd": 100.39999997615814, + "connectStart": 100.39999997615814, + "secureConnectionStart": 0, + "connectEnd": 100.39999997615814, + "requestStart": 100.70000004768372, + "responseStart": 105, + "firstInterimResponseStart": 0, + "finalResponseHeadersStart": 105, + "responseEnd": 123.39999997615814, + "transferSize": 2247670, + "encodedBodySize": 2247370, + "decodedBodySize": 2247370, + "responseStatus": 200, + "serverTiming": [] + } + ] + } + ] + }, + "journeyAfter": { + "environment": { + "node": "v24.15.0", + "browser": "154.0.8037.57", + "platform": "darwin", + "os": "25.6.0", + "arch": "arm64", + "cpu": "Apple M3", + "viewport": { + "width": 1440, + "height": 1000 + }, + "baseURL": "http://127.0.0.1:3108", + "censusRows": 3662 + }, + "summaries": [ + { + "throttle": 1, + "phase": "prefix-r", + "n": 9, + "p50_ms": 357, + "p95_ms": 394.2000000476837, + "elements": 57526, + "rows": 3592 + }, + { + "throttle": 1, + "phase": "prefix-re", + "n": 9, + "p50_ms": 101.80000007152557, + "p95_ms": 110.19999992847443, + "elements": 49068, + "rows": 3061 + }, + { + "throttle": 1, + "phase": "readFile", + "n": 9, + "p50_ms": 34.59999990463257, + "p95_ms": 35.60000002384186, + "elements": 247, + "rows": 6 + }, + { + "throttle": 1, + "phase": "clear", + "n": 9, + "p50_ms": 23.399999976158142, + "p95_ms": 31.5, + "elements": 1131, + "rows": 55 + }, + { + "throttle": 1, + "phase": "expand-all", + "n": 9, + "p50_ms": 307.7999999523163, + "p95_ms": 341.89999997615814, + "elements": 58649, + "rows": 3662 + }, + { + "throttle": 1, + "phase": "collapse-all", + "n": 9, + "p50_ms": 36.300000071525574, + "p95_ms": 39.5, + "elements": 1131, + "rows": 55 + }, + { + "throttle": 1, + "phase": "typed-readFile", + "n": 9, + "p50_ms": 514.1999999284744, + "p95_ms": 556.9000000953674, + "elements": 247, + "rows": 6 + }, + { + "throttle": 4, + "phase": "prefix-r", + "n": 9, + "p50_ms": 1351.3999999761581, + "p95_ms": 1455.1000000238419, + "elements": 57526, + "rows": 3592 + }, + { + "throttle": 4, + "phase": "prefix-re", + "n": 9, + "p50_ms": 427.7999999523163, + "p95_ms": 456.5, + "elements": 49068, + "rows": 3061 + }, + { + "throttle": 4, + "phase": "readFile", + "n": 9, + "p50_ms": 140.69999992847443, + "p95_ms": 162.30000007152557, + "elements": 247, + "rows": 6 + }, + { + "throttle": 4, + "phase": "clear", + "n": 9, + "p50_ms": 31, + "p95_ms": 36.39999997615814, + "elements": 1131, + "rows": 55 + }, + { + "throttle": 4, + "phase": "expand-all", + "n": 9, + "p50_ms": 1274.6999999284744, + "p95_ms": 1435.6999999284744, + "elements": 58649, + "rows": 3662 + }, + { + "throttle": 4, + "phase": "collapse-all", + "n": 9, + "p50_ms": 160, + "p95_ms": 171, + "elements": 1131, + "rows": 55 + }, + { + "throttle": 4, + "phase": "typed-readFile", + "n": 9, + "p50_ms": 1972.3999999761581, + "p95_ms": 2101.2000000476837, + "elements": 247, + "rows": 6 + } + ], + "samples": { + "1x/prefix-r": { + "rows": 3592, + "elements": 57526, + "ms": [ + 371.60000002384186, + 383.2999999523163, + 335.89999997615814, + 394.2000000476837, + 345.7999999523163, + 357, + 357, + 356.2000000476837, + 346.1999999284744 + ] + }, + "1x/prefix-re": { + "rows": 3061, + "elements": 49068, + "ms": [ + 110.19999992847443, + 99.79999995231628, + 101.80000007152557, + 98.19999992847443, + 105.60000002384186, + 105.60000002384186, + 97.69999992847443, + 107.20000004768372, + 95.30000007152557 + ] + }, + "1x/readFile": { + "rows": 6, + "elements": 247, + "ms": [ + 35.60000002384186, + 31.90000009536743, + 35.59999990463257, + 34.59999990463257, + 34.799999952316284, + 35.39999997615814, + 33.10000002384186, + 32.90000009536743, + 31.800000071525574 + ] + }, + "1x/clear": { + "rows": 55, + "elements": 1131, + "ms": [ + 23.399999976158142, + 22.800000071525574, + 18.899999976158142, + 24.700000047683716, + 26.799999952316284, + 16.59999990463257, + 31.5, + 17.5, + 24.299999952316284 + ] + }, + "1x/expand-all": { + "rows": 3662, + "elements": 58649, + "ms": [ + 341.89999997615814, + 307.39999997615814, + 313.5, + 298.59999990463257, + 335.7999999523163, + 298.7999999523163, + 307.7999999523163, + 326.7999999523163, + 291.10000002384186 + ] + }, + "1x/collapse-all": { + "rows": 55, + "elements": 1131, + "ms": [ + 34.60000002384186, + 36.300000071525574, + 35.89999997615814, + 38.699999928474426, + 39.199999928474426, + 39.5, + 36.300000071525574, + 37.39999997615814, + 34.10000002384186 + ] + }, + "1x/typed-readFile": { + "rows": 6, + "elements": 247, + "ms": [ + 506.10000002384186, + 540.6000000238419, + 485.40000009536743, + 539.6999999284744, + 501.39999997615814, + 556.9000000953674, + 514.1999999284744, + 539, + 485 + ] + }, + "4x/prefix-r": { + "rows": 3592, + "elements": 57526, + "ms": [ + 1453, + 1342.7999999523163, + 1353.6000000238419, + 1351.3999999761581, + 1455.1000000238419, + 1309.0999999046326, + 1397.5, + 1299.8999999761581, + 1324.5 + ] + }, + "4x/prefix-re": { + "rows": 3061, + "elements": 49068, + "ms": [ + 418.3000000715256, + 419.6999999284744, + 456.5, + 440.60000002384186, + 427.7999999523163, + 422.1999999284744, + 425, + 456.3000000715256, + 441 + ] + }, + "4x/readFile": { + "rows": 6, + "elements": 247, + "ms": [ + 138.10000002384186, + 138.79999995231628, + 140.69999992847443, + 162.30000007152557, + 145.5, + 137.10000002384186, + 140.20000004768372, + 145.89999997615814, + 160.80000007152557 + ] + }, + "4x/clear": { + "rows": 55, + "elements": 1131, + "ms": [ + 31, + 33, + 31.5, + 30, + 28.700000047683716, + 27.5, + 29.600000023841858, + 36.39999997615814, + 35.89999997615814 + ] + }, + "4x/expand-all": { + "rows": 3662, + "elements": 58649, + "ms": [ + 1264.5, + 1387.7999999523163, + 1327.4000000953674, + 1201.9000000953674, + 1274.6999999284744, + 1273.1000000238419, + 1241.8999999761581, + 1435.6999999284744, + 1354.0999999046326 + ] + }, + "4x/collapse-all": { + "rows": 55, + "elements": 1131, + "ms": [ + 159.40000009536743, + 160, + 165.60000002384186, + 150.89999997615814, + 171, + 152.89999997615814, + 163.89999997615814, + 166.89999997615814, + 141.09999990463257 + ] + }, + "4x/typed-readFile": { + "rows": 6, + "elements": 247, + "ms": [ + 2051.8000000715256, + 2021.2999999523163, + 1896.2999999523163, + 1860.1999999284744, + 2101.2000000476837, + 1972.3999999761581, + 1930.6000000238419, + 2074.399999976158, + 1914.2999999523163 + ] + } + }, + "loads": [ + { + "throttle": 1, + "usable_ms": 133, + "navigation": { + "name": "http://127.0.0.1:3108/compatibility", + "entryType": "navigation", + "startTime": 0, + "duration": 70.5, + "navigationId": 379, + "initiatorType": "navigation", + "deliveryType": "", + "nextHopProtocol": "http/1.1", + "renderBlockingStatus": "non-blocking", + "contentType": "text/html", + "contentEncoding": "gzip", + "workerStart": 0, + "workerRouterEvaluationStart": 0, + "workerCacheLookupStart": 0, + "workerMatchedSourceType": "", + "workerFinalSourceType": "", + "redirectStart": 0, + "redirectEnd": 0, + "fetchStart": 0.7999999523162842, + "domainLookupStart": 0.7999999523162842, + "domainLookupEnd": 0.7999999523162842, + "connectStart": 0.7999999523162842, + "secureConnectionStart": 0, + "connectEnd": 0.7999999523162842, + "requestStart": 1.7999999523162842, + "responseStart": 10.5, + "firstInterimResponseStart": 0, + "finalResponseHeadersStart": 10.5, + "responseEnd": 10.899999976158142, + "transferSize": 5020, + "encodedBodySize": 4720, + "decodedBodySize": 20336, + "responseStatus": 200, + "serverTiming": [], + "unloadEventStart": 0, + "unloadEventEnd": 0, + "domInteractive": 37.199999928474426, + "domContentLoadedEventStart": 37.199999928474426, + "domContentLoadedEventEnd": 37.199999928474426, + "domComplete": 70.5, + "loadEventStart": 70.5, + "loadEventEnd": 70.5, + "type": "navigate", + "redirectCount": 0, + "activationStart": 0, + "criticalCHRestart": 0, + "notRestoredReasons": null, + "confidence": { + "randomizedTriggerRate": 0.4994798, + "value": "low" + } + }, + "data": [ + { + "name": "http://127.0.0.1:3108/compatibility/data?v=b9e39038b2832f02e54b", + "entryType": "resource", + "startTime": 87.69999992847443, + "duration": 16, + "navigationId": 379, + "initiatorType": "fetch", + "deliveryType": "", + "nextHopProtocol": "http/1.1", + "renderBlockingStatus": "non-blocking", + "contentType": "application/json", + "contentEncoding": "", + "workerStart": 0, + "workerRouterEvaluationStart": 0, + "workerCacheLookupStart": 0, + "workerMatchedSourceType": "", + "workerFinalSourceType": "", + "redirectStart": 0, + "redirectEnd": 0, + "fetchStart": 87.69999992847443, + "domainLookupStart": 87.69999992847443, + "domainLookupEnd": 87.69999992847443, + "connectStart": 87.69999992847443, + "secureConnectionStart": 0, + "connectEnd": 87.69999992847443, + "requestStart": 88, + "responseStart": 100.89999997615814, + "firstInterimResponseStart": 0, + "finalResponseHeadersStart": 100.89999997615814, + "responseEnd": 103.69999992847443, + "transferSize": 2247670, + "encodedBodySize": 2247370, + "decodedBodySize": 2247370, + "responseStatus": 200, + "serverTiming": [] + } + ] + }, + { + "throttle": 4, + "usable_ms": 315.5, + "navigation": { + "name": "http://127.0.0.1:3108/compatibility", + "entryType": "navigation", + "startTime": 0, + "duration": 80.79999995231628, + "navigationId": 9274, + "initiatorType": "navigation", + "deliveryType": "cache", + "nextHopProtocol": "", + "renderBlockingStatus": "non-blocking", + "contentType": "text/html", + "contentEncoding": "gzip", + "workerStart": 0, + "workerRouterEvaluationStart": 0, + "workerCacheLookupStart": 0, + "workerMatchedSourceType": "", + "workerFinalSourceType": "", + "redirectStart": 0, + "redirectEnd": 0, + "fetchStart": 0.2999999523162842, + "domainLookupStart": 0.2999999523162842, + "domainLookupEnd": 0.2999999523162842, + "connectStart": 0.2999999523162842, + "secureConnectionStart": 0, + "connectEnd": 0.2999999523162842, + "requestStart": 1.100000023841858, + "responseStart": 4.899999976158142, + "firstInterimResponseStart": 0, + "finalResponseHeadersStart": 4.899999976158142, + "responseEnd": 5.100000023841858, + "transferSize": 300, + "encodedBodySize": 4720, + "decodedBodySize": 20336, + "responseStatus": 200, + "serverTiming": [], + "unloadEventStart": 21.100000023841858, + "unloadEventEnd": 21.100000023841858, + "domInteractive": 41, + "domContentLoadedEventStart": 41, + "domContentLoadedEventEnd": 41, + "domComplete": 80.60000002384186, + "loadEventStart": 80.79999995231628, + "loadEventEnd": 80.79999995231628, + "type": "navigate", + "redirectCount": 0, + "activationStart": 0, + "criticalCHRestart": 0, + "notRestoredReasons": null, + "confidence": { + "randomizedTriggerRate": 0.4994798, + "value": "high" + } + }, + "data": [ + { + "name": "http://127.0.0.1:3108/compatibility/data?v=b9e39038b2832f02e54b", + "entryType": "resource", + "startTime": 107.69999992847443, + "duration": 29, + "navigationId": 9274, + "initiatorType": "fetch", + "deliveryType": "", + "nextHopProtocol": "http/1.1", + "renderBlockingStatus": "non-blocking", + "contentType": "application/json", + "contentEncoding": "", + "workerStart": 0, + "workerRouterEvaluationStart": 0, + "workerCacheLookupStart": 0, + "workerMatchedSourceType": "", + "workerFinalSourceType": "", + "redirectStart": 0, + "redirectEnd": 0, + "fetchStart": 107.69999992847443, + "domainLookupStart": 107.69999992847443, + "domainLookupEnd": 107.69999992847443, + "connectStart": 107.69999992847443, + "secureConnectionStart": 0, + "connectEnd": 107.69999992847443, + "requestStart": 108.39999997615814, + "responseStart": 111.79999995231628, + "firstInterimResponseStart": 0, + "finalResponseHeadersStart": 111.79999995231628, + "responseEnd": 136.69999992847443, + "transferSize": 2247670, + "encodedBodySize": 2247370, + "decodedBodySize": 2247370, + "responseStatus": 200, + "serverTiming": [] + } + ] + } + ] + } + }, + "memoBootstrap": { + "resamples": 10000, + "seed": 42, + "random": "LCG: state = (1664525 * state + 1013904223) mod 2^32", + "method": "independent before/after resampling; nearest-rank 2.5/97.5 percentiles of before median minus after median", + "intervals": { + "1x": { + "low_ms": 2.700000047683716, + "high_ms": 20.59999990463257 + }, + "4x": { + "low_ms": 15.899999856948853, + "high_ms": 67.29999995231628 + } + } + }, + "rejectedCssTrials": [ + { + "variant": "baseline", + "ms": 2577.600000023842, + "rows": 3592, + "height_px": 210587 + }, + { + "variant": "baseline", + "ms": 2374.7999999523163, + "rows": 3592, + "height_px": 210587 + }, + { + "variant": "baseline", + "ms": 2537.100000023842, + "rows": 3592, + "height_px": 210587 + }, + { + "variant": "rowVisibility", + "ms": 2542.0999999046326, + "rows": 3592, + "height_px": 210587 + }, + { + "variant": "rowVisibility", + "ms": 2840.5, + "rows": 3592, + "height_px": 210587 + }, + { + "variant": "rowVisibility", + "ms": 2445, + "rows": 3592, + "height_px": 210587 + }, + { + "variant": "cellVisibility", + "ms": 1168.6000000238419, + "rows": 3592, + "height_px": 66785 + }, + { + "variant": "cellVisibility", + "ms": 1157.1999999284744, + "rows": 3592, + "height_px": 67864 + }, + { + "variant": "cellVisibility", + "ms": 1105, + "rows": 3592, + "height_px": 67864 + } + ] +} diff --git a/package.json b/package.json index 2208a4b66..3d9161021 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "scriptc": "tsx packages/cli/src/main.ts" }, "devDependencies": { + "@playwright/test": "1.63.0", "@types/node": "^24.0.0", "effect": "3.22.2", "eslint": "^9.20.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4284ef410..d6f3c76f7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,6 +11,9 @@ importers: .: devDependencies: + '@playwright/test': + specifier: 1.63.0 + version: 1.63.0 '@types/node': specifier: ^24.0.0 version: 24.13.3 @@ -853,6 +856,11 @@ packages: cpu: [x64] os: [win32] + '@playwright/test@1.63.0': + resolution: {integrity: sha512-oxMK4vllB9RK5NQ2l1pq1IfOf2AvnEuj/vYGDj0H2nMtmtZpKtCwt/l00GEO6xjGfpBNAvjovvYdCm50dRQkpQ==} + engines: {node: '>=20'} + hasBin: true + '@renovatebot/pep440@4.2.1': resolution: {integrity: sha512-2FK1hF93Fuf1laSdfiEmJvSJPVIDHEUTz68D3Fi9s0IZrrpaEcj6pTFBTbYvsgC5du4ogrtf5re7yMMvrKNgkw==} engines: {node: ^20.9.0 || ^22.11.0 || ^24, pnpm: ^10.0.0} @@ -2230,6 +2238,16 @@ packages: resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==} engines: {node: '>=12'} + playwright-core@1.63.0: + resolution: {integrity: sha512-rYCsBF/M5HjUch52bbtVONEFjv6Xu8sm8h72dNlR5bzIE1fvC/bxgspzkjSfU+MweEMmPM8KJebG6nnyxo5mCg==} + engines: {node: '>=20'} + hasBin: true + + playwright@1.63.0: + resolution: {integrity: sha512-+7ziBLidS4NaNCdt57SUDT+wYmmd5fmiQejUic/kb+YsYSCPyOOE9sebzMjNmQrsnNpDJqd4WHvV/8lfKfUDUg==} + engines: {node: '>=20'} + hasBin: true + postcss@8.5.16: resolution: {integrity: sha512-vuwillviilfKZsg0VGj5R/YwwcHx4SLsIOI/7K6mQkWx+l5cUHTjj5g0AasTBcyXsbfTgrwsUNmVUb5xVwyPwg==} engines: {node: ^10 || ^12 || >=14} @@ -3114,6 +3132,10 @@ snapshots: '@oxc-transform/binding-win32-x64-msvc@0.111.0': optional: true + '@playwright/test@1.63.0': + dependencies: + playwright: 1.63.0 + '@renovatebot/pep440@4.2.1': {} '@rolldown/binding-android-arm64@1.0.0-rc.1': @@ -4556,6 +4578,12 @@ snapshots: picomatch@4.0.5: {} + playwright-core@1.63.0: {} + + playwright@1.63.0: + dependencies: + playwright-core: 1.63.0 + postcss@8.5.16: dependencies: nanoid: 3.3.15 diff --git a/tests/browser/compatibility-oracle.ts b/tests/browser/compatibility-oracle.ts new file mode 100644 index 000000000..6ff18536b --- /dev/null +++ b/tests/browser/compatibility-oracle.ts @@ -0,0 +1,22 @@ +import snapshot from "../../docs/src/generated/node-v24-compatibility.json"; + +export { snapshot }; +const chapters = new Map(snapshot.chapters.map((chapter) => [chapter.slug, chapter.title])); +export const label = (row: typeof snapshot.rows[number]) => row.depth === 0 ? chapters.get(row.chapter) ?? row.label : row.label; + +// Select matches and their ancestor chain directly from the published preorder +// census, independently of the UI's tree/filter implementation. +export function expectedLabels(query: string, staticStatus = "all", dynamicStatus = "all") { + const included = new Set(); + const ancestors: typeof snapshot.rows = []; + for (const row of snapshot.rows) { + ancestors.length = row.depth; + ancestors[row.depth] = row; + if (staticStatus !== "all" && row.static.status !== staticStatus) continue; + if (dynamicStatus !== "all" && row.dynamic.status !== dynamicStatus) continue; + const text = [chapters.get(row.chapter), row.kind, row.name, row.signature, row.apiSymbol, row.static.detail, row.dynamic.detail].join(" ").toLocaleLowerCase(); + if (!text.includes(query.toLocaleLowerCase())) continue; + for (const ancestor of ancestors) if (ancestor) included.add(ancestor.id); + } + return snapshot.rows.filter((row) => included.has(row.id)).map(label); +} diff --git a/tests/browser/compatibility.bench.ts b/tests/browser/compatibility.bench.ts new file mode 100644 index 000000000..d7ca5460a --- /dev/null +++ b/tests/browser/compatibility.bench.ts @@ -0,0 +1,75 @@ +import { test, expect } from "@playwright/test"; +import { writeFileSync } from "node:fs"; +import { arch, cpus, platform, release } from "node:os"; +import { expectedLabels, label, snapshot } from "./compatibility-oracle"; + +test("compatibility lookup latency and rendered work", async ({ page, browser, baseURL }) => { + const iterations = Number(process.env.SCRIPTC_DOCS_ITERATIONS ?? "9"); + if (!Number.isInteger(iterations) || iterations < 1 || iterations > 100) throw new Error("SCRIPTC_DOCS_ITERATIONS must be an integer from 1 to 100"); + test.setTimeout(30_000 + iterations * 30_000); + const session = await page.context().newCDPSession(page); + const samples: { phase: string; throttle: number; ms: number; rows: number; elements: number }[] = []; + const loads: object[] = []; + // Time actual browser input to two animation frames, not command round trips. + // Result checks run outside the interval. For sequential typing, also retain + // the first-input-to-final-result duration across all intermediate renders. + await page.addInitScript(() => { + const state = window as typeof window & { firstInput: number | null; latency: { event: string; ms: number; journey_ms: number; rows: number; elements: number } | null }; + for (const type of ["input", "click"]) document.addEventListener(type, (e) => { + if (!(e.target instanceof HTMLElement)) return; + const event = e.target instanceof HTMLInputElement ? e.target.value : e.target.textContent ?? ""; + if (type === "click" && !["Expand all", "Collapse all"].includes(event)) return; + const start = performance.now(); + state.firstInput ??= start; + requestAnimationFrame(() => requestAnimationFrame(() => { + const now = performance.now(); + state.latency = { event, ms: now - start, journey_ms: now - state.firstInput!, rows: document.querySelectorAll("tbody tr").length, elements: document.querySelectorAll("*").length }; + })); + }, true); + }); + const roots = snapshot.rows.filter((row) => row.depth === 0).map(label); + for (const throttle of [1, 4]) { + await session.send("Emulation.setCPUThrottlingRate", { rate: throttle }); + await page.goto("/compatibility"); + await expect(page.getByRole("button", { name: "Expand all", exact: true })).toBeVisible(); + loads.push(await page.evaluate((throttle) => ({ + throttle, + usable_ms: performance.now(), + navigation: performance.getEntriesByType("navigation")[0].toJSON(), + data: performance.getEntriesByType("resource").filter((entry) => entry.name.includes("/compatibility/data")).map((entry) => entry.toJSON()), + }), throttle)); + const search = page.getByRole("searchbox"); + async function sample(phase: string, action: () => Promise, event: string, labels: string[]) { + await page.evaluate(() => { + const state = window as typeof window & { latency: unknown; firstInput: number | null }; + state.latency = null; + state.firstInput = null; + }); + await action(); + await expect(page.locator("tbody tr td:first-child a")).toHaveText(labels); + await page.waitForFunction((event) => (window as typeof window & { latency: { event: string } | null }).latency?.event === event, event); + const result = await page.evaluate(() => (window as typeof window & { latency: { ms: number; journey_ms: number; rows: number; elements: number } }).latency); + expect(result.rows).toBe(labels.length); + samples.push({ phase, throttle, ...result, ms: phase === "typed-readFile" ? result.journey_ms : result.ms }); + } + for (let i = 0; i < iterations; i++) { + await sample("prefix-r", () => search.fill("r"), "r", expectedLabels("r")); + await sample("prefix-re", () => search.fill("re"), "re", expectedLabels("re")); + await sample("readFile", () => search.fill("readFile"), "readFile", expectedLabels("readFile")); + await sample("clear", () => search.fill(""), "", roots); + await sample("expand-all", () => page.getByRole("button", { name: "Expand all", exact: true }).click(), "Expand all", snapshot.rows.map(label)); + await sample("collapse-all", () => page.getByRole("button", { name: "Collapse all", exact: true }).click(), "Collapse all", roots); + await sample("typed-readFile", () => search.pressSequentially("readFile"), "readFile", expectedLabels("readFile")); + await search.fill(""); + await expect(page.locator("tbody tr")).toHaveCount(roots.length); + } + } + const summaries = [1, 4].flatMap((throttle) => [...new Set(samples.map((sample) => sample.phase))].map((phase) => { + const group = samples.filter((sample) => sample.throttle === throttle && sample.phase === phase); + const times = group.map((sample) => sample.ms).sort((a, b) => a - b); + return { throttle, phase, n: times.length, p50_ms: times[Math.ceil(times.length * 0.5) - 1], p95_ms: times[Math.ceil(times.length * 0.95) - 1], elements: group[0].elements, rows: group[0].rows }; + })); + const result = { environment: { node: process.version, browser: browser.version(), platform: platform(), os: release(), arch: arch(), cpu: cpus()[0].model, viewport: { width: 1440, height: 1000 }, baseURL, censusRows: snapshot.rows.length }, summaries, samples, loads }; + if (process.env.SCRIPTC_DOCS_RESULT) writeFileSync(process.env.SCRIPTC_DOCS_RESULT, JSON.stringify(result, null, 2) + "\n"); + console.log(JSON.stringify(result, null, 2)); +}); diff --git a/tests/browser/compatibility.test.ts b/tests/browser/compatibility.test.ts new file mode 100644 index 000000000..b18864dbd --- /dev/null +++ b/tests/browser/compatibility.test.ts @@ -0,0 +1,120 @@ +import { expect, test, type Page } from "@playwright/test"; +import { expectedLabels, label, snapshot } from "./compatibility-oracle"; + +const rowLabels = (page: Page) => page.locator("tbody tr td:first-child a"); + +test.beforeEach(async ({ page }) => { + await page.goto("/compatibility"); + await expect(page.getByRole("button", { name: "Expand all", exact: true })).toBeVisible(); +}); + +test("all APIs remain reachable without eagerly mounting hidden tooltips", async ({ page }) => { + await expect(rowLabels(page)).toHaveText(snapshot.rows.filter((row) => row.depth === 0).map(label)); + await page.getByRole("button", { name: "Expand all", exact: true }).click(); + await expect(rowLabels(page)).toHaveText(snapshot.rows.map(label)); + // Stable work ceilings, not noisy CI timing: no hidden popup DOM, and a + // bounded number of elements per API even when the whole census is open. + await expect(page.getByRole("tooltip", { includeHidden: true })).toHaveCount(0); + const elements = await page.locator("*").count(); + expect(elements).toBeLessThanOrEqual(snapshot.rows.length * 17 + 500); + await page.getByRole("button", { name: "Collapse all", exact: true }).click(); + await expect(rowLabels(page)).toHaveText(snapshot.rows.filter((row) => row.depth === 0).map(label)); +}); + +test("search and independent tier filters preserve every match and its parents", async ({ page }) => { + const search = page.getByRole("searchbox"); + for (const query of ["r", "readFile", "file"]) { + await search.fill(query); + await expect(rowLabels(page)).toHaveText(expectedLabels(query)); + } + await page.getByRole("combobox", { name: /^Static/ }).selectOption("partial"); + await expect(rowLabels(page)).toHaveText(expectedLabels("file", "partial")); + await page.getByRole("combobox", { name: /^Dynamic/ }).selectOption("supported"); + await expect(rowLabels(page)).toHaveText(expectedLabels("file", "partial", "supported")); + await search.fill("scriptc-no-such-api-unique"); + await expect(page.getByText("No API rows match these filters.")).toBeVisible(); + await page.getByRole("button", { name: "Reset filters", exact: true }).click(); + await expect(search).toHaveValue(""); + await expect(page.getByRole("combobox", { name: /^Static/ })).toHaveValue("all"); + await expect(page.getByRole("combobox", { name: /^Dynamic/ })).toHaveValue("all"); + await expect(rowLabels(page)).toHaveText(snapshot.rows.filter((row) => row.depth === 0).map(label)); +}); + +test("retained API badges do not rerender on every search keystroke", async ({ page }) => { + const session = await page.context().newCDPSession(page); + await session.send("Debugger.enable"); + await session.send("Profiler.enable"); + await session.send("Profiler.startPreciseCoverage", { callCount: true, detailed: false }); + await page.mouse.move(0, 0); + await page.getByRole("searchbox").fill("r"); + await expect(rowLabels(page)).toHaveText(expectedLabels("r")); + const initial = await session.send("Profiler.takePreciseCoverage"); + const markers = [{ text: "Verification:", column: 3 }, { text: "Node.js Stability", column: 2 }]; + const candidates: { text: string; scriptId: string; start: number; end: number; count: number }[] = []; + for (const script of initial.result) { + if (!script.url.includes("/_next/")) continue; + const { scriptSource } = await session.send("Debugger.getScriptSource", { scriptId: script.scriptId }); + for (const fn of script.functions) { + const range = fn.ranges[0]; + // The smallest covered function containing the badge's fixed text is + // its renderer. This observes real calls without production counters + // or depending on identifiers rewritten by Next's minifier. + for (const { text } of markers) { + if (scriptSource.slice(range.startOffset, range.endOffset).includes(text)) { + candidates.push({ text, scriptId: script.scriptId, start: range.startOffset, end: range.endOffset, count: range.count }); + } + } + } + } + candidates.sort((a, b) => (a.end - a.start) - (b.end - b.start)); + const badges = markers.map(({ text, column }) => { + const badge = candidates.find((candidate) => candidate.text === text); + expect(badge).toBeDefined(); + expect(badge!.count).toBeGreaterThan(0); + return { ...badge!, column }; + }); + await page.getByRole("searchbox").fill("re"); + await expect(rowLabels(page)).toHaveText(expectedLabels("re")); + const next = await session.send("Profiler.takePreciseCoverage"); + for (const badge of badges) { + const fn = next.result.find((script) => script.scriptId === badge.scriptId)?.functions.find((fn) => fn.ranges[0].startOffset === badge.start); + // Small allowance for hover/focus work, never thousands of unchanged + // badge renders. Precise coverage resets counts between snapshots. + expect(fn?.ranges[0].count ?? 0).toBeLessThanOrEqual(16); + // V8 may omit a function with no calls. An actual hover render proves + // the same renderer is still being observed after the zero interval. + const target = page.locator(`tbody td:nth-child(${badge.column}) > span[tabindex="0"]`).first(); + await target.hover(); + await expect(target.getByRole("tooltip")).toBeVisible(); + const control = await session.send("Profiler.takePreciseCoverage"); + const rendered = control.result.find((script) => script.scriptId === badge.scriptId)?.functions.find((fn) => fn.ranges[0].startOffset === badge.start); + expect(rendered?.ranges[0].count).toBeGreaterThan(0); + } + await session.send("Profiler.stopPreciseCoverage"); +}); + +test("status and stability details remain available to mouse and keyboard users", async ({ page }) => { + for (const column of [3, 2]) { + const badge = page.locator(`tbody td:nth-child(${column}) > span[tabindex="0"]`).first(); + const title = await badge.locator("span[title]").first().getAttribute("title"); + expect(title).toBeTruthy(); + await badge.hover(); + const tooltip = badge.getByRole("tooltip"); + await expect(tooltip).toBeVisible(); + await expect(tooltip).toHaveText(title!, { useInnerText: true }); + await page.mouse.move(0, 0); + await expect(page.getByRole("tooltip", { includeHidden: true })).toHaveCount(0); + await page.keyboard.press("Tab"); + await badge.focus(); + await expect(tooltip).toBeVisible(); + await expect(tooltip).toHaveText(title!, { useInnerText: true }); + await badge.hover(); + await page.mouse.move(0, 0); + await expect(tooltip).toBeVisible(); // Focus survives pointer leave. + await badge.hover(); + await page.getByRole("searchbox").focus(); + await expect(tooltip).toBeVisible(); // Hover survives keyboard blur. + await page.mouse.move(0, 0); + await expect(page.getByRole("tooltip", { includeHidden: true })).toHaveCount(0); + } +});