性能监控LightHouse

from 前端早读课2020-05-21https://mp.weixin.qq.com/s/I8DYY4oY_uJ_6IpIQNLSYQ

一、简介

Lighthouse 是一个开源的自动化工具,用于改进网络应用的质量。只要为 Lighthouse 提供一个需要审查的网址,它将针对此页面运行一连串的测试,然后生成一个有关页面性能的报告。

二、使用方式

目前官方提供了4种使用方式:https://github.com/GoogleChrome/lighthouse

  • Chrome 开发者工具(DevTools)

  • Chrome 扩展

  • Node Module
  • Node CLI

安装:

npm i -g lighthouse

测试:

lighthouse https://webpack.js.org/plugins/provide-plugin/

结果:

 

lighthouse测试流程图如下:

    • Lighthouse 与浏览器建立连接。
    • 测试的初始化配置与加载待测试页面。
    • 在页面加载过程中,运行一系列的采集器(gatherers),每个采集器都会收集自己的目标信息,并生成中间产物(artifacts)。
    • 运行一系列的审计项(audits),每个审计项都会从中间产物(artifacts)中获取所需的数据,计算出各自的评分。
    • 输出report
  • 生成的.html文件

 

 

 

 

 

Lighthouse 6.0 的报告引入了 3 个新的指标,其中两个 LCP 和 CLS 来自 5 月份新发布的 Core Web Vitals 衡量体系,另一个是 TBT。

  • Largest Contentful Paint(LCP)

  主内容渲染时间,是前 FCP 指标的一个有力补充,LCP 分数低于 2.5 秒会被认为是“好”的体验。

  • Cumlative Layout Shift(CLS)

  累计布局变更/累计视觉变更,用来计算非预期的 UI 界面变更对用户操作的影响,CLS分数低于 0.10 被认为是“好”的体验。

  • Total Blocking Time(TBT)

  总阻塞时间。用来量化加载的响应能力,累积主线程被阻塞并会影响用户操作反馈的总时间。TBT 也与 Core Web Vitals 中的 FID 指标相关联(First Input Delay 首次交互延迟)。

随着衡量指标的更新,评分规则也必然做出相应调整,具体如下图所示:

  • TTI 的权重从 33% 下降到 15%,这个主要基于 TTI 反馈的稳定性不够以及新的补充指标 TBT 的加入。

  • FCP 的权重从 23% 下降到 15%,主要是新的补充指标 LCP 的加入。

  • 最大可能 FID 指标被废弃,不会再暂时到报告中,现在更推荐通过TBT 指标来衡量可交互性。

  • 首次有效渲染(First Meaningful Paint)被废弃,这个数据太不稳定且因为 Chrome 内部渲染机制的关系而无法标准化。

  • 首次 CPU 空闲 被废弃,因为这个指标和 TTI 指标重复性较高,而后续更推荐使用 TBT 和 TTI 指标来衡量交互性。

  • CLS 指标的权重目前还相对较低,在后续的主版本更新中可能会将其调高。

三、LightHouse各个模块

 

  1. Driver模块

 Chrome 浏览器在启动的时候,可以通过 --remote-debugging-port 参数设置远程调试端口,如以下命令可以打开 Chrome 并设置远程调试端口为9222。

chrome.exe --remote-debugging-port=9222

之后就可以使用地址 http://localhost:9222 进行远程调试了,比如以下命令可以让 Chrome 浏览器打开一个新的 Tab。

curl http://localhost:9222/json/new

  与浏览器通讯

Driver 模块的 Connection 实例(负责与浏览器进行通信),该实例在初始化的时候,正是通过调用远程调试端口的/json/new指令打开一个新的 Tab,并使用返回的 webSocketDebuggerUrl 与浏览器建立 WebSocket 连接,之后就可以进行双向通信

 

 双方建立 WebSocket 连接后,必须使用Chrome DevTools Protocol进行通讯。该协议以 JSON 为格式,定义指令的方法名与参数。

 Lighthouse 通过 Chrome DevTools Protocol 定义的主动指令与事件通知,就实现了操控 Chrome 浏览器,并且感知页面加载过程中的各个事件。

  日志记录

Driver 模块中的另外2个重要实例是 DevtoolsLog、NetworkRecorder,他们用于将浏览器发出的通知事件进行结构化的存储。其中 DevtoolsLog 会记录各个领域的全量日志,NetworkRecorder 只存储网络相关日志,并会分析出当前网络请求状态(繁忙、空闲)等。

  模拟器

emulation模块的作用是模拟测试设备,如模拟 移动端 / PC 端、屏幕的尺寸,模拟设备的 UserAgent、Cookie、网络限速等。

  2.Gatherer 模块

该模块的一个重要概念是 pass:控制页面如何加载,并通过配置gathers决定在页面加载过程中采集哪些信息。

