Lighthouse 实战 超详细解析 逐项分析优化 - zptime/blog GitHub Wiki

Lighthouse 实战 超详细解析 逐项分析优化

前言

通过谷歌无痕浏览器内嵌的 Lighthouse 分析测试环境的 home 页

图示展示

Performance(性能)

Metrics(指标)

图示展示

First Contentful Paint (FCP)

第一次内容绘制,标记绘制第一个文本或图像的时间。官网介绍

  • 提高分数比较重要的一点是字体加载时间,可参考 Ensure text remains visible during webfont load
  • 避免显示不可见文本:在 @font-face样式中添加font-display: swap,swap 告诉浏览器使用该字体的文本应立即使用系统字体显示。自定义字体准备就绪后,将替换系统字体。
  • 预加载网页字体:用<link rel="preload" as="font">提前获取字体文件

Speed Index

速度指数,衡量页面加载期间内容的视觉显示速度。官网介绍

提高速度指数得分:

Largest Contentful Paint(LCP)

最大内容绘制,标记绘制最大文本或图像的渲染时间。官网介绍

Time to Interactive(TTI)

交互时间,是页面完全交互所需的时间。官网介绍

Total Blocking Time(TBT)

总阻塞时间,FCP 和 TTI 之间总时间,当任务长度超过 50ms 时,以毫秒表示。官网介绍

Cumulative Layout Shift(CLS)

累积布局偏移。官网介绍

Opportunities(机会)

如下建议可以帮助更快地加载页面,但它们不会直接影响性能得分

图示展示

Enable text compression

官网详细说明

基于文本的资源应该使用压缩(gzip、deflate 或 brotli),以最小化网络总字节数(FCP,LCP)。即还有潜在的压缩空间,可以配置 gzip压缩

Reduce unused JavaScript

官网详细说明

减少未使用的 JavaScript 并推迟加载脚本,直到需要时才加载,以减少网络活动消耗的字节数(LCP)。即删除无用的 JS,主要方法就是合理的代码分割按需引入

Eliminate render-blocking resources

官网详细说明

列出了阻止页面首次绘制的所有 URL(FCP,LCP)。

目标是通过内联关键资源、推迟非关键资源和删除任何未使用的内容来减少这些阻止渲染的 URL 的影响。即合理加载资源,控制加载顺序

  • 如何识别关键资源:使用 Chrome DevTools 中的 Coverage 选项卡来识别非关键 CSS 和 JS。当加载或运行页面时,该选项卡可以分析使用了多少代码,以及加载了多少代码,绿色(关键),红色(非关键 ​)
  • 如何消除渲染阻塞脚本:合理使用 asyncdefer 属性标记 <script>,可查看使用 JavaScript 添加交互
  • 如何消除阻塞渲染的样式表:可使用 preload 链接异步加载其余样式,可查看推迟非关键 CSS

HTTP/2 提供了许多优于 HTTP/1.1 的优点,包括二进制标头和多路复用。即现在用的是 HTTP/1.1,建议使用 HTTP/2。这个需要服务端改,目前不支持。

Diagnostics(诊断)

图示展示

Avoid chaining critical requests

官网详细说明

避免链接关键请求,链的长度越大,下载量越大,对页面加载性能的影响就越大。下面的关键请求链向您展示了哪些资源以高优先级加载。考虑减少链的长度减少资源的下载大小,或推迟不必要资源的下载以提高页面加载。

Keep request counts low and transfer sizes small

官网详细说明

保持较低的请求数量和较小的传输大小

Largest Contentful Paint element

官网详细说明

最大的内容 Paint 元素。

可按照图示进行针对性的优化:主要是人员管理的文案

图示展示

Avoid large layout shifts

避免大的布局变化。

看图解析:首页有好几个模块都是通过接口获取的数据,接口是不同步的,因此采用骨架屏形式,进行异步渲染。这几个模块是由骨架屏替换而来的,因此会有大的布局变化,会影响性能。

图示展示

Avoid long main-thread tasks

官网详细说明

