26、WebRTC性能基准测试:设计测试用例、测量延迟/吞吐量/CPU占用、对比不同配置下的表现
性能基准测试,说白了就是给你的WebRTC应用「体检」。我见过太多项目上线后才发现卡顿、延迟高,那时候再回头找问题,成本就高了去了。今天咱们就聊聊怎么系统地做这件事。
为什么需要基准测试?
你想想看,WebRTC的配置项那么多——编解码器、分辨率、码率、ICE策略……每个参数组合都会影响最终体验。没有基准测试,你根本不知道瓶颈在哪。
我个人习惯在项目初期就搭一套测试框架。嗯,别等到用户投诉了再动手。
设计测试用例
测试用例不是随便跑跑就完事。我一般分三类:
- 基础连通性测试:验证P2P连接能否建立,STUN/TURN是否正常工作
- 负载测试:模拟多路流并发,看系统能扛多少
- 边界测试:弱网环境、丢包率10%以上、带宽受限场景
测量延迟
延迟分好几层:
- 端到端延迟:从发送端采集到接收端渲染的时间
- 网络延迟:RTT(往返时间)
- 编解码延迟:编码+解码耗时
测量方法我推荐用performance.now()打时间戳。发送端在帧数据里嵌入时间,接收端解码时读取差值。
// 发送端
const startTime = performance.now();
// 假设这是你的视频帧数据
const frame = { data: videoFrame, timestamp: startTime };
peerConnection.send(frame);
// 接收端
peerConnection.ontrack = (event) => {
const receiveTime = performance.now();
const sendTime = event.track.timestamp;
const latency = receiveTime - sendTime;
console.log(`端到端延迟: ${latency.toFixed(2)}ms`);
};
测量吞吐量
吞吐量就是单位时间内能传多少数据。WebRTC里通常看视频码率。
我习惯用RTCPeerConnection.getStats()来拿数据。这个API能返回收发字节数、丢包数、抖动等。
async function measureThroughput(pc) {
const stats = await pc.getStats();
let bytesSent = 0;
stats.forEach(report => {
if (report.type === 'outbound-rtp' && report.mediaType === 'video') {
bytesSent = report.bytesSent;
}
});
return bytesSent;
}
// 每秒采样一次
setInterval(async () => {
const bytes = await measureThroughput(pc);
console.log(`当前吞吐量: ${(bytes / 1024 / 1024).toFixed(2)} MB/s`);
}, 1000);
测量CPU占用
CPU占用是性能瓶颈的重灾区。编码器、解码器、渲染管线都会吃CPU。
浏览器里可以用performance.memory(仅Chrome)或者navigator.hardwareConcurrency看逻辑核数。但更精确的做法是用requestAnimationFrame的帧率来间接判断——如果帧率掉到30fps以下,CPU大概率是瓶颈。
对比不同配置下的表现
这才是重头戏。我一般会列一个配置矩阵:
| 配置项 | 选项A | 选项B | 选项C |
|---|---|---|---|
| 编解码器 | VP8 | VP9 | H.264 |
| 分辨率 | 720p | 1080p | 4K |
| 码率 | 1 Mbps | 2 Mbps | 4 Mbps |
| ICE策略 | 全部 | 中继 | 直连 |
然后跑测试,记录延迟、吞吐量、CPU占用。结果用表格对比:
| 配置组合 | 延迟(ms) | 吞吐量(Mbps) | CPU占用(%) |
|---|---|---|---|
| VP8 + 720p + 1Mbps | 45 | 0.95 | 12 |
| VP9 + 1080p + 2Mbps | 62 | 1.88 | 28 |
| H.264 + 1080p + 2Mbps | 58 | 1.92 | 22 |
从数据能看出:VP9虽然压缩率高,但CPU占用也高。H.264在同等画质下CPU更友好。嗯,这就是取舍。
核心逻辑图
下面这张图展示了整个基准测试的流程:
避坑指南
我曾经踩过一个坑:测试时只跑了一路流,数据很好看。结果上线后并发20路,CPU直接飙到90%。后来我学乖了,测试用例里必须包含多路并发场景。
还有一点:浏览器差异。Chrome和Firefox的WebRTC实现细节不同,同样的配置在Chrome上延迟低,在Firefox上可能CPU高。所以测试要覆盖主流浏览器。
RTCPeerConnection.getStats()的type: 'candidate-pair'可以看ICE连接质量。如果看到state: 'failed',说明网络有问题,赶紧排查。
总结
基准测试不是一次性工作。每次改配置、升级浏览器、换网络环境,都应该重新跑一遍。数据会告诉你真相。
嗯,今天就聊到这。记住:没有测量就没有优化。动手搭一套测试框架,比看一百篇理论文章都管用。