跳到主要内容

estimate bandwidth

一、作用

二、估算带宽

export default function estimateBandwidth(): number {
// Estimate the current bandwidth for downloading static resources given resources already
// loaded.
// 根据已加载的资源估算当前下载静态资源的带宽。
if (typeof performance.getEntriesByType === 'function') {
let count = 0;
let bits = 0;
const resourceEntries = performance.getEntriesByType('resource');
for (let i = 0; i < resourceEntries.length; i++) {
const entry = resourceEntries[i];
const transferSize: number = entry.transferSize;
const initiatorType: string = entry.initiatorType;
const duration = entry.duration;
if (
!transferSize ||
!duration ||
!isLikelyStaticResource(initiatorType)
) {
// Skip cached, cross-orgin entries and resources likely to be dynamically generated.
// 跳过缓存的、跨源的条目以及可能动态生成的资源。
continue;
}
// Find any overlapping entries that were transferring at the same time since the total
// bps at the time will include those bytes.
// 查找任何同时传输的重叠条目,因为当时的总 bps 将包括那些字节。
let overlappingBytes = 0;
const parentEndTime: number = entry.responseEnd;
let j;
for (j = i + 1; j < resourceEntries.length; j++) {
const overlapEntry = resourceEntries[j];
const overlapStartTime = overlapEntry.startTime;
if (overlapStartTime > parentEndTime) {
break;
}
const overlapTransferSize: number = overlapEntry.transferSize;
const overlapInitiatorType: string = overlapEntry.initiatorType;
if (
!overlapTransferSize ||
!isLikelyStaticResource(overlapInitiatorType)
) {
// Skip cached, cross-orgin entries and resources likely to be dynamically generated.
continue;
}
const overlapEndTime: number = overlapEntry.responseEnd;
const overlapFactor =
overlapEndTime < parentEndTime
? 1
: (parentEndTime - overlapStartTime) /
(overlapEndTime - overlapStartTime);
overlappingBytes += overlapTransferSize * overlapFactor;
}
// Skip past any entries we already considered overlapping. Otherwise we'd have to go
// back to consider previous entries when we then handled them.
// 跳过我们已经认为是重叠的条目。否则,当我们处理它们时,就必须回头考虑之前的条目。
i = j - 1;

const bps =
((transferSize + overlappingBytes) * 8) / (entry.duration / 1000);
bits += bps;
count++;
if (count > 10) {
// We have enough to get an average.
// 我们有足够的数据来计算平均值。
break;
}
}
if (count > 0) {
return bits / count / 1e6;
}
}

// Fallback to the navigator.connection estimate if available
// 如果可用,则回退到 navigator.connection 的估算
if (navigator.connection) {
const downlink: ?number = navigator.connection.downlink;
if (typeof downlink === 'number') {
return downlink;
}
}

// Otherwise, use a default of 5mbps to compute heuristics.
// This can happen commonly in Safari if all static resources and images are loaded
// cross-orgin.
// 否则,使用默认的 5mbps 来计算启发式。
// 如果所有静态资源和图片都是跨域加载的,这种情况在 Safari 中很常见。
return 5;
}

三、工具

1. 可能是静态资源

function isLikelyStaticResource(initiatorType: string) {
switch (initiatorType) {
case 'css':
case 'script':
case 'font':
case 'img':
case 'image':
case 'input':
case 'link':
return true;
default:
return false;
}
}