PageSourceSearch

https://degenai.dev/js/plugins/chart-plugins/shared/frame-cost.spec.bxfx4c49xk.js

js degenai.dev collected 2026-10-06 14:18:40 UTC 3,528 bytes, 100 lines download raw bytes

1import { describe, it, expect, beforeEach } from 'vitest';
2import {
3    enableFrameCost,
4    isFrameCostEnabled,
5    resetFrameCost,
6    sampleFrame,
7    getFrameCostReport,
8} from './frame-cost.js';
9
10describe('frame-cost sampler', () => {
11    beforeEach(() => {
12        enableFrameCost(false);
13        resetFrameCost();
14    });
15
16    it('records nothing while disabled', () => {
17        expect(isFrameCostEnabled()).toBe(false);
18        sampleFrame('layer', 12, 'compute');
19        expect(getFrameCostReport()).toEqual({});
20    });
21
22    it('records per-layer percentiles once enabled', () => {
23        enableFrameCost();
24        // 1..100 ms so the percentile positions are trivially checkable.
25        for (let i = 1; i <= 100; i++) sampleFrame('layer', i);
26
27        const r = getFrameCostReport().layer;
28        expect(r.frames).toBe(100);
29        expect(r.p50).toBe(50);
30        expect(r.p95).toBe(95);
31        expect(r.max).toBe(100);
32        expect(r.mean).toBe(50.5);
33    });
34
35    it('keeps layers independent', () => {
36        enableFrameCost();
37        sampleFrame('a', 5);
38        sampleFrame('b', 50);
39
40        const r = getFrameCostReport();
41        expect(r.a.max).toBe(5);
42        expect(r.b.max).toBe(50);
43    });
44
45    it('counts render paths so the compute-vs-remap ratio is readable', () => {
46        enableFrameCost();
47        sampleFrame('heatmap', 20, 'compute');
48        for (let i = 0; i < 9; i++) sampleFrame('heatmap', 0.4, 'remap');
49
50        const r = getFrameCostReport().heatmap;
51        expect(r.paths).toEqual({ compute: 1, remap: 9 });
52        // The whole point of viewport decoupling: the expensive path is the rare one.
53        expect(r.paths.remap / r.frames).toBeGreaterThan(0.8);
54    });
55
56    it('ages path counts out of the window with their samples', () => {
57        enableFrameCost();
58        // A burst of computes, then a long drag that pushes them all out of the 240-frame window.
59        for (let i = 0; i < 10; i++) sampleFrame('heatmap', 20, 'compute');
60        for (let i = 0; i < 240; i++) sampleFrame('heatmap', 0.4, 'remap');
61
62        const r = getFrameCostReport().heatmap;
63        // Counts must describe the SAME frames the percentiles do -- a lifetime tally would still
64        // be claiming 10 computes here, long after none of them were in the reported window.
65        expect(r.paths).toEqual({ remap: 240 });
66        expect(r.frames).toBe(240);
67        expect(r.max).toBe(0.4);
68    });
69
70    it('bounds memory by overwriting the oldest samples', () => {
71        enableFrameCost();
72        // 500 samples into a 240-slot window: only the last 240 survive, so the early
73        // (cheap) frames must have been evicted by the later (expensive) ones.
74        for (let i = 1; i <= 500; i++) sampleFrame('layer', i);
75
76        const r = getFrameCostReport().layer;
77        expect(r.frames).toBe(240);
78        expect(r.max).toBe(500);
79        expect(r.p50).toBeGreaterThan(240);
80    });
81
82    it('ignores non-finite durations rather than poisoning the percentiles', () => {
83        enableFrameCost();
84        sampleFrame('layer', NaN);
85        sampleFrame('layer', Infinity);
86        sampleFrame('layer', undefined);
87        sampleFrame('layer', 7);
88
89        const r = getFrameCostReport().layer;
90        expect(r.frames).toBe(1);
91        expect(r.max).toBe(7);
92    });
93
94    it('drops all samples when disabled again', () => {
95        enableFrameCost();
96        sampleFrame('layer', 9);
97        enableFrameCost(false);
98        expect(getFrameCostReport()).toEqual({});
99    });
100});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.