避免长时间的主线程任务。由于耗时超过 50 毫秒的复杂工作,会出现占用大量 CPU 的长任务。长任务会使主线程保持忙碌,延迟用户交互。Chrome DevTools 现在可以将长任务可视化,从而更容易查看要优化的任务

  • 在 Chrome DevTools 中手动查找超过 50 毫秒的“长黄色块”脚本
  • DevTools 可视化了 Long Tasks。如果任务(以灰色显示)是长任务,则它们会带有红旗

看图解析:主要是 main.js5.js 需要优化

Avoid non-composited animations

避免非合成动画。官网详细说明

看图解析:主要是骨架屏的代码。首页有好几个模块都是通过接口获取的数据,接口是不同步的,因此采用骨架屏形式,进行异步渲染

图示展示

Passed audits(审核通过)

  • Properly size images:适当大小的图像,避免字节浪费而减慢页面加载时间
  • Defer offscreen images:屏幕外图像延迟加载
  • Minify CSS:缩小 CSS 文件,减少网络负载大小
  • Minify JavaScript:缩小 JS 文件,减少有效负载大小和脚本解析时间
  • Reduce unused CSS:删除未使用的 CSS
  • Efficiently encode images:有效地图片编码和优化
  • Serve images in next-gen formats:以下一代格式提供图像
  • Enable text compression:启用文本压缩
  • Preconnect to required origins:预连接到所需的源
  • Initial server response time was short:初始服务器响应时间很短
  • Avoid multiple page redirects:避免多个页面重定向
  • Preload key requests:预加载关键请求
  • Use video formats for animated content:用视频替换动画 GIF
  • Remove duplicate modules in JavaScript bundles:删除 JavaScript 包中的重复模块
  • Avoid serving legacy JavaScript to modern browsers:避免向现代浏览器提供旧版 JavaScript
  • Preload Largest Contentful Paint image:预加载最大的内容绘制
  • Avoids enormous network payloads:避免巨大的网络负载
  • Uses efficient cache policy on static assets:对静态资产使用高效的缓存策略
  • Avoids an excessive DOM size:避免过大的 DOM 元素
  • User Timing marks and measures:用户计时标记和度量
  • JavaScript execution time:JavaScript 执行时间
  • Minimizes main-thread work:最小化主线程工作
  • All text remains visible during webfont loads:在 webfont 加载期间所有文本保持可见
  • Minimize third-party usage:尽量减少第三方使用
  • Lazy load third-party resources with facades:延迟加载第三方资源
  • Uses passive listeners to improve scrolling performance:使用被动侦听器来提高滚动性能
  • Avoids document.write():避免使用 document.write()
  • Image elements have explicit width and height:图像元素应具有明确的宽度和高度

Accessibility(无障碍)

可访问性,网站的内容可用,其功能可由任何人操作

  • 可感知: 用户是否能感知内容?仅凭可通过一种感官(例如视觉)感知内容并不能断定所有用户都能感知。
  • 可操作: 用户是否能使用 UI 组件和在内容中导航?例如,需要悬停交互的内容无法由不能使用鼠标或触摸屏的用户操作。
  • 可理解: 用户是否能理解内容?用户能否理解界面,以及其一致性是否足以避免产生混淆?
  • 强健: 内容是否能被多种 User Agent(浏览器)使用? 它是否能与辅助技术协作?

图示展示

ARIA

增强辅助技术用户的体验,如屏幕阅读器。

问题:[aria-] attributes do not match their roles([aria-] 属性与其角色不匹配) 解决:Ant Design 日历图标属性不匹配,这个是组件库的问题,不好改

Contrast(对比度)

提高内容易读性

问题:Background and foreground colors do not have a sufficient contrast ratio(背景色和前景色没有足够的对比度) 解决:UI 设计的样式和颜色就是这样的,不好改

Names and labels

改进应用程序中的控件语义,增强辅助技术(如屏幕阅读器)用户的体验

  • Image elements do not have [alt] attributes(图像元素没有 [alt] 属性)
    • 解决:需要向图像添加替代文本,添加alt属性,用作占位符,这个容易改
  • Links do not have a discernible name(链接没有可辨别的名称)
    • 链接主要从其文本内容中获取其可访问的名称,内容不具备代表性时,可使用aria-label定义