// 一个pass的配置
{
  passes:[{
    passName: 'defaultPass',
    recordTrace:true,// 是否记录Trace信息
    useThrottling:true,// 是否使用限速
    gatherers:[     // gatherers列表
      'css-usage',
      'viewport-dimensions',
      'runtime-exceptions',      
      'console-messages',
      'anchor-elements',
      'image-elements',
      'link-elements',
      'meta-elements',
      'script-elements',
      'iframe-elements',
      ...    // 省略
    ],
  },
    ...    // 省略
} 

其中,gathers中每一个 gatherer,在代码仓库中都有与之对应的同名实现文件,并且都继承自相同的父类 Gatherer,其中定义了三个模板方法,子类只需实现模板方法即可。

Class Gather {
    // 在页面导航前
     beforePass (passContext) {    }
    // 在页面loaded后
    pass (passContext) {    }
    // 在页面加载完毕,且trace信息收集完毕后
    afterPass (passContext, loadData) {    }
}

当 pass 中定义的所有 gatherers 运行完后,就会生成一个中间产物 artifacts,此后 Lighthouse 就可以断开与浏览器的连接,只使用 artifacts 进行后续的分析。

3. Audits 模块

与 gatherers 类似,在配置文件中也会定义需要运行的 audits,每一个 audits 也都有与之对应的同名实现文件。

{
  audits:[
    'errors-in-console',
    'metrics/first-contentful-paint',
    'metrics/first-meaningful-paint',
    'metrics/speed-index',
    'metrics/first-cpu-idle',    
    'metrics/interactive',
    'screenshot-thumbnails',    
    'final-screenshot',
    // 省略
  ],
  // 省略
}

在每个 audit 中都会定义一个静态方法meta(),对该 audit 进行描述,并声明所需的 artifacts,ErrorLogs 这项 audit 就声明了其需要上文提到的 RuntimeExceptions 所生成的中间产物。

class ErrorLogs extends Audit {
  static get meta (){
    return {
      id:'errors-in-console',
      title: str_(UIStrings.title),
      failureTitle: str_(UIStrings.failureTitle),
      description: str_(UIStrings.description),
      requiredArtifacts: ['ConsoleMessages', 'RuntimeExceptions'],            
  };  } }

Audit 实例需要实现的另一个模板方法是audit(),在该方法中可以拿到所需的中间产物,并基于中间产物计算出本项 audit 的得分与详情。

class PageTitle extends Audit {
    static get meta() {
    return {
        id: 'page-title',
        title: 'title of page document',
        failureTitle: 'Does not have page title',
        description: 'This audit get document.title when page loaded',
        requiredArtifacts: ['PageTitle'],
        };
    }
     static audit(artifacts) {
    return {
    score: artifacts.PageTitle ? 1 : 0,
    displayValue: artifacts.PageTitle || 'none'
        };
    }
}

4. Report 模块

在配置文件中,会定义每个测试类别所需的审计项,以及每个审计项所占的权重。如下所示的为性能(performance)这项测试类别所需的审计项:

{
    'performance': {
    title: str_(UIStrings.performanceCategoryTitle),
    auditRefs: [
        {id: 'first-contentful-paint', weight: 3, group: 'metrics'},
        {id: 'first-meaningful-paint', weight: 1, group: 'metrics'},
        {id: 'speed-index', weight: 4, group: 'metrics'},
        {id: 'interactive', weight: 5, group: 'metrics'},
        {id: 'first-cpu-idle', weight: 2, group: 'metrics'},
        {id: 'max-potential-fid', weight: 0, group: 'metrics'},
        // 省略
        ]
    },
}    

在最终汇总阶段,Lighthouse 会根据该配置文件以及前一个环节中计算出的每个审计项的评分,加权计算出 performance 的评分。

并基于每个审计项的评分与种类,将审计项划分为通过与不通过,对于不通过的审计项会给出详细的测试详情与优化指引。

四、限速模拟

由于页面性能受宿主机网络与 CPU 频率等参数的影响较大,Lighthouse 提供了三种方式供模拟较差的宿主机网络环境。其背后的逻辑是,如果页面能够在较差的环境下达到一个较好的测试分数、那么大部分用户对页面的直观感受都会较好。

Chrome Devtools 的 Audits 面板中,可以看到三种限速方式:

 

 

  •  simulated: 即限速是模拟的(加载页面时不进行限速,加载完页面后,模拟计算出在限速条件下的性能指标值),所以可以在较快的速度下地完成审计并有相似的测试精度。
  • applied: 即通过 DevTools 进行限速,页面是在一个真实受限的网络与降速 CPU 条件下加载的。
  • no throttling: 即 Lighthouse 不进行额外的限速,通常在不进行性能测试、或开发者自行对宿主机进行限速时使用该项。

在三种限速方式中,Lighthouse 真正对网络与 CPU 进行限速的只有 devtools 这种限速方式,实现的方式是通过上文提到的 Driver 模块发送对应领域的指令给 Chrome 浏览器。

五、补充

1. 在上文介绍 pass 时,我们提到其中有一个参数用来控制是否收集 Trace 信息。Trace 信息的可视化展示就在 Chrome devtools 中 Performance 面板:

 

 当 pass 中配置了开启收集 Trace 信息时,Lighthouse 在页面加载完毕后,就可以拿到完整的 Trace 信息, 从中可以知道页面加载时的 FCP 等关键渲染节点。

 

posted @ 2020-05-23 12:39  cecelia  阅读(1651)  评论(0编辑  收藏  举报