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}