Lighthouse Viewer 深度指南:本地构建、发布部署与查询参数驱动的报告加载机制
【免费下载链接】lighthouseAutomated auditing, performance metrics, and best practices for the web.项目地址: https://gitcode.com/GitHub_Trending/lig/lighthouse
本篇技术指南以 viewer/README.md 为骨架,系统讲解 Lighthouse 生态中的Lighthouse Report Viewer(Lighthouse 报告在线查看器):如何在本地 checkout 中完成构建与调试,如何通过gist、jsonurl、psiurl三类深链参数一键加载报告,以及category、strategy、locale、utm_source等可选参数的作用。同时结合viewer/app/src/下的源码实现与 viewer/test/viewer-test-pptr.js 测试用例,剖析报告加载、GitHub Gist 读写、PSI 数据拉取与本地化切换的底层调用链,帮助开发者完成从"会用"到"能改、能测、能发布"的进阶。
项目定位:一份 LHR JSON 的通用查看终端
Lighthouse 在每次运行后产出一份 JSON 格式的 Lighthouse Report(LHR,即LH.Result),而Lighthouse Viewer是一个纯前端的报告查看器:把 LHR JSON(或 Flow 用户流报告LH.FlowResult)渲染成带评分、图表、审计明细的交互式 HTML 报告页面。
Viewer 的典型应用场景包括:
- 把
lighthouse --output=json生成的报告文件拖入页面直接可视化; - 将报告上传为 GitHub Gist 后通过
?gist=分享给他人; - 通过
?psiurl=直接对线上 URL 实时跑一次 PageSpeed Insights 审计并渲染结果; - 作为其他工具(扩展、CI 产物、报告 Diff 工具)的"打开报告"落地页。
在仓库中,Viewer 位于 viewer/ 目录,其核心渲染能力复用自 report/renderer/report-renderer.js(单次报告)与 flow-report/api.ts(用户流报告),自身只负责"把 JSON 弄进来"以及"把渲染结果接出去"。
本地开发与构建
按 viewer/README.md 的 Development 章节,在 Lighthouse checkout 的根目录依次执行:
yarn yarn build-viewer yarn serve-gh-pages open http://localhost:7333/viewer/说明:
yarn安装仓库全部依赖(Viewer 使用 ES Module 与 esbuild 打包,依赖在根目录package.json中统一管理)。yarn build-viewer编译并压缩入口 viewer/app/src/main.js,产物写入dist/gh-pages/viewer/。构建脚本定义于根目录 package.json("build-viewer": "node ./build/build-viewer.js")。yarn serve-gh-pages启动静态服务器:"serve-gh-pages": "cd dist/gh-pages && python3 -m http.server 7333",即用 Python 内置 HTTP 服务在7333端口托管构建产物,模拟 GitHub Pages 的目录结构。- 打开
http://localhost:7333/viewer/即为本地 Viewer 页面。
构建产物目录刻意命名为dist/gh-pages/viewer/,与线上gh-pages分支下viewer/目录一一对应——这样本地预览路径与最终部署路径完全一致,避免深链参数、静态资源相对路径在部署后失效。
部署到 gh-pages 分支
按 README 的 Deploy 章节,Viewer 的部署作为Lighthouse 发版流程的一部分完成,在 checkout 根目录执行:
yarn deploy-viewer该命令("deploy-viewer": "yarn build-viewer --deploy")会在构建后把产物推送到gh-pages分支的viewer/目录下。完整的发版流程细节参见仓库根目录的发布指南 docs/releasing.md(README 中引用的releasing.md即此文件),其中说明了发版节奏、版本号语义与发布步骤。
三种深链参数:gist / jsonurl / psiurl
Viewer 支持通过 URL 查询参数直接加载报告,入口逻辑在 viewer/app/src/lighthouse-report-viewer.js 的_loadFromDeepLink()方法中:页面初始化时解析location.search,按优先级依次处理gist、psiurl、jsonurl。
从 Gist 加载
把 GitHub Gist 的 ID 作为gist查询参数传入:
http://localhost:7333/viewer/?gist=bd1779783a5bbcb348564a58f80f7099底层由 viewer/app/src/github-api.js 的getGistFileContentAsJson(id)完成:调用https://api.github.com/gists/{id},优先选取文件名以.lighthouse.report.json结尾的文件,否则回退到任意.json文件,解析后交给渲染层。该实现还内置了两层优化:
- ETag 缓存:每次请求把上次响应头中的
ETag通过If-None-Match带回,命中304时直接使用 IndexedDB(idb-keyval)中的缓存副本; - 速率限制告警:当
X-RateLimit-Remaining低于 10 时向用户提示接近 GitHub API 速率上限,并建议登录以提升限额。
加载成功后 URL 会通过history.pushState改写为?gist=<id>,方便直接复制分享。
从任意 URL 加载 JSON
把 LHR JSON 文件的绝对地址作为jsonurl传入:
http://localhost:7333/viewer/?jsonurl=https://gist.githubusercontent.com/Kikobeats/d570a1aa285c5d1d97bbda10b92fb97f/raw/4b0f14a5914edd25c95b4bd9d09728ab42181c3e/lighthouse.json实现上,jsonurl分支会先通过 Firebase Auth 检查当前是否已登录 GitHub:已登录时拒绝加载(避免带鉴权头跨域请求引发问题),未登录则直接fetch(jsonurl)并解析 JSON。从源码看这是一个安全约束:未登录状态下没有 GitHub token 会被附加到请求上。
运行并加载 PageSpeed Insights 结果
传入目标 URL 作为psiurl,Viewer 会实时调用 PSI API 生成报告再渲染:
http://localhost:7333/viewer/?psiurl=https://www.example.com&category=seo请求由 viewer/app/src/psi-api.js 的fetchPSI()构造,指向https://www.googleapis.com/pagespeedonline/v5/runPagespeed。其默认行为(有源码与测试双重印证):
- 默认类别:未显式传
category时,请求performance、accessibility、seo、best-practices、agentic-browsing五个类别(PSI_DEFAULT_CATEGORIES,见 viewer/app/src/psi-api.js 第 11–17 行); - 默认策略:
strategy为空时兜底为mobile; - 每个类别以独立的
category参数重复追加(测试注释特别强调"传给 PSI 的参数顺序很重要"); - 请求附带
referer: googlechrome.github.io头。
附加查询参数详解
README 列出的四个可选参数在_loadFromDeepLink()中透传给 PSI 请求(viewer/app/src/lighthouse-report-viewer.js 第 121–128 行):
| 参数 | 含义 | 取值/默认 |
|---|---|---|
category | 启用哪个类别,每次只能传一个类别 | performance、accessibility、seo、best-practices、agentic-browsing;可重复出现多次以请求多个类别,缺省时使用上述五个默认类别 |
strategy | 运行策略 | mobile(默认)、desktop |
locale | 渲染报告使用的语言区域 | 任意受支持 locale,如es、zh,缺省为报告原始 locale(通常en-US) |
utm_source | 标识"哪个工具在使用 Viewer"的 ID | 自定义字符串,仅用于流量归因统计 |
其中locale的处理并不只作用于 PSI 请求参数:报告渲染完成后,viewer/app/src/viewer-ui-features.js 会通过懒加载shared/localization/i18n-module.js(约 30KB,仅在需要时拉取),在页面右上角提供语言选择器,可对已渲染的报告进行运行时本地化切换(swapLocale),切换后整体重新渲染。
除深链外的四种交互式加载方式
即便不依赖任何查询参数,打开 Viewer 页面也有多种加载途径,交互入口定义在 viewer/app/index.html 的占位区(.viewer-placeholder):
- 拖拽文件:把
.json报告拖入页面,由 viewer/app/src/drag-and-drop.js 监听dragenter/dragover/drop事件,用FileReader.readAsText读取第一个文件; - 点击选择文件:点击"select a file"按钮触发隐藏的
<input id="hidden-file-input" type="file" accept="application/json">; - 粘贴:在页面任意位置粘贴 Gist 链接(
https://gist.github.com/...,通过正则/[a-f0-9]{5,}/提取 ID)或直接粘贴 JSON 文本,见 viewer/app/src/lighthouse-report-viewer.js 的_onPaste(); - 输入 Gist URL:在
.js-gist-url输入框中填写 Gist 地址。
报告渲染的底层流程与兼容性处理
无论是深链加载还是文件上传,最终都汇聚到 viewer/app/src/lighthouse-report-viewer.js 的_replaceReportHtml(json),其处理链条如下:
- 格式归一化:兼容三类输入——
{lhr: ...}(runner 结果)、{lighthouseResult: ...}(PSI 响应)、原生 LHR;通过'steps' in json判断是否为 Flow 报告并分流到renderFlowReport(来自 flow-report/api.ts)或ReportRenderer.renderReport(来自 report/renderer/report-renderer.js); - 版本校验:
_validateReportJson()要求 JSON 必须含lighthouseVersion字段(否则报"不是 Lighthouse 生成的 JSON");当报告主/次版本低于当前 Viewer 版本时给出警告"Results may not display properly"; - v2 旧报告重定向:
lighthouseVersion以2开头时,把报告写入 IndexedDB 后跳转到旧版 Viewer(../viewer2x/)渲染; - 调试便利:渲染后把 LHR 挂到
window.__LIGHTHOUSE_JSON__(Flow 报告挂window.__LIGHTHOUSE_FLOW_JSON__)便于控制台调试; - 深链清理:非 Gist/PSI/URL 来源加载时,通过
history.pushState清空查询串,避免误刷新重新加载。
入口 viewer/app/src/main.js 还负责日志系统(div#lh-log与Logger,实现见 report/renderer/logger.js)以及lh-log、lh-analytics两个自定义事件的转发,后者在存在gtag时上报统计。
Gist 保存与 GitHub 登录
Viewer 支持把当前报告一键保存为 Gist 以便分享。保存逻辑在 viewer/app/src/github-api.js 的createGist():
- 文件名由 report/generator/file-namer.js 生成(基于
finalDisplayedUrl与fetchTime),追加.lighthouse.report.json后缀; - 以
POST https://api.github.com/gists创建私有 Gist,需要 GitHub OAuth token; - 认证由 viewer/app/src/firebase-auth.js 完成:通过 Firebase
signInWithPopup+GithubAuthProvider(scope 为gist)弹出 GitHub 授权,并把 token 存入 IndexedDB(GitHub token 永不过期,刷新页面后仍可复用); - 保存成功后页面 URL 被改写为
?gist=<id>,可复制分享。
在 viewer/app/src/viewer-ui-features.js 中,"Save as Gist"菜单项在保存成功后才被禁用,且当报告本身来自 Gist 时不会提供重复保存入口。
测试验证:Viewer 的关键行为都有 Puppeteer 覆盖
viewer/test/viewer-test-pptr.js 启动本地静态服务器(端口 10200)与 Puppeteer,对 Viewer 做了端到端验证,覆盖以下能力,可作为理解与二次开发的参考:
- Flow 报告渲染:上传
sample-flow-result.json后应出现.App容器与包含 14 个评分的 Summary 页; - 单次报告渲染:上传 core/test/results/sample_v2.json 后断言所有类别、全部审计项、胶片帧(
.lh-filmstrip)均正确渲染,且无 "Audit error"; - 旧版本报告兼容:逐一加载
report/test-assets/下从lhr-3.0.0.json到lhr-11.7.0.json的历史报告,验证零报错渲染; - 本地化切换:默认
en-US,切换到es后界面文案变为 "Copiar JSON"; - 保存 HTML:通过 CDP 监听下载事件验证 "Save as HTML" 可生成独立报告页;
- PSI 集成:拦截请求验证默认类别顺序、
strategy=mobile兜底、自定义category/locale/utm_source透传,以及 API 报错时的日志提示(如badPsiResponse error)。
快速自查清单
- 本地调试:
yarn→yarn build-viewer→yarn serve-gh-pages→http://localhost:7333/viewer/; - 分享报告:Viewer 内保存为 Gist 后,用
?gist=<id>深链分发; - 实时审计:
?psiurl=<目标URL>&category=performance&strategy=desktop&locale=zh; - 部署上线:随 Lighthouse 发版执行
yarn deploy-viewer,产物推至gh-pages分支viewer/目录,完整流程参见 docs/releasing.md。
至此,从本地构建、参数化加载到源码原理与测试验证,Lighthouse Viewer 的完整工作链路已全部打通。
【免费下载链接】lighthouseAutomated auditing, performance metrics, and best practices for the web.项目地址: https://gitcode.com/GitHub_Trending/lig/lighthouse
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考