Timing bar
Horizontal request-phase waterfall, one segment per phase.
Basic usage
Data comes in via props; rendered as pure SVG with no third-party charting dependency.
Colors come from the --viz-1..8 tokens, colorblind-friendly.
背景
<script setup lang="ts">
import { CfTimingBar } from '@chufix-design/vue';
const phases = [
{ label: 'DNS', start: 0, end: 12, colorIndex: 6 },
{ label: 'Connect', start: 12, end: 38, colorIndex: 0 },
{ label: 'TLS', start: 38, end: 92, colorIndex: 2 },
{ label: 'TTFB', start: 92, end: 245, colorIndex: 1 },
{ label: 'Download', start: 245, end: 312, colorIndex: 3 },
];
</script>
<template>
<CfTimingBar :phases="phases" />
</template> <script setup>
import { CfTimingBar } from '@chufix-design/vue';
const phases = [
{ label: 'DNS', start: 0, end: 12, colorIndex: 6 },
{ label: 'Connect', start: 12, end: 38, colorIndex: 0 },
{ label: 'TLS', start: 38, end: 92, colorIndex: 2 },
{ label: 'TTFB', start: 92, end: 245, colorIndex: 1 },
{ label: 'Download', start: 245, end: 312, colorIndex: 3 },
];
</script>
<template>
<CfTimingBar :phases="phases" />
</template> import { CfTimingBar } from '@chufix-design/react';
export default function Demo() {
const phases = [
{ label: 'DNS', start: 0, end: 12, colorIndex: 6 },
{ label: 'Connect', start: 12, end: 38, colorIndex: 0 },
{ label: 'TLS', start: 38, end: 92, colorIndex: 2 },
{ label: 'TTFB', start: 92, end: 245, colorIndex: 1 },
{ label: 'Download', start: 245, end: 312, colorIndex: 3 },
];
return (
<>
<CfTimingBar phases={phases} />
</>
);
} import { CfTimingBar } from '@chufix-design/react';
export default function Demo() {
const phases = [
{ label: 'DNS', start: 0, end: 12, colorIndex: 6 },
{ label: 'Connect', start: 12, end: 38, colorIndex: 0 },
{ label: 'TLS', start: 38, end: 92, colorIndex: 2 },
{ label: 'TTFB', start: 92, end: 245, colorIndex: 1 },
{ label: 'Download', start: 245, end: 312, colorIndex: 3 },
];
return (
<>
<CfTimingBar phases={phases} />
</>
);
} Real waterfall scenario
Three concurrent HTTP requests with their timings stitched together: DNS / Connect / TLS / Wait / Receive each in its own color.
背景
GET /v1/me · 264ms
GET /v1/orders (cached) · 220ms
POST /v1/charges · 480ms
<script setup lang="ts">
import { CfTimingBar } from '@chufix-design/vue';
// 真实场景:3 个并发 HTTP 请求
const r1 = [
{ label: 'DNS', start: 0, end: 8, colorIndex: 6 },
{ label: 'Connect', start: 8, end: 32, colorIndex: 0 },
{ label: 'TLS', start: 32, end: 80, colorIndex: 2 },
{ label: 'Wait', start: 80, end: 220, colorIndex: 1 },
{ label: 'Receive', start: 220, end: 264, colorIndex: 3 },
];
const r2 = [
{ label: 'Wait', start: 0, end: 184, colorIndex: 1 },
{ label: 'Receive', start: 184, end: 220, colorIndex: 3 },
];
const r3 = [
{ label: 'Wait', start: 0, end: 412, colorIndex: 5 },
{ label: 'Receive', start: 412, end: 480, colorIndex: 3 },
];
</script>
<template>
<div style="display: flex; flex-direction: column; gap: 12px;">
<div style="font-size: 11px; color: var(--fg-3); font-family: var(--font-mono);">GET /v1/me · 264ms</div>
<CfTimingBar :phases="r1" />
<div style="font-size: 11px; color: var(--fg-3); font-family: var(--font-mono);">GET /v1/orders (cached) · 220ms</div>
<CfTimingBar :phases="r2" />
<div style="font-size: 11px; color: var(--fg-3); font-family: var(--font-mono);">POST /v1/charges · 480ms</div>
<CfTimingBar :phases="r3" />
</div>
</template> <script setup>
import { CfTimingBar } from '@chufix-design/vue';
// 真实场景:3 个并发 HTTP 请求
const r1 = [
{ label: 'DNS', start: 0, end: 8, colorIndex: 6 },
{ label: 'Connect', start: 8, end: 32, colorIndex: 0 },
{ label: 'TLS', start: 32, end: 80, colorIndex: 2 },
{ label: 'Wait', start: 80, end: 220, colorIndex: 1 },
{ label: 'Receive', start: 220, end: 264, colorIndex: 3 },
];
const r2 = [
{ label: 'Wait', start: 0, end: 184, colorIndex: 1 },
{ label: 'Receive', start: 184, end: 220, colorIndex: 3 },
];
const r3 = [
{ label: 'Wait', start: 0, end: 412, colorIndex: 5 },
{ label: 'Receive', start: 412, end: 480, colorIndex: 3 },
];
</script>
<template>
<div style="display: flex; flex-direction: column; gap: 12px;">
<div style="font-size: 11px; color: var(--fg-3); font-family: var(--font-mono);">GET /v1/me · 264ms</div>
<CfTimingBar :phases="r1" />
<div style="font-size: 11px; color: var(--fg-3); font-family: var(--font-mono);">GET /v1/orders (cached) · 220ms</div>
<CfTimingBar :phases="r2" />
<div style="font-size: 11px; color: var(--fg-3); font-family: var(--font-mono);">POST /v1/charges · 480ms</div>
<CfTimingBar :phases="r3" />
</div>
</template> import { CfTimingBar } from '@chufix-design/react';
export default function Demo() {
return (
<>
<CfTimingBar phases={phases} />
</>
);
} import { CfTimingBar } from '@chufix-design/react';
export default function Demo() {
return (
<>
<CfTimingBar phases={phases} />
</>
);
} API
| Prop | Type | Default | Description |
|---|---|---|---|
phases | TimingPhase[] | — | { label, start, end, colorIndex? }[] (ms) |
showAxis | boolean | true | Bottom segment labels |
labelMode | 'auto' | 'all' | 'none' | 'auto' | Segment label strategy; auto hides colliding labels |
反馈与讨论
Timing bar · Discussion