Best practices(最佳实践)

  • [user-scalable="no"] is used in the element or the [maximum-scale] attribute is less than 5:([user-scalable="no"](禁用网页上的浏览器缩放)用于 元素或 [maximum-scale]属性小于 5)
    • 分析:对于依赖浏览器缩放来查看网页内容的低视力用户来说,这两个配置都是有问题的
    • 解决:但是实际情况中,缩放了页面样式会混乱,一般是不能缩放的。

Additional items to manually check(手动检查)

  • The page has a logical tab order(该页面具有逻辑 Tab 键顺序)
    • 测试:可以用 tab 键盘浏览页面,元素聚焦顺序遵循 DOM 顺序
    • 修复:tabindex 属性可控制
  • Interactive controls are keyboard focusable(交互式控件可通过键盘聚焦)
    • 测试:先通过 Tab 键浏览,再使用 TAB(或 SHIFT + TAB)到控制间来回移动,并使用箭头键 ENTER 和 SPACE 操纵它们的值
    • 修复:tabindex 来提高控件的可聚焦性;可能还需要向自定义控件元素添加适当的 ARIA 角色
  • Interactive elements indicate their purpose and state(交互元素表明它们的目的和状态)
    • 测试:tab 键测试,:focus 可设置焦点指示器的样式
  • The user's focus is directed to new content added to the page(用户的焦点被定向到添加到页面的新内容)
  • User focus is not accidentally trapped in a region(用户焦点不会意外陷入某个区域)
    • 测试:使用键盘在所有页面元素之间导航。用于 TAB“向前”SHIFT + TAB 导航和“向后”导航。
    • 修复:提供一种键盘可访问的方法来转义模态,创建可访问 modal模态和键盘陷阱
  • Custom controls have associated labels(自定义控件具有关联的标签,是可聚焦的)
  • Custom controls have ARIA roles(检查所有自定义控件是否具有 role 赋予其属性和状态的适当且任何必需的 ARIA 属性)
  • Visual order on the page follows DOM order(页面上的视觉顺序遵循 DOM 顺序)
  • Offscreen content is hidden from assistive technology(屏幕外内容对辅助技术隐藏)
  • HTML5 landmark elements are used to improve navigation(HTML5 地标元素用于改进导航,如 main、nav、aside 等)

Passed audits(通过审核)

  • [aria-hidden="true"] is not present on the document (body 上不能写 aria-hidden 属性)
  • [aria-hidden="true"] elements do not contain focusable descendents([aria-hidden="true"] 元素包含可聚焦的后代)
  • [aria-] attributes have valid values([aria-] 属性没有有效值)
  • [aria-] attributes are valid and not misspelled([aria-] 属性无效或拼写错误)
  • Buttons have an accessible name(按钮没有可访问的名称,aria-label 属性标识)
  • The page contains a heading, skip link, or landmark region(页面不包含标题、跳过链接或地标区域)
  • Document has a <title> element(文档有<title>元素)
  • Heading elements appear in a sequentially-descending order(标题元素不是按顺序降序排列的,即结构不佳)
  • element has a [lang] attribute(元素没有lang属性)
  • element has a valid value for its [lang] attribute(lang属性没有有效值)
  • Form elements have associated labels(表单元素没有关联的标签,使用 for 属性引用元素的 id)
  • No element has a [tabindex] value greater than 0(某些元素的[tabindex]值大于 0,会被认为是反模式)

Best Practices(最佳实践)

图示展示

Trust and Safety(信任与安全)

  • Does not use HTTPS(没有使用 HTTPS,有 14 个不安全的请求)
    • 解决:因为测试的是测试环境,没有使用 https,正式环境是 https
  • Ensure CSP is effective against XSS attacks:确保 CSP 对 XSS 攻击有效

General(通用)

  • Missing source maps for large first-party JavaScript:缺少 JavaScript 的源映射
    • 解决:开发环境是有的,但是生产环境为了减少包大小,一般不会配置

