我正在寻找一种在Lighthouse上优化我们网站的速度指数指标的方法
我发现这篇有用的文章很好地描述了速度指数指标,并帮助我理解了速度指数的计算方式。
https://calendar.perfplanet.com/2016/speed-index-tips-and-tricks/
但是有一个关键概念没有在文章中清楚地描述,我搜索了许多其他与 Speed Index 相关的博客,但仍然找不到答案。
什么是 100%视觉完整性框架?
我们都知道第一帧是0%VC,因为它是空白的,但是在页面加载过程中VC一直在增加,因此什么帧将被视为 100%视觉完整性< / strong>?
100%VC框架的定义很重要,因为它是计算所有其他框架的视觉完整性的基准。
如果我的页面仅以1到100的间隔间隔100ms打印,并且足以填充视口,那么 100%VC框架将是编号为 100 < / strong>已打印?
答案 0 :(得分:2)
根据Google's description of the Lighthouse "Speed Index" audit:
灯塔使用名为Speedline的节点模块来生成速度指数得分。
由Speed Index引入的WebpageTest.org旨在解决这个问题。它测量页面内容的可视显示速度。当前的实现基于Speed Index页上所述的视频捕获的视觉进度计算方法。 通过比较当前帧和最终帧的直方图之间的距离来计算视觉进度。
(斜体字。)
“速度指数”页面进入painful detail,介绍如何计算视觉进度。这是一个片段:
对于基于Webkit的浏览器,我们收集时间轴数据,其中包括绘画矩形以及其他有用的事件。
我相信“时间轴数据”是指通过Performance Timeline API检索到的JSON对象。
Lighthouse似乎将JSON时间轴传递给Speedline,该轴then extracts由一系列“帧”组成,用于描述页面加载的绘制事件:
/**
* @param {string|Array<TraceEvent>|{traceEvents: Array<TraceEvent>}} timeline
* @param {Options} opts
*/
function extractFramesFromTimeline(timeline, opts) {
Speedline将每个绘画事件的图像数据转换为an image histogram,有趣的是排除了“足够接近”以通过白色的像素:
/**
* @param {number} i
* @param {number} j
* @param {ImageData} img
*/
function isWhitePixel(i, j, img) {
return getPixel(i, j, 0, img.width, img.data) >= 249 &&
getPixel(i, j, 1, img.width, img.data) >= 249 &&
getPixel(i, j, 2, img.width, img.data) >= 249;
}
很多数学都用于计算和比较直方图。项目维护者是问这个问题的合适人选。但这是最终的determination of the "visually complete" happens:
// find visually complete
for (let i = 0; i < frames.length && !visuallyCompleteTs; i++) {
if (frames[i][progressToUse]() >= 100) {
visuallyCompleteTs = frames[i].getTimeStamp();
}
}
给定帧的“进度”似乎是通过此函数计算的:
/**
* @param {Frame} current
* @param {Frame} initial
* @param {Frame} target
*/
function calculateFrameProgress(current, initial, target) {
let total = 0;
let match = 0;
const currentHist = current.getHistogram();
const initialHist = initial.getHistogram();
const targetHist = target.getHistogram();
for (let channel = 0; channel < 3; channel++) {
for (let pixelVal = 0; pixelVal < 256; pixelVal++) {
const currentCount = currentHist[channel][pixelVal];
const initialCount = initialHist[channel][pixelVal];
const targetCount = targetHist[channel][pixelVal];
const currentDiff = Math.abs(currentCount - initialCount);
const targetDiff = Math.abs(targetCount - initialCount);
match += Math.min(currentDiff, targetDiff);
total += targetDiff;
}
}
let progress;
if (match === 0 && total === 0) { // All images are the same
progress = 100;
} else { // When images differs
progress = Math.floor(match / total * 100);
}
return progress;
}
在没有完全审核代码的情况下,我的解释是,“视觉上完整的帧”是计算出的与初始帧和最终帧具有相同总差异的第一帧(由Lighthouse chooses to send to Speedline帧确定) )。
或者换句话说,很复杂。
答案 1 :(得分:1)
当视口中的页面停止更改时,视觉上是完整的。即视觉效果没有改变。
通过在整个加载过程中截取屏幕截图并将它们相互之间以及与最终状态进行比较来计算。因此,在您的示例中,当所有数字1至100都已打印并且页面停止更改时,您是“视觉上完整的”。
因此,如果页面快速加载了视图中的数据,但是渲染“折叠后”内容(例如,屏幕外图像)的速度变慢了,那么即使页面的整体加载时间仍然很长,您也会获得视觉上的快速完成。 / p>
类似地,如果屏幕上的大多数内容是在早期绘制的,而一小部分是在稍后绘制的(也许是“单击聊天”选项),则您将在视觉上获得大部分的视觉效果,因此即使没有和上面的例子一样好。
另一方面,如果最后加载字体或大英雄图像,并且它重新绘制了页面的大部分内容,则您的视觉完成时间会很慢,而索引速度也会很慢。
此处有更多详细信息:https://sites.google.com/a/webpagetest.org/docs/using-webpagetest/metrics/speed-index
答案 2 :(得分:0)
我刚刚从Lighthouse回购贡献者那里得到了答案,请检查此链接。