高级前端篇之前端监控平台

5,591 阅读22分钟

前端篇系列长文:

轻轻喷,借鉴了很多文章,刚学完理出框架只完成了一点点,做一个复习,还在更新大改中,能帮到大家就最开心了,喜欢可以点个赞,持续更新中,谢谢大家,祝大家鹏程万展

一、背景与基础概念

(本篇已进行一些更改,删掉了一些无关紧要的概念,多写些干货,博主正在准备面试,时间比较少,愿大家谅解,最终版为一个实战落地方案,心急的同学可以自行下载项目,(前端可视化vue,服务端express,ngx日志上报,SDK(fee灯塔框架+脚手架命令进行数据清洗与上报)的企业级落地项目)

https://gitee.com/MrHuang-junzhe/huang-monior.git

在时代快速发展的今天,除了会用框架和技术外,更加注重方案设计。前端监控平台作为前端基建的一环,统计用户流量,页面性能,错误监控,对数量进行分析并做以可视化展示,并可对特定情况进行报警,大多数企业已经采用阿里云等提供的云服务进行便捷的数据采集。

但是直接使用的云服务无法对数据进行自定义处理以及会收费,所以了解一个自己编写的监控平台还是很有必要的,也有利于提升自己对于前端的理解。2025,AI的发展唱衰前端的声音一片,行业去水严重,需要在学习前沿技术的同时,加深自己的竞争力,愿同行们安好。

大致流程:

1744734323515.png

  • 业务层监控(web端,pc端等)
  • SDK工具库开发(业务层通过引入SDK工具库来监控数据)
  • 生成访问日志
  • 数据清洗与入库
  • 可视化展示

业界常用的监控流程都离不开上面的步骤: 在前端项目里引入SDK工具库对业务端进行监听,采集数据,对数据进行过滤和数据清洗,设置定时任务定时对数据进行清洗,将符合要求的数据入到数据库,再对数据进行可视化展示

开发人员通过对前端监控的学习,对浏览器性能机制以及前端性能有更深刻的理解

国内流行的埋点方案
  1. 云服务:腾讯云、百度、阿里ASMS,神策,都有配套的监控方案
  • 优点:便捷,自成体系

  • 缺点:收费,数据存在别人库里拿不到,无法对数据进行自定义化

  • 阿里云 ARMS:作为阿里云提供的应用性能监控服务,ARMS 具备性能埋点、错误监控以及资源优化等功能。它不仅能帮助企业监控应用的性能指标,还能及时发现并解决应用中出现的错误,提升应用的稳定性和用户体验。

  • 腾讯云 TA(腾讯分析) :该数据分析工具同样提供了用户行为分析、事件追踪和渠道效果分析等功能,助力企业深入了解用户行为,优化产品和运营策略。 能。通过对用户行为数据的多维度分析,帮助企业找到产品优化的关键点,提高用户留存率和活跃度。

  1. 自建的埋点体系
  • sentry主要专注于收集错误信息,支持大多数流行语言的客户端和服务端。然而,它对小程序的支持存在不足,虽然目前有大公司根据sentry的上报数据结构,自行实现了小程序SDK并开源,但该SDK的关注度和流行度相对较低。此外,除了错误收集,它在其他类型的前端监控能力方面相对较弱。
    • fee灯塔等

二. 分析评估

在前端项目中,性能优化不是盲目的,而是基于量化的指标和监控数据来判断 哪些地方需要优化 以及 如何优化。我们可以通过前端性能监控、分析工具和指标数据,找出性能瓶颈,并针对性地进行优化

1. 什么是前端性能监控量化?

前端性能监控量化 是指使用可量化的指标(如页面加载时间、交互响应速度、资源大小等)来评估网页或应用的性能,并通过监测这些指标的数据趋势,找出可能的性能瓶颈。

常见的性能优化需要关注以下几方面:

  • 页面加载性能(首屏渲染时间、白屏时间、资源加载速度、页面卡顿时间)
  • 交互响应性能(用户操作的延迟、动画流畅度、页面停留时间)
  • 代码执行性能(JavaScript 运行速度、计算密集型任务优化)
  • 网络请求优化(HTTP 请求数、请求大小、CDN 加速)
  • 错误和异常监控(JS 报错、网络请求失败)

2. 前端性能监控的核心指标

前端性能监控指标可以分为 页面加载性能指标交互体验性能指标

2.1 页面加载性能指标
指标说明重要性
TTFB(Time to First Byte)从用户发起请求到服务器返回第一字节的时间🔥🔥🔥
FCP(First Contentful Paint)页面首次渲染内容出现的时间🔥🔥
LCP(Largest Contentful Paint)加载最大可视内容(如大图片或大段文本)的时间🔥🔥🔥
TTI(Time to Interactive)页面可以交互的时间🔥🔥🔥
DOMContentLoaded(DCL)DOM 解析完成的时间🔥
Load Time页面所有资源加载完成的时间🔥

下图为页面加载全流程:

1744736501890.png

  • 卸载老页面
  • 重定向
  • app缓存
  • DNS解析
  • TCP
  • 请求
  • 响应
  • 卸载load事件

所有的指标数据都显示在上面,我们可以通过浏览器提供的API拿到,并算出我们需要的数据,比如首页加载事件,白屏事件(FCP第一个元素渲染时间)

以下为简单的一些指标,具体太多不做赘述。

2.2 交互体验性能指标
指标说明重要性
FID(First Input Delay)用户首次交互(点击、输入等)与浏览器响应之间的延迟🔥🔥🔥
CLS(Cumulative Layout Shift)页面布局的视觉稳定性🔥🔥
FPS(Frames Per Second)页面帧率,影响动画流畅度🔥🔥
TBT(Total Blocking Time)JavaScript 阻塞主线程的时间🔥🔥🔥

3. 如何进行前端性能监测?

我们可以通过以下方式对前端项目进行监控:

3.1 使用 Chrome DevTools

Chrome DevTools 提供了一整套分析工具:

  1. Network 面板:查看网络请求、资源加载情况。
  2. Performance 面板:分析 CPU、JavaScript 执行、帧率等。
  3. Coverage 面板:检测未使用的 CSS 和 JavaScript 代码。

示例:使用 Performance 进行分析

  1. 打开 DevTools(F12Cmd + Option + I)。
  2. 选择 Performance 选项卡。
  3. 点击 Start Profiling and Reload Page 进行录制。
  4. 查看 CPU、网络请求、渲染时间等数据。
3.4 使用 Performance API

Performance API 允许我们在 JavaScript 代码中监控关键性能数据,这也是前端监控SDK必备的一个浏览器API,我们通过它可以直接拿到指标数据,并进行自定义的上报与修改

🔹 示例:获取页面加载时间

js
 代码解读
复制代码
window.addEventListener('load', () => {
  const { loadEventEnd, navigationStart } = performance.timing;
  console.log('页面加载时间:', loadEventEnd - navigationStart, 'ms');
});

6. 总结

如何找到性能问题?

  1. 使用 Chrome DevTools 分析页面加载情况
  2. 使用 Lighthouse 进行自动化评分
  3. 使用 Performance API 监测关键指标
  4. 使用 Web Vitals 监测 LCP、FID、CLS
  5. 使用第三方监控工具(Sentry、New Relic)

通过这些方法,我们可以准确定位性能瓶颈,并进行针对性优化

流行的监控工具
  1. Sentry:作为一个开源的前端错误监控工具,Sentry 能够精准捕获和报告 JavaScript 及前端框架的错误和异常。它提供详细的错误信息和堆栈跟踪,极大地帮助开发人员快速定位和解决问题,提高开发效率。
  2. Google Analytics(谷歌分析) :这是一款全球广泛使用的网站统计和分析工具,具备丰富的功能,包括用户行为分析、性能监控、事件追踪等。通过对网站数据的全面分析,帮助企业了解用户行为,优化网站性能和用户体验。
  3. Lighthouse:由 Google 提供的开源网站性能分析工具,Lighthouse 可以对页面的性能、可访问性、SEO 等方面进行全面评估。它提供详细的报告和优化建议,帮助开发者提升网站的整体质量。
  4. WebPageTest:这是一个在线的网站性能测试工具,能够测试页面加载速度、首屏渲染时间等关键性能指标。通过对不同地区、不同网络环境下的测试,帮助企业了解用户在各种情况下的体验,优化网站性能。

三、行业通用方案剖析

随着前端技术的飞速发展,前端监控已成为众多项目不可或缺的一部分。在实际项目中,我们常常会采用各种开源项目或付费平台来实现前端监控,如sentry、阿里的ARMS,甚至小程序自带的前端监控服务。

(1)sentry

sentry主要专注于收集错误信息,支持大多数流行语言的客户端和服务端。然而,它对小程序的支持存在不足,虽然目前有大公司根据sentry的上报数据结构,自行实现了小程序SDK并开源,但该SDK的关注度和流行度相对较低。此外,除了错误收集,它在其他类型的前端监控能力方面相对较弱。

(2)阿里 ARMS

ARMS提供的功能较为齐全,对多种客户端都有良好的支持,包括小程序。它涵盖了性能监控、错误追踪、用户行为分析等多个方面,功能全面且符合国内的业务环境。不过,使用ARMS需要支付一定的费用。

(3)小程序自带监控

微信小程序不断完善内部监控功能,其涵盖的监控范围逐渐丰富,包括性能监控、错误监控等。但小程序自带监控的局限性在于,它仅能支持小程序本身,无法对其他类型的前端应用进行监控。

尽管这些开源或平台前端监控服务为我们提供了便利,但在实际使用过程中,它们也暴露出一些不足之处。例如,不同的监控工具和平台导致系统分散,难以统一管理;在满足自定义数据收集和查询需求方面存在困难;部分工具的特性更新缓慢,BUG解决周期较长;而且进行二次开发时,往往面临较大的难度。

四、系统架构与融合

3.1 基本构成

一个完整的前端监控系统通常由多个关键部分组成,各部分相互协作,共同实现前端监控的功能。

  1. 客户端 SDK

    • web:用于收集 Web 应用中的用户行为和性能数据,如页面加载时间、用户点击事件等。
    • 小程序:针对小程序的特点,收集小程序运行过程中的数据,包括页面加载性能、接口调用情况等。
    • ios:专门为 iOS 应用开发的 SDK,能够收集 iOS 应用中的各种数据,如应用启动时间、页面切换时间等。
    • android:适用于 Android 应用,用于收集 Android 应用中的用户行为和性能数据。
  2. 服务端 node + EggJs:使用node作为服务端开发语言,node具有出色的I/O性能,非常适合I/O密集型场景,且与前端技术栈相契合。EggJs是一个基于node的框架,它简单易用,文档完善,大部分熟悉node的前端程序员能够快速上手。服务端负责接收客户端SDK上报的数据,并进行处理和存储。

  3. 数据库 Redis + Mongo + mongooseJs (orm)

    • Mongo:作为持久化存储数据库,Mongo 是文档模型数据库,其数据结构类似json,方便与node配合使用。这种数据结构天生适合日志系统,能够方便地存储和扩展监控数据。
    • Redis:用作数据缓存,Redis 是简单易用的高性能key - value数据库,在市场上占据主流地位,被广泛熟知。它能够快速缓存常用数据,提高系统的响应速度。
  4. 管理台 Vue + ElementUI:管理台用于数据查询与管理,使用Vue框架结合ElementUI组件库进行开发,能够快速搭建出简洁美观、功能强大的管理界面,方便用户对监控数据进行查看和管理。

为了实现前端监控,首先要解决的是客户端数据收集问题。为此,我们开发封装了一个统一的SDK,方便客户端集成监控系统。在项目初期,我们优先支持web和微信小程序客户端,随着系统的不断迭代,现在也已支持native客户端。SDK收集到数据后,通过服务端接口上报。服务端接收到数据后,先将数据存储在redis中,然后根据自身的消费能力,从redis中拉取数据进行处理分析,最后将处理后的数据存储到mongo中。用户可以通过管理后台查看处理好的应用数据。

3.2 系统融合与关联

为了丰富前端监控系统的功能,提高其易用性,减少工作量,我们将公司内部现有的优质系统进行了接入和融合。

  1. SSO 系统:企业内部的SSO单点登录系统为每个员工注册了一个账户,员工可以通过账户密码、企业微信扫码或微信扫码等方式登录。接入SSO系统,不仅解决了不同系统之间的账户密码和登录方式不一致的问题,还方便了系统之间的相互跳转和接口请求,提高了用户的使用体验。
  2. 加入内部导航黄页:将前端监控系统的项目加入内部导航页,方便员工快速访问,提高系统的使用便捷性。
  3. 本地日志系统 finder elasticsearch:前端监控系统的node后端服务会产生本地日志,通过将日志存储到约定目录,运维服务会收集这些日志,并提供finderelasticsearch两个查询系统。finder按照时间和文件夹结构划分日志,查看视角类似于直接在服务器上查看本地日志,大多数情况下,用户更习惯使用finder进行日志查看。而elasticsearch则更适合通过搜索方式查询日志,方便用户快速定位所需信息。
  4. APM 系统 skywalkingAPM(应用性能管理)的目标是通过各种探针采集数据,收集关键指标,并搭配数据呈现,实现对应用程序性能管理和故障管理的系统化解决方案。我们企业内部统一使用skywalking,由于大部分服务是java开发,skywalking提供了node探针,使我们的前端监控系统后端node服务也能够接入。接入后,我们可以通过skywalking管理台查询后端node服务的性能以及调用情况。在这个过程中,traceId起着关键作用。APM工具会在服务端生成traceId,它标示一次调用的上下文id,通过此id可以查询所做事情的足迹链。后端服务可以通过前端http请求把这次调用的traceId通过响应头返回给客户端。前端监控的前端SDK探针便可以收集traceId,从而打通前端监控与后端监控。在前端监控管理后台,我们不仅能看到前端的监控网络日志,还能通过traceId查询到后端链路信息。
  5. 告警平台:前端监控系统需要实时或定时推送一些告警邮件等信息。内部告警平台提供了告警策略配置功能,并会主动拉取前端监控数据。接入告警平台,能够减轻前端监控系统自身在告警方面的工作量,确保告警信息能够及时、准确地发送给相关人员。
  6. 操作日志平台:在网关层,操作日志平台可以拦截管理台的操作请求,记录用户在系统中的操作行为。这些操作日志有助于进行敏感操作追溯以及报警,保障系统的安全和合规性。
  7. SPA 平台SPA平台是公司内部自研的静态资源发布平台,可用于半自动化管理业务项目,包括配置注入、静态资源管理等。前端监控在收集到压缩代码的报错时,需要通过sourceMap文件解析转换为源代码。大部分前端监控方案需要手动上传sourceMap文件到监控系统,而使用SPA平台后,资源被统一管理,我们可以通过内部配置将sourceMap文件存放在约定位置,免去了业务方手动上传的繁琐操作,提高了系统的易用性。

3.3 高效运维

一个稳定运行的线上系统离不开高效的运维服务。

  1. 日志抓取:运维服务负责抓取前端监控系统产生的各种日志,包括客户端SDK上报的日志、服务端运行日志等,这些日志为系统的问题排查和优化提供了重要依据。
  2. 自动化构建:通过自动化构建工具,实现代码的自动编译、打包和部署,提高开发和部署效率,减少人为错误。
  3. 容器化:将前端监控系统进行容器化部署,使用容器技术(如 Docker)可以实现环境的一致性和隔离性,方便系统的管理和维护,提高系统的可扩展性和稳定性。
  4. 负载均衡:采用负载均衡技术,将客户端请求均匀分配到多个服务器实例上,避免单个服务器负载过高,提高系统的整体性能和可用性。
  5. 健康检测、安全关闭:前端监控系统随时都会接收业务方上报的数据,在系统重启或关闭时,必须确保服务不间断且数据不丢失。当更新代码并重新构建时,首先会预先启动新的容器,待新容器启动完成后,逐步关闭替换旧的服务。旧服务在关闭前会收到通知,停止接收新的处理任务,待所有正在执行的任务处理完毕后再关闭,从而保障系统的稳定运行。

4.2 数据录入

数据收集后,不能直接录入数据库,需要经过一定处理。

  1. SDK 过滤:一些三方业务接口和资源请求量较大,且自身可能频繁报错,或者存在一些内部接口我们不希望收集数据,这些数据会干扰监控数据的准确性。因此,客户端SDK提供过滤配置,业务方可以根据业务需求过滤不需要收集的接口等,也可以内置企业约定过滤的接口路径。
  2. 服务端处理SDK上报的数据,服务端需要进行二次处理后再保存。例如,为了方便查询,可能需要对原始数据进行拆分等操作,确保存储到数据库中的数据格式和结构符合查询和分析的要求。

4.3 数据分析

数据录入数据库后,就可以进行分析和查询了。除了管理台提供的基础数据查询功能,我们还通过图表和日报等形式来满足不同的使用场景。

  1. 日报:日报从已有的数据中筛选出重点信息和分析后的内容。虽然监控平台随时可查,但用户可能无法时刻关注。日报主要面向开发和测试人员,帮助他们及时了解系统的关键信息和问题。
  2. 图表:图表是一种直观的数据展示形式,如页面性能加载实时图表、实时错误图表等。在上线新版本等关键时期,开发人员可以通过实时关注图表变化,及时发现性能问题和错误趋势,为及时调整和优化提供依据。

五、问题发现与解决

5.1 自动化集成测试

JS - SDK作为一个需要长期维护和更新的独立库,被广泛应用于众多业务项目中。随着代码量和特性的不断增加,人工测试成本急剧上升,测试覆盖率低,开发过程缺乏安全感。因此,我们从零开始完善自动化集成测试。JS - SDK主要通过加入探针监听业务项目的运行状态来收集信息,集成测试是重点关注对象。由于Web SDK运行依赖Web浏览器环境,不能单纯在node中运行,目前我们采用两种测试方式:

  1. 终端测试:支持持续集成环境,即代码提交到仓库后,在托管平台提供的环境中进行托管测试,确保代码在不同环境中的兼容性和稳定性。
  2. 浏览器测试:让代码运行在真实的浏览器环境中,不仅可以进行功能测试,还能进行浏览器兼容性测试,确保SDK在各种主流浏览器上都能正常工作。

5.2 数据聚合

在管理台查看监控数据时,需要对数据进行聚合归类,以便清晰展示。但实际中存在一些影响数据聚合的因素:

  1. 动态路由:部分接口使用动态路由设置参数,如xxx.com/api/getuid/15501/detail。这种接口会导致无法根据url聚合同一个接口。为此,SDK默认将此类接口的动态参数部分替换为*,例如上述链接变为xxx.com/api/getuid/*/detail,这样服务端就能将它们归类为一个接口。目前采用正则匹配全数字的方式,适用于内部接口服务参数为纯数字的情况。若动态参数部分存在非纯数字参数,则无法判别,此时需要SDK提供配置列表,由业务方配置相关链接,

六、专有名词解释

  1. PV(Page View) :页面浏览量,指用户访问网站页面的次数。每一次页面刷新或重新加载都会使 PV 增加。它反映了页面的受欢迎程度和用户对内容的关注度。例如,一个新闻网站某篇热门文章一天内 PV 达到 10 万,说明该文章被大量用户浏览。
  2. UV(Unique Visitor) :独立访客数,指在一定时间内访问网站的不同用户数量。同一用户在一天内多次访问只计为 1 个 UV。通过 UV 可了解网站的实际用户覆盖范围。比如,一个电商网站一天的 UV 为 5 万,意味着当天有 5 万不同用户访问了该网站。
  3. TTFB(Time to First Byte) :首字节时间,是指从浏览器发起请求到接收到服务器返回的第一个字节所花费的时间。它反映了服务器的响应速度,受网络延迟、服务器性能等因素影响。例如,一个页面的 TTFB 为 500ms,说明从用户请求到开始接收数据用了 0.5 秒。
  4. FCP(First Contentful Paint) :首次内容绘制时间,指浏览器首次将任何文本、图像、非空白 canvas 或 SVG 渲染到屏幕的时间。这是衡量页面加载速度和用户体验的重要指标。如果 FCP 在 1 秒内,用户通常会感觉页面加载迅速。

七、前端性能监控

  1. 页面加载性能

    • 使用 Performance API:浏览器提供的 Performance API 可精确测量页面加载相关时间。例如,获取页面完全加载时间:

javascript

const loadTime = window.performance.timing.loadEventEnd - window.performance.timing.navigationStart;
console.log(`页面加载时间: ${loadTime} 毫秒`);
  • 资源加载监控:监听load事件,统计所有资源(如脚本、样式表、图片)的加载时间,找出加载缓慢的资源。

javascript

const resources = [];
const resourceTypes = ['script','style', 'image'];
resourceTypes.forEach(type => {
    document.addEventListener('load', function (event) {
        if (event.target.tagName.toLowerCase() === type) {
            const startTime = event.target.startTime;
            const endTime = performance.now();
            const loadTime = endTime - startTime;
            resources.push({ type, loadTime });
        }
    });
});

2. 用户交互性能

*   **帧率监控**:通过`requestAnimationFrame`计算帧率,判断页面动画和交互的流畅度。正常帧率应保持在 60fps 左右。

javascript

let frameCount = 0;
let startTime = performance.now();
function monitorFPS() {
    requestAnimationFrame(() => {
        frameCount++;
        const now = performance.now();
        const elapsed = now - startTime;
        if (elapsed >= 1000) {
            const fps = frameCount / (elapsed / 1000);
            console.log(`当前帧率: ${fps} fps`);
            frameCount = 0;
            startTime = now;
        }
        monitorFPS();
    });
}
monitorFPS();
  • 输入延迟监控:使用Performance.now()记录用户输入事件(如点击、按键)发生时间和实际处理时间,计算输入延迟。

八、前端错误收集

  1. 全局错误捕获

    • window.onerror:在浏览器环境中,可通过window.onerror捕获未被 try - catch 块处理的 JavaScript 错误。

javascript

window.onerror = function (message, source, lineno, colno, error) {
    console.log(`错误信息: ${message}`);
    console.log(`错误源: ${source}`);
    console.log(`行号: ${lineno}`);
    console.log(`列号: ${colno}`);
    console.log(`错误对象: ${error}`);
    return true; // 阻止默认的错误处理行为
};
  • Promise.reject:全局捕获未处理的 Promise 拒绝错误。

javascript

window.addEventListener('unhandledrejection', function (event) {
    console.log(`未处理的Promise拒绝: ${event.reason}`);
    event.preventDefault();
});

2. 框架特定错误捕获

*   **React**:使用`ErrorBoundary`组件捕获其子组件树中的 JavaScript 错误。

javascript

class ErrorBoundary extends React.Component {
    constructor(props) {
        super(props);
        this.state = { hasError: false };
    }
    componentDidCatch(error, errorInfo) {
        console.log(`React错误: ${error}`);
        console.log(`错误信息: ${errorInfo}`);
        this.setState({ hasError: true });
    }
    render() {
        if (this.state.hasError) {
            return <div>发生错误,组件渲染失败</div>;
        }
        return this.props.children;
    }
}
  • Vue:在 Vue 应用中,通过errorHandler全局配置捕获错误。

javascript

Vue.config.errorHandler = function (err, vm, info) {
    console.log(`Vue错误: ${err}`);
    console.log(`组件实例: ${vm}`);
    console.log(`错误信息: ${info}`);
};

前端监控平台是保障前端应用质量的重要手段。通过了解主流监控平台方案、掌握性能监控与错误收集方法、熟悉关键专有名词,前端架构师能够构建更稳定、高效的前端应用,为用户带来优质体验。