目录 (Outline)
- 一、 CDP:浏览器背后的「神秘推手」
- 二、 核心协议域:Network、Page、Runtime 与 Performance
- 三、 实战 1:精细化流量拦截与模拟 (Network Domain)
- 四、 实战 2:秒级生成性能 Profile 并分析 (Performance Domain)
- 五、 总结与最佳实践
一、 CDP:浏览器背后的「神秘推手」
1. 历史背景
CDP 是 Chrome 浏览器与其内置开发者工具通信的协议。它是基于 JSON-RPC 的双向通信协议(WebSocket)。
2. 标志性事件
- 2017 年:Puppeteer 发布,将复杂的 CDP 调用封装为友好的 API。
- 2020 年:Playwright 发布,通过对 CDP 的深度优化,实现了更快的执行速度和更好的跨浏览器兼容性。
3. 解决的问题 / 带来的变化
直接调用 CDP 相比上层框架:
- 更轻量:不需要加载庞大的框架运行环境。
- 更底层:能访问框架未暴露的功能(如精细的 CPU 节流、网络请求头伪造)。
二、 核心协议域:Network、Page、Runtime 与 Performance
CDP 将功能划分为不同的「域」(Domains):
- Network:处理网络请求、Cookie、缓存。
- Page:控制页面导航、快照、生命周期事件。
- Runtime:在页面上下文中执行 JS,访问变量。
- Performance:开启性能统计、获取 Metrics 指标。
三、 实战 1:精细化流量拦截与模拟 (Network Domain)
痛点场景
你想测试应用在某些 API 返回 500 错误时的表现,或者模拟极慢的网络环境。
实战代码 (基于 Puppeteer 访问底层 CDP)
const client = await page.target().createCDPSession();
// 1. 开启网络域
await client.send('Network.enable');
// 2. 拦截特定请求
await client.send('Network.setRequestInterception', {
patterns: [{ urlPattern: '*/api/v1/user*', resourceType: 'Fetch', interceptionStage: 'Request' }]
});
// 3. 监听拦截事件并 mock 返回
client.on('Network.requestIntercepted', async ({ interceptionId, request }) => {
console.log(`拦截到请求: ${request.url}`);
await client.send('Network.continueInterceptedRequest', {
interceptionId,
rawResponse: btoa('HTTP/1.1 500 Internal Server Error\r\nContent-Type: application/json\r\n\r\n{"error": "Mock Error"}')
});
});
四、 实战 2:秒级生成性能 Profile 并分析 (Performance Domain)
痛点场景
在自动化测试流程中,你想自动检测某个关键页面是否出现了性能退化。
实战代码
const client = await page.target().createCDPSession();
// 开启性能监控
await client.send('Performance.enable');
// 执行某些用户操作
await page.click('#heavy-task-button');
// 获取性能指标
const { metrics } = await client.send('Performance.getMetrics');
// 提取感兴趣的指标
const jsHeapSize = metrics.find(m => m.name === 'JSHeapUsedSize').value;
const layoutDuration = metrics.find(m => m.name === 'LayoutDuration').value;
console.log(`当前 JS 堆内存: ${(jsHeapSize / 1024 / 1024).toFixed(2)} MB`);
console.log(`布局总耗时: ${layoutDuration}s`);
五、 总结与最佳实践
- 安全第一:CDP 是极高权限的协议。在线上环境,严禁开启
--remote-debugging-port。 - 稳定性建议:直接使用 CDP 虽然强大,但代码会比上层框架冗长。建议在 90% 的场景下使用 Puppeteer/Playwright,仅在需要「骚操作」时通过
createCDPSession()调用底层协议。
掌握了 CDP,你就掌握了控制浏览器的「核按钮」。无论是开发自动化调试工具,还是做精细化的性能压测,它都是你不可或缺的利器。