Open JuniorTour opened 1 year ago
上一节:《你做的前端优化都错了!《现代前端工程体验优化》前言 && 第一章 数据驱动》
有了获取用户体验指标数据的工具,还需要进一步大量收集、细致分析这些数据,以便了解现状、确定优化方向。
笔者推荐一套经过实践检验、开发体验较好的开源工具:Prometheus 和 Grafana。
Prometheus 是一款开源的数据监控解决方案,包括针对各种编程语言的数据采集SDK(例如面向 Node.js 的NPM包客户端:prom-client)、接收数据上报的后端服务器应用、基于时间序的数据库、以及基础的数据可视化前端应用,具有强大的拓展能力,可以方便快速地融合进已有的项目中,作为数据监控的中台工具。
Grafana 是一款开源的数据可视化工具,主要包括兼容 Prometheus 在内各种数据库的数据查询工具、内置各种图表模板的数据可视化前端应用,并且支持免费的私有化部署。
将 Prometheus 与 Grafana 整合进我们的项目中就能方便地实现强大的数据收集、可视化能力。
下面我们以Node.js为例,演示如何接入这2款工具。
Node.js
我们将基于:
prom-client
演示如何从本地环境收集 web-vitals 数据,并上传到 Grafana,最终创建出数据可视化图表。
首先我们注册并登录 Grafana 官方的云端应用:https://grafana.com/get/?pg=graf&plcmt=hero-btn-1 ,每个账户都有足够的免费试用额度供我们测试。
完成注册后,我们就会进入 Grafana 的看板页面,这里是我们管理数据可视化图表、接入数据源的主要工作区域。
但因为此时我们还没有接入数据,所以内容还是一片空白。接下来我们启动一个基于 prom-client 的 Node.js 服务器作为我们的数据收集应用。
首先我们从左侧侧边栏访问 Connection > Connect data 目录,搜索 node.js 即可找到官方推荐的 Node.js 应用接入基础设施:
不同的数据源有不同的特性,例如: 查询语句的格式 是否支持日志全文查询 Grafana 支持众多数据源,如果 Prometheus 不适合你的前后端架构,可以参考官方文档选择Elasticsearch、Graphite等其他数据源:https://grafana.com/docs/grafana/latest/datasources/ 如果只需要指标收集和存储,建议选择 Prometheus 或 Graphite; 如果需要进行日志收集和分析,对日志全文做可视化,建议选择 Elasticsearch;
不同的数据源有不同的特性,例如:
Grafana 支持众多数据源,如果 Prometheus 不适合你的前后端架构,可以参考官方文档选择Elasticsearch、Graphite等其他数据源:https://grafana.com/docs/grafana/latest/datasources/
Elasticsearch
Graphite
如果只需要指标收集和存储,建议选择 Prometheus 或 Graphite; 如果需要进行日志收集和分析,对日志全文做可视化,建议选择 Elasticsearch;
点击进入 Node.js Infrastructure 后,接下来我们按照官方文档首先检查必要准备:
安装 Grafana Agent 应用用于收集、转发本地的Prometheus数据:
选择对应系统,输入 API key 的备注名,点击 Generate API token 生成接口令牌,随后会提示生成已完成:Your API token has been generated below.
Your API token has been generated below.
接下来我们要运行官方提供的命令行从而下载、安装并配置 Grafana Agent 应用,下载和安装可能需要一定时间并克服网络限制:
注意:需要以管理员身份运行 PowerShell,运行方式如下图:
命令执行完成后,点击左下角的 Test agent connection 即可验证安装是否完成。
验证通过、安装完成后,就可以在本地通过Node.js应用收集并上报数据了,让我们新建一个空白 Node.js 项目:
npm init
package.json
"start": "node app.js"
npm install express prom-client
app.js
官方示例需要Node.js环境支持 ES module 语法,你也可以参考笔者提供的示例项目,直接使用更方便的 CommonJS module 语法: 《feat: 引入express && prom-client;初始化服务》commit:https://github.com/JuniorTour/node-prometheus-grafana-demo/commit/7ba9148a70164c944cd6d474251c5bef2507273c
官方示例需要Node.js环境支持 ES module 语法,你也可以参考笔者提供的示例项目,直接使用更方便的 CommonJS module 语法:
《feat: 引入express && prom-client;初始化服务》commit:https://github.com/JuniorTour/node-prometheus-grafana-demo/commit/7ba9148a70164c944cd6d474251c5bef2507273c
运行 npm run start 后,prom-client就会自动开始采集一批默认的 Node.js 应用数据。
npm run start
最后,让我们把预置的可视化图表,添加到我们的看板中,点击下图中的安装 Install 按钮:
安装后,一套监控 Node.js 应用内存用量、CPU使用率等指标的可视化看板就被添加到我们的看板中了:
我们的目标不只是监控这些基础指标,下面让我们试试如何增加自定义指标来。
Grafana 官方 Node.js 集成文档:https://grafana.com/docs/grafana-cloud/data-configuration/integrations/integration-reference/integration-nodejs/ 各大云服务供应商也有集成 Grafana: 阿里云:https://www.aliyun.com/product/aliware/grafana 腾讯云:https://cloud.tencent.com/document/product/1437/61603
Grafana 官方 Node.js 集成文档:https://grafana.com/docs/grafana-cloud/data-configuration/integrations/integration-reference/integration-nodejs/
各大云服务供应商也有集成 Grafana:
为了将前端利用 web-vitals 收集的数据,发送到 Grafana,后端服务需要基于 prom-client 的能力,增加一批自定义指标。
让我继续在 app.js 中添加以下代码:
这部分可以参考笔者提供示例中的《feat: 增加自定义计数指标 webVitalsRatingCounter》commit:https://github.com/JuniorTour/node-prometheus-grafana-demo/commit/6c7c57abcf4c94685c45cbef3a0715f8a41e4fab // 3. 对所有接口增加 跨域资源共享(CORS)配置 // Enable CORS for all routes app.use((req, res, next) => { res.header("Access-Control-Allow-Origin", "*"); // Allow any origin res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); // Allow these headers if (req.method === 'OPTIONS') { res.header("Access-Control-Allow-Methods", "POST"); // Allow POST method return res.sendStatus(200); } next(); });
这部分可以参考笔者提供示例中的《feat: 增加自定义计数指标 webVitalsRatingCounter》commit:https://github.com/JuniorTour/node-prometheus-grafana-demo/commit/6c7c57abcf4c94685c45cbef3a0715f8a41e4fab
// 3. 对所有接口增加 跨域资源共享(CORS)配置 // Enable CORS for all routes app.use((req, res, next) => { res.header("Access-Control-Allow-Origin", "*"); // Allow any origin res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); // Allow these headers if (req.method === 'OPTIONS') { res.header("Access-Control-Allow-Methods", "POST"); // Allow POST method return res.sendStatus(200); } next(); });
// 2. 新建一个自定义计数指标webVitalsRatingCounter // https://www.npmjs.com/package/prom-client#:~:text=()%3B-,Custom%20Metrics,-All%20metric%20types const webVitalsRatingCounter = new client.Counter({ name: 'webVitalsRatingCounter', help: 'counter to store web-vitals rating data', registers: [register], labelNames: ['name', 'rating'], });
// 1. 增加一个POST方法的接口 app.post('/post-web-vitals', function(req, res) { console.log(req.body=${req.body}) const labels = req.body.labels
req.body=${req.body}
webVitalsRatingCounter.inc(labels)
const message = Get web-vitals: labels=${JSON.stringify(labels)} console.log(message) res.status(200).json({ message }); });
Get web-vitals: labels=${JSON.stringify(labels)}
通过这段代码,我们: 1. 增加了一个POST方法的接口`/post-web-vitals`,用于接收前端发送来的 web-vitals 数据; 1. 新建了一个自定义计数指标`webVitalsRatingCounter`,用于收到 web-vitals 数据计数、统计数据名称(`name`)、评分(`rating`); 1. 对所有接口增加 跨域资源共享(CORS)配置,以便我们稍后从DEMO中获取的数据可以跨域发送给我们本地的`http://localhost:4001/post-web-vitals`接口; 基于这段代码我们就可以从前端应用中通过HTTP 异步请求发送 web-vitals 数据到这个后端服务,并借助 prom-client 的自定义计数指标`webVitalsRatingCounter`将数据上报到 Grafana 供我们查询、创建可视化图表。 接下来我们基于之前的《获取web-vitals数据 DEMO》: https://output.jsbin.com/bizanep 增加上报数据到 Node.js 后端的逻辑: ``` js // 《发送 web-vitals 数据 DEMO》:https://output.jsbin.com/xifudez async function sendDataToBackend(data) { if (!data) { return } await fetch('http://localhost:4001/post-web-vitals', { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ labels: { name: data?.name, rating: data?.rating } }), }) } function onGetWebVitalsData(data) { if (!data?.name) { return } const name = data.name const value = data.value const rating = data.rating sendDataToBackend(data) const msg = (`(已发送到后端)${name}: value=${value}, rating=${rating}`) console.log(msg) setInnerHtml(name?.toLowerCase(), msg) } onFCP(onGetWebVitalsData);
我们的改动主要是:
sendDataToBackend
name, rating
onGetWebVitalsData
sendDataToBackend(data)
完整示例请参考 《发送 web-vitals 数据 DEMO》:https://output.jsbin.com/xifudez
运行这些新增改动后,我们将能在开发中工具的Network面板中看发送数据的HTTP请求,以及后端的响应信息:
有了这样一套前后端逻辑,我们的web-vitals数据就成功的发送到了 Grafana,接下来我们试着基于这些数据创建几张可视化图表。
下面我们一起来试着创建一张 Grafana 的可视化图表,主要有以下几步:
如果按照上文的接入演示一路操作过来,会有默认的数据源grafanaclound-yourName-prom
grafanaclound-yourName-prom
Grafana 中不同的数据源对应不同的查询器面板及语法,我们以前文示例的 Prometheus 数据源为例,其主要有 交互界面选择查询语句(Builder)和 直接输入查询语句文本(Code)2种模式。
推荐使用对新用户更为友好的Builder模式,可以看到包含以下各选项:
分别对应我们调用 prom-client 的 new Counter API 时传入的name,labelNames字段:
new Counter
name
labelNames
const webVitalsRatingCounter = new client.Counter({ name: 'webVitalsRatingCounter', help: 'counter to store web-vitals rating data', registers: [register], labelNames: ['name', 'rating'], });
我们分别输入并选择 webVitalsRatingCounter,name=FCP,rating=good 三项后,
webVitalsRatingCounter
name=FCP
rating=good
点击刷新仪表盘(Refresh Dashboard)即可看到我们刚刚上传的数据,将对应时段有多少次name=FCP,rating=good 在可视化图表中展示出来:
不同的数据源有各自不同的查询语法 Prometheus 数据源查询语法:https://prometheus.io/docs/prometheus/latest/querying/basics/ ElasticSearch 数据源查询语法:http://lucenetutorial.com/lucene-query-syntax.html
不同的数据源有各自不同的查询语法
Prometheus 数据源查询语法:https://prometheus.io/docs/prometheus/latest/querying/basics/
ElasticSearch 数据源查询语法:http://lucenetutorial.com/lucene-query-syntax.html
有了数据后,我们就可以进一步完善可视化图表的细节,常用的功能主要有:
图表类型:常用的有折线图、柱状图,纯文本;
标题和描述
提示(Tooltip)和图例(Legend):设置何时显示提示、图例的样式和内容;
度量选项(Standard Options):设置当前查询的值是什么单位,常用的有:
时间间隔:设置将多久的时间间隔内的所有数据,聚合数据为可视化图中的一个数据点。例如截图中5m即表示将5分钟内的数据统一计入可视化图中的一个点。例如下图中时间范围(Time Range)选择最近15分钟(Last 15 minutes),对应折线图就有3个点。
5m
覆盖配置:设置查询语句显示名称、颜色等特殊配置
以上各项配置是个人总结较为常用的配置项,可以随意尝试调整,观察效果。
先后点击:
至此,我们就创建了第一张可视化图表,后续可以在实践中逐步熟悉 Grafana 的强大功能。这只是我们的第一步,接下来我会分享实践中遇到的问题和解决方案。
将数据记录并可视化,非常有成就感,可以让我们明确的感知到工作的产出。 当我们的数据和图表越来越多,我们对维护项目的了解也会越来越深入。
将数据记录并可视化,非常有成就感,可以让我们明确的感知到工作的产出。
当我们的数据和图表越来越多,我们对维护项目的了解也会越来越深入。
从 web-vitals 获得的数据中比较有统计意义的是:
'good'
'needs-improvement'
'poor'
例如这条从onFCPAPI获取的LCP数据:
onFCP
{ delta: 382.80000019073486 entries: [ { duration: 0 element: p entryType: "largest-contentful-paint" id: "" loadTime: 0 name: "" renderTime: 382.8 size: 8985 startTime: 382.80000019073486 url: "" } ] id: "v3-1683034382854-2926018174544" name: "LCP" navigationType: "reload" rating: "good" value: 382.80000019073486 }
笔者更推荐使用评分字段作为可视化图表的主要指标。
原因是直接使用值经常会有异常波动,经常在前端项目没有任何变更的情况下,观察到值产生了显著的变化。
使用评分作为指标,相当于对观测的值做了一次标准化处理,将一定范围内的值处理成统一的评分,有助于规避个别极端值导致的异常波动。
如下图,4/22 前后的 LCP 平均值在我们的前端项目没有变更的情况下就出现了减少11%的变化,这样的异常波动显然不利于评估我们优化的效果:
笔者最初基于 web-vitals 制作数据可视化图时,用的就是值字段,计算了FCP等指标的平均值,观察一段时间后发现即使前后端项目没有上线变更,各指标的平均值也会有10%以上的波动,这显然是不符合预期的,这种波动将会降低我们评估优化效果的准确性。
后来改成基于评分字段制作各评分占比变化图后,数据波动问题就不再出现了,各评分的占比平均值在长时间内都能保持不超过5%的波动。当我们主动进行一些用户优化后就能观察到更客观,更有说服力的指标变化。
下面分享一套基于模拟数据的“堆叠百分比图”示例及配置源码,各位读者可以根据需要复制后粘贴到自己的仪表盘内,并替换为真实数据,从而得到客观稳定的优化效果评估数据。
{ "datasource": { "type": "testdata", "uid": "a95c7111-f01f-4e29-b3a6-9b0ac81d9094" }, "description": "“堆叠百分比图”配置源码,作者:https://github.com/JuniorTour", "fieldConfig": { "defaults": { "custom": { "drawStyle": "line", "lineInterpolation": "linear", "barAlignment": 0, "lineWidth": 1, "fillOpacity": 70, "gradientMode": "none", "spanNulls": false, "showPoints": "auto", "pointSize": 1, "stacking": { "mode": "normal", "group": "A" }, "axisPlacement": "auto", "axisLabel": "", "axisColorMode": "text", "scaleDistribution": { "type": "linear" }, "axisCenteredZero": false, "hideFrom": { "tooltip": false, "viz": false, "legend": false }, "thresholdsStyle": { "mode": "off" } }, "color": { "mode": "palette-classic" }, "mappings": [], "thresholds": { "mode": "absolute", "steps": [ { "color": "green", "value": null }, { "color": "red", "value": 80 } ] }, "max": 1, "min": 0, "unit": "percentunit" }, "overrides": [ { "matcher": { "id": "byName", "options": "G" }, "properties": [ { "id": "color", "value": { "fixedColor": "red", "mode": "fixed" } }, { "id": "displayName", "value": "差" } ] }, { "matcher": { "id": "byName", "options": "E" }, "properties": [ { "id": "displayName", "value": "优" } ] }, { "matcher": { "id": "byName", "options": "F" }, "properties": [ { "id": "displayName", "value": "待改进" } ] } ] }, "gridPos": { "h": 8, "w": 12, "x": 0, "y": 16 }, "id": 4, "options": { "tooltip": { "mode": "multi", "sort": "none" }, "legend": { "showLegend": true, "displayMode": "table", "placement": "right", "calcs": [ "min", "max", "mean" ] } }, "targets": [ { "alias": "good", "datasource": { "type": "testdata", "uid": "a95c7111-f01f-4e29-b3a6-9b0ac81d9094" }, "hide": true, "refId": "A", "scenarioId": "csv_metric_values", "stringInput": "47,57,46,54,54,57,47,46,54,54,55,52,46,53,46" }, { "alias": "needsImprove", "datasource": { "type": "testdata", "uid": "a95c7111-f01f-4e29-b3a6-9b0ac81d9094" }, "hide": true, "refId": "B", "scenarioId": "csv_metric_values", "stringInput": "10,14,11,11,19,13,15,19,15,13,16,17,12,9,19" }, { "alias": "poor", "datasource": { "type": "testdata", "uid": "a95c7111-f01f-4e29-b3a6-9b0ac81d9094" }, "hide": true, "refId": "C", "scenarioId": "csv_metric_values", "stringInput": "15,18,6,12,9,17,10,16,5,8,15,12,11,12,16" }, { "datasource": { "name": "Expression", "type": "__expr__", "uid": "__expr__" }, "expression": "$A+$B+$C", "hide": true, "refId": "D", "type": "math" }, { "datasource": { "name": "Expression", "type": "__expr__", "uid": "__expr__" }, "expression": "$A/$D", "hide": false, "refId": "E", "type": "math" }, { "datasource": { "name": "Expression", "type": "__expr__", "uid": "__expr__" }, "expression": "$B/$D", "hide": false, "refId": "F", "type": "math" }, { "datasource": { "name": "Expression", "type": "__expr__", "uid": "__expr__" }, "expression": "$C/$D", "hide": false, "refId": "G", "type": "math" } ], "title": "堆叠百分比统计 WebVitals CLS 指标示例", "type": "timeseries" }
粘贴图表方式: 创建一张空图表后,点击更多选项-Inspect-Panel JSON,粘贴上述配置源码,点击应用(Apply)后即可立即生效
通过创建多张针对不同指标的堆叠百分比图,我们就能对生产环境的web-vitals各项指标有稳定、客观、可量化的监控,从而:
web-vitals
上一节:《你做的前端优化都错了!《现代前端工程体验优化》前言 && 第一章 数据驱动》
3. 用户体验数据收集与可视化:基于 Prometheus 及 Grafana 的实现简介
有了获取用户体验指标数据的工具,还需要进一步大量收集、细致分析这些数据,以便了解现状、确定优化方向。
笔者推荐一套经过实践检验、开发体验较好的开源工具:Prometheus 和 Grafana。
1. Prometheus 及 Grafana 简介
Prometheus 是一款开源的数据监控解决方案,包括针对各种编程语言的数据采集SDK(例如面向 Node.js 的NPM包客户端:prom-client)、接收数据上报的后端服务器应用、基于时间序的数据库、以及基础的数据可视化前端应用,具有强大的拓展能力,可以方便快速地融合进已有的项目中,作为数据监控的中台工具。
Grafana 是一款开源的数据可视化工具,主要包括兼容 Prometheus 在内各种数据库的数据查询工具、内置各种图表模板的数据可视化前端应用,并且支持免费的私有化部署。
将 Prometheus 与 Grafana 整合进我们的项目中就能方便地实现强大的数据收集、可视化能力。
下面我们以
Node.js
为例,演示如何接入这2款工具。2. 接入演示
我们将基于:
prom-client
演示如何从本地环境收集 web-vitals 数据,并上传到 Grafana,最终创建出数据可视化图表。
首先我们注册并登录 Grafana 官方的云端应用:https://grafana.com/get/?pg=graf&plcmt=hero-btn-1 ,每个账户都有足够的免费试用额度供我们测试。
完成注册后,我们就会进入 Grafana 的看板页面,这里是我们管理数据可视化图表、接入数据源的主要工作区域。
但因为此时我们还没有接入数据,所以内容还是一片空白。接下来我们启动一个基于 prom-client 的 Node.js 服务器作为我们的数据收集应用。
首先我们从左侧侧边栏访问 Connection > Connect data 目录,搜索 node.js 即可找到官方推荐的 Node.js 应用接入基础设施:
点击进入 Node.js Infrastructure 后,接下来我们按照官方文档首先检查必要准备:
安装 Grafana Agent 应用用于收集、转发本地的Prometheus数据:
选择对应系统,输入 API key 的备注名,点击 Generate API token 生成接口令牌,随后会提示生成已完成:
Your API token has been generated below.
接下来我们要运行官方提供的命令行从而下载、安装并配置 Grafana Agent 应用,下载和安装可能需要一定时间并克服网络限制:
命令执行完成后,点击左下角的 Test agent connection 即可验证安装是否完成。
验证通过、安装完成后,就可以在本地通过Node.js应用收集并上报数据了,让我们新建一个空白 Node.js 项目:
npm init
初始化生成package.json
,并添加启动脚本:"start": "node app.js"
npm install express prom-client
app.js
,将官方的代码示例复制粘贴下来运行
npm run start
后,prom-client
就会自动开始采集一批默认的 Node.js 应用数据。最后,让我们把预置的可视化图表,添加到我们的看板中,点击下图中的安装 Install 按钮:
安装后,一套监控 Node.js 应用内存用量、CPU使用率等指标的可视化看板就被添加到我们的看板中了:
我们的目标不只是监控这些基础指标,下面让我们试试如何增加自定义指标来。
3. 增加自定义指标上报并创建可视化图表
为了将前端利用 web-vitals 收集的数据,发送到 Grafana,后端服务需要基于 prom-client 的能力,增加一批自定义指标。
让我继续在 app.js 中添加以下代码:
// 2. 新建一个自定义计数指标webVitalsRatingCounter // https://www.npmjs.com/package/prom-client#:~:text=()%3B-,Custom%20Metrics,-All%20metric%20types const webVitalsRatingCounter = new client.Counter({ name: 'webVitalsRatingCounter', help: 'counter to store web-vitals rating data', registers: [register], labelNames: ['name', 'rating'], });
// 1. 增加一个POST方法的接口 app.post('/post-web-vitals', function(req, res) { console.log(
req.body=${req.body}
) const labels = req.body.labelswebVitalsRatingCounter.inc(labels)
const message =
Get web-vitals: labels=${JSON.stringify(labels)}
console.log(message) res.status(200).json({ message }); });我们的改动主要是:
sendDataToBackend
方法,用于接受到web-vitals库的数据后发送HTTP请求到后端接口,并把name, rating
这2个字段作为请求体;onGetWebVitalsData
方法中增加sendDataToBackend(data)
方法的调用,将指标数据作为参数传入;运行这些新增改动后,我们将能在开发中工具的Network面板中看发送数据的HTTP请求,以及后端的响应信息:
有了这样一套前后端逻辑,我们的web-vitals数据就成功的发送到了 Grafana,接下来我们试着基于这些数据创建几张可视化图表。
4. 创建 Grafana 可视化图表指南
下面我们一起来试着创建一张 Grafana 的可视化图表,主要有以下几步:
1. 访问仪表盘(Dashboard)页面,点击新建仪表盘(New Dashboard)按钮
2. 点击增加可视化(Add visualization)
3. 选择(或确认)数据源
4. 输入查询语录
Grafana 中不同的数据源对应不同的查询器面板及语法,我们以前文示例的 Prometheus 数据源为例,其主要有 交互界面选择查询语句(Builder)和 直接输入查询语句文本(Code)2种模式。
推荐使用对新用户更为友好的Builder模式,可以看到包含以下各选项:
分别对应我们调用 prom-client 的
new Counter
API 时传入的name
,labelNames
字段:我们分别输入并选择
webVitalsRatingCounter
,name=FCP
,rating=good
三项后,点击刷新仪表盘(Refresh Dashboard)即可看到我们刚刚上传的数据,将对应时段有多少次
name=FCP
,rating=good
在可视化图表中展示出来:5. 调整样式、配置等细节
有了数据后,我们就可以进一步完善可视化图表的细节,常用的功能主要有:
图表类型:常用的有折线图、柱状图,纯文本;
标题和描述
提示(Tooltip)和图例(Legend):设置何时显示提示、图例的样式和内容;
度量选项(Standard Options):设置当前查询的值是什么单位,常用的有:
时间间隔:设置将多久的时间间隔内的所有数据,聚合数据为可视化图中的一个数据点。例如截图中
5m
即表示将5分钟内的数据统一计入可视化图中的一个点。例如下图中时间范围(Time Range)选择最近15分钟(Last 15 minutes),对应折线图就有3个点。覆盖配置:设置查询语句显示名称、颜色等特殊配置
以上各项配置是个人总结较为常用的配置项,可以随意尝试调整,观察效果。
6. 分别保存图表和仪表盘
先后点击:
至此,我们就创建了第一张可视化图表,后续可以在实践中逐步熟悉 Grafana 的强大功能。这只是我们的第一步,接下来我会分享实践中遇到的问题和解决方案。
5. 堆叠百分比图优点及示例说明
从 web-vitals 获得的数据中比较有统计意义的是:
'good'
),待提升('needs-improvement'
),差('poor'
)三类值,可用于对数据进行标准化处理;例如这条从
onFCP
API获取的LCP数据:笔者更推荐使用评分字段作为可视化图表的主要指标。
原因是直接使用值经常会有异常波动,经常在前端项目没有任何变更的情况下,观察到值产生了显著的变化。
使用评分作为指标,相当于对观测的值做了一次标准化处理,将一定范围内的值处理成统一的评分,有助于规避个别极端值导致的异常波动。
笔者最初基于 web-vitals 制作数据可视化图时,用的就是值字段,计算了FCP等指标的平均值,观察一段时间后发现即使前后端项目没有上线变更,各指标的平均值也会有10%以上的波动,这显然是不符合预期的,这种波动将会降低我们评估优化效果的准确性。
后来改成基于评分字段制作各评分占比变化图后,数据波动问题就不再出现了,各评分的占比平均值在长时间内都能保持不超过5%的波动。当我们主动进行一些用户优化后就能观察到更客观,更有说服力的指标变化。
下面分享一套基于模拟数据的“堆叠百分比图”示例及配置源码,各位读者可以根据需要复制后粘贴到自己的仪表盘内,并替换为真实数据,从而得到客观稳定的优化效果评估数据。
堆叠百分比图配置源码
通过创建多张针对不同指标的堆叠百分比图,我们就能对生产环境的
web-vitals
各项指标有稳定、客观、可量化的监控,从而:《前端工程体验优化》全书现已发布到掘金小册,欢迎各位朋友交流学习