Chrome bug 之 JSON 序列化 PerformanceResourceTiming 对象

利用 nightmare 做下线性能对比分析中,少不了要获取 PerformanceResourceTiming 数据:

1
performance.getEntriesByType('resource');

但运行 nightmare 的 NodeJS 环境与运行 getEntriesByType 的 Browser 环境之间只能传输简单数据类型如 string、boolean、number,故下面的写法不可行:

1
let resources = yield nightmare.evaluate(() => performance.getEntriesByType('resource'));

当不得不写成这样时:

1
let resources = yield nightmare.evaluate(() => JSON.stringify(performance.getEntriesByType('resource')));

你会发现返回值是这样的:

1
2
3
4
5
6
7
8
[
{
"name": "https://...",
"entryType": "resource",
"startTime": 1059.82,
"duration": 413.96500000000015
}
]

显然这比我们见过的 PerformanceResourceTiming 对象少了好多字段。

转向 Chrome,执行类似的操作,发现这并非 nightmare 的问题,而是 blink 内核的bug。Safari 由于不支持 getEntriesByType 而无法测试,Firefox 则输出正常:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[
{
"name": "https://...",
"entryType": "resource",
"startTime": 4326.712201,
"duration": 1264.9166809999997,
"initiatorType": "xmlhttprequest",
"redirectStart": 0,
"redirectEnd": 0,
"fetchStart": 4326.712201,
"domainLookupStart": 0,
"domainLookupEnd": 0,
"connectStart": 0,
"connectEnd": 0,
"secureConnectionStart": 0,
"requestStart": 0,
"responseStart": 0,
"responseEnd": 5591.628882
}
]

造成该现象的原因是,序列化 JSON 时,字段取的是 PerformanceEntry 而非其子类 PerformanceResourceTiming

目前,twitter 员工提出的该 bug 与我先前提出的雷同,代码上已经被修复,等待 Chrome 50 的发版。