REAL SHOWCASE SOURCEperformance-timeline-runtime
1 个文件 · 90 行 · TypeScript
// ===== showcase/src/examples/components/performance_timeline.ts ===== import { DrawList, RenderBox, RenderButton, RenderPageHeader, RenderStackPanel, RenderText, RenderWrapPanel, constrainSize, paintFramePerformanceTimelineChart, resolveFramePerformanceTimelineChartState, type BoxConstraints, type FramePerformanceTimelineSample, type LayoutContext, type Offset, type PaintContext,} from 'ds-ui' class PerformanceTimelineSurface extends RenderBox { samples: FramePerformanceTimelineSample[] constructor(samples: FramePerformanceTimelineSample[]) { super({ height: 270 }) this.samples = samples } visitChildren(): void {} performLayout(constraints: BoxConstraints, _context: LayoutContext): void { this.size = constrainSize(constraints, { width: constraints.maxWidth === Infinity ? 720 : constraints.maxWidth, height: 270 }) } performPaint(context: PaintContext, offset: Offset): void { paintFramePerformanceTimelineChart( new DrawList(context), context, { x: offset.x + 8, y: offset.y + 8, width: Math.max(0, this.size.width - 16), height: Math.max(0, this.size.height - 16) }, this.samples, { frameBudgetMs: 16.7, maxSamples: 80, showLegend: true }, ) }} function createSamples(slowEvery = 9): FramePerformanceTimelineSample[] { return Array.from({ length: 72 }, (_, index) => { const slow = index % slowEvery === 0 const layoutMs = 2.2 + (index % 5) * 0.4 const paintMs = 3.6 + Math.abs(Math.sin(index / 5)) * 3.8 const compositeMs = 1.1 + (index % 3) * 0.25 return { layoutMs, paintMs, compositeMs, totalMs: layoutMs + paintMs + compositeMs + (slow ? 11 : 2.4) } })} export function createPerformanceTimelineExample(): RenderStackPanel { let samples = createSamples() const surface = new PerformanceTimelineSurface(samples) const status = new RenderText('', { role: 'secondary' }) const syncStatus = (): void => { const state = resolveFramePerformanceTimelineChartState(samples, { frameBudgetMs: 16.7, maxSamples: 80 }) status.text = `${state.visibleSampleCount} 帧 · 慢帧 ${state.slowFrameCount} · 预算 ${state.frameBudgetMs}ms` } const actions = new RenderWrapPanel({ spacing: 8, runSpacing: 8 }) actions.addChild(new RenderButton({ label: '正常负载', onClick: () => { samples = createSamples(18); surface.samples = samples; surface.markNeedsPaint(); syncStatus() }, })) actions.addChild(new RenderButton({ label: '模拟慢帧', variant: 'primary', onClick: () => { samples = createSamples(5); surface.samples = samples; surface.markNeedsPaint(); syncStatus() }, })) actions.addChild(new RenderButton({ label: '清空样本', onClick: () => { samples = []; surface.samples = samples; surface.markNeedsPaint(); syncStatus() }, })) syncStatus() const panel = new RenderStackPanel({ orientation: 'vertical', spacing: 12, crossAxisAlignment: 'stretch' }) panel.addChild(new RenderPageHeader({ title: 'PerformanceTimeline 帧性能时间线', description: '将布局、绘制、合成和其他耗时堆叠呈现,并用 16.7ms 预算线标记慢帧。', })) panel.addChild(actions) panel.addChild(surface, 1) panel.addChild(status) panel.padding = 18 return panel}