Passed audits(审核通过)

  • Links to cross-origin destinations are safe(指向跨源目的地的链接不安全)
    • 问题:使用target="_blank"属性链接到另一个站点上的页面时,可能会面临性能和安全问题
    • 解决:添加 rel="noopener"rel="noreferrer"
  • Avoids requesting the geolocation permission on page load(在页面加载时请求地理定位权限)
    • 问题:代码调用 geolocation.getCurrentPosition()或 geolocation.watchPosition(),并且尚未授予地理定位权限,则审核失败
  • Avoids requesting the notification permission on page load(请求页面加载通知权限)
    • 问题:代码调用 notification.requestPermission(),并且尚未授予通知权限,则审核失败
  • Avoids front-end JavaScript libraries with known security vulnerabilities(具有已知安全漏洞的前端 JavaScript 库)
    • 问题:入侵者可以通过自动网络爬虫扫描站点,查找已知的安全漏洞
  • Allows users to paste into password fields(防止用户获取密码)
  • Displays images with correct aspect ratio(显示纵横比不正确的图像)
  • Serves images with appropriate resolution(提供响应式图像)
  • Page has the HTML doctype(页面缺少 HTML 文档类型,从而触发怪异模式)
  • Properly defines charset(字符集声明缺失或在 HTML 中出现得太晚)
  • Avoids unload event listeners(要避免遗留的生命周期 API,事件或者监听器要注销)
  • Avoids Application Cache(使用应用程序缓存)
    • 使用缓存 API 而不是应用程序缓存,通过 Service Worker 使用缓存 API
  • Detected JavaScript libraries(列出所有前端使用的 JavaScript 库)
  • Avoids deprecated APIs(使用已弃用的 API)
  • No browser errors logged to the console(没有浏览器错误被记录到控制台)
  • No issues in the Issues panel in Chrome Devtools(Chrome Devtools “Issues” 面板中没有未解决的问题)

SEO(搜索引擎优化)

图示展示

  • Crawling and Indexing(爬取和索引)
    • Links are not crawlable:链接不可抓取
      • 具体分析:a 标签没有定义 href 属性,把跳转事件写到 click 中了,这个好改
  • Content Best Practices(内容最佳实践)
    • Image elements do not have [alt] attributes
      • 具体分析:图片没写 alt 属性,这个好改,就是图片有点多
  • Additional items to manually check(需要手动检查的项目)
    • Structured data is valid:结构化数据有效
  • Passed audits(审核通过)
    • Has a tag with width or initial-scale:视窗宽度和缩放比例
    • Document has a <title> element:标题
    • Document has a meta description:元描述
    • Page has successful HTTP status code:成功的 HTTP 状态代码
    • Links have descriptive text:描述性链接文本
    • Page isn’t blocked from indexing:页面没有阻止搜索引擎爬虫编制索引
    • Document has a valid hreflang:有效的语言代码
    • Document avoids plugins:避免插件,如 embed、object、applet
  • Not applicable(不适用)

PWA(渐进式 web 应用程序)

图示展示

介绍文档:https://web.dev/pwa-checklist/

  • Installable(安装)
    • Web app manifest or service worker do not meet the installability requirements:Web 应用清单或 Service Worker 不符合可安装性要求
  • PWA Optimized(PWA 优化)
    • Does not register a service worker that controls page and start_url:没有注册 Service Worker
    • Does not redirect HTTP traffic to HTTPS:使用 HTTPS 进行保护
    • Is not configured for a custom splash screen:自定义启动画面,Failures: No manifest was fetched.
    • Does not set a theme color for the address bar:为地址栏设置主题颜色 <meta name="theme-color" content="#317EFB"/>
    • Does not provide a valid apple-touch-icon:添加 Apple 触摸图标 <link rel="apple-touch-icon" href="/example.png">
    • Manifest doesn't have a maskable icon:没有可屏蔽图标,No manifest was fetched

因为我之前没有配置 pwa,easywebpack 有默认的配置,但是默认没开启,可以开启下

优化点汇总

针对首页分析,进行优化点汇总:

  • 字体样式控制:在 @font-face样式中添加font-display: swap
  • gzip 压缩
  • 合理的代码分割按需引入
  • CSS(preload),JS(asyncdefer)加载顺序控制
  • HTTP/2 替换 HTTP/1.1
  • 减少请求链长度,减少资源下载大小,推迟不必要资源的下载
  • 减少请求数量和传输大小
  • 减少重排和重绘,避免大的布局变化
  • 避免长时间主线程任务
  • 避免非合成动画,骨架屏要改
  • Accessibility(无障碍)要加强
  • img 图片添加 alt 属性
  • PWA 配置开启

参考文档

⚠️ **GitHub.com Fallback** ⚠️