前端监控指的是什么?
前端监控分为三个方面:
- 异常监控(监控前端页面的报错)
 - 性能监控(监控页面的性能)
 - 用户行为监控(监控用户的行为,计算PV、UV、在线时间等、数据监控即我们常说的埋点
 
例子1
 在后端突然上线了某个需求,某个接口的数据格式发生了变化,造成lavaScript运行错误,导致我们的用户比如按钮点不动、页面白屏之类的错误,影响用户体验
例子2
 多个用户反馈我们系统的某个界面反应速度慢,前端自查后发现前端代码并没有问题,然后回猜
 测是不是接口返回速度过慢,直接去和后端沟通的话,没有数据支撑,无法使后端同学信服,最终影响用户体验
例子3
 解决技术产出的问题,技术产出和业务的好坏相关的,上线用户行为监控可以统计某个功能模块的具体使用情况,如果产品经理提出同类型产品需求的时候,如果上次产品效果不好,我们可以质疑产品经理提出的需求是否具有价值。
1、异常监控
- JS 代码运行错误、语法错误等;
 - AJAX 请求错误;
 - 静态资源加载错误;
 - Promise 异步函数错误;
 
错误信息监控简单来说就是要搜集报错信息的发生的位置,以及报错的类型,进行上报,便于我们能够更好的掌握错误信息,从而能够对症下药。按照 5W1H 的法则来说,我们需要关注以下的几项信息:
- What ,发生了什么错误:语法错误、类型错误、数据错误、逻辑错误等;
 - When ,什么时间发生的错误,可带上时间戳进行上报;
 - Who ,哪个用户或者哪一类用户发生了错误,包括用户 ID 、设备信息、IP 信息等;
 - Where ,哪个项目、哪些页面发生错误,可以上报页面的 URL 以及代码报错行数等信息;
 - Why ,为什么会发生错误,也就是用户在什么样的场景下发生的错误,便于问题复现;
 - How ,根据以上的信息如何进行问题的定位,然后怎么处理并解决问题;
 
常见的错误捕获方法主要是 try / catch 、window.onerror 和window.addEventListener 等。
try / catch
这是我们在代码调试的过程中最常用的一个方式,但它只能捕获代码常规的运行错误,语法错误和异步错误并能捕获到。
// 常规运行时错误,可以捕获 ✅
try {console.log(notdefined);
} catch(e) {console.log('捕获到异常:', 'ReferenceError');}// 语法错误,不能捕获 ❌
try {const notdefined,
} catch(e) {console.log('捕获不到异常:', 'Uncaught SyntaxError');
}// 异步错误,不能捕获 ❌
try {setTimeout(() => {console.log(notdefined);}, 0)
} catch(e) {console.log('捕获不到异常:', 'Uncaught ReferenceError');
}
 
window.onerror
当 JS 运行时错误发生时,window 会触发一个 ErrorEvent 接口的 error 事件,并执行 window.onerror() 。
加载一个全局的 error 事件处理函数可用于自动收集错误报告。
最后需要补充的是:window.onerror 函数只有在返回 true 的时候,异常才不会向上抛出,否则即使是知道异常的发生,控制台还是会显示 Uncaught Error 。
```javascript
/*** @param { string } message 错误信息
* @param { string } source 发生错误的脚本URL
* @param { number } lineno 发生错误的行号
* @param { number } colno 发生错误的列号
* @param { object } error Error对象*/window.onerror = function(message, source, lineno, colno, error) {console.log('捕获到的错误信息是:', message, source, lineno, colno, error )
}// 常规运行时错误,可以捕获 ✅
window.onerror = function(message, source, lineno, colno, error) {console.log('捕获到异常:',{message, source, lineno, colno, error});
}
console.log(notdefined);
// message: "Uncaught ReferenceError: notdefined is not defined"
// source: "file:///C:/Users/qinzq42866/Desktop/error.html"
// lineno: 14
// colno: 19
// error: ReferenceError: notdefined is not defined at file
// 语法错误,不能捕获 ❌
window.onerror = function(message, source, lineno, colno, error) {console.log('未捕获到异常:',{message, source, lineno, colno, error});
}
const notdefined,
// Uncaught SyntaxError: Missing initializer in const declaration// 异步错误,可以捕获 ✅
window.onerror = function(message, source, lineno, colno, error) {console.log('捕获到异常:',{message, source, lineno, colno, error});
}
setTimeout(() => {console.log(notdefined);
}, 0)// message: "Uncaught ReferenceError: notdefined is not defined"// source: "file:///C:/Users/qinzq42866/Desktop/error.html"// lineno: 15// colno: 21// error: ReferenceError: notdefined is not defined at file// 资源错误,不能捕获 ❌
<script>
window.onerror = function(message, source, lineno, colno, error) {console.log('捕获到异常:',{message, source, lineno, colno, error});
}</script>// GET https://yun.tuia.cn/image/kkk.png 404 (Not Found)
 
window.addEventListener
当一项静态资源加载失败时,加载资源的元素会触发一个 Event 接口的 Error 事件,这些 Error 事件不会向上冒泡到 window ,但能被捕获。而 window.onerror 不能检测捕获。
// 图片、script、css加载错误,都能被捕获 ✅<script>window.addEventListener('error', (error) => {console.log('捕获到异常:', error);}, true)</script>// fetch错误,不能捕获 ❌<script>window.addEventListener('error', (error) => {console.log('未捕获到异常:', error);}, true)</script<script>fetch('https://tuia.cn/test')</script>
 
由于网络请求异常不会发生事件冒泡,因此必须在事件捕获的阶段将其捕捉到才行,这种方式虽然能够捕捉到网络请求的异常,但是却无法判断 HTTP 的状态,因此仍然需要配合服务端的日志进行配合分析。
需要注意的是:不同浏览器下返回的 Error 对象是不一样的,需要做兼容处理。
Promise 错误
没有写 catch 的 Promise 中抛出的错误是无法被 onerror 或 try / catch 捕获到的,这也是为什么我们一定要在 Promise 后面加上 catch 去捕获和处理异常。
为了防止有漏掉的 Promise 异常信息,建议在全局增加一个对 unhandledrejection 的监听,用来全局监听 Uncaught Promise Error 。
说明:当 Promise 被 reject 且没有 reject 处理器的时候,会触发 unhandledrejection 事件;这可能发生在 window 下,但也可能发生在 Worker 中。 这对于调试回退错误处理非常有用。
  
window.addEventListener("unhandledrejection", event => {console.warn('UNHANDLED PROMISE REJECTION:', ${event.reason});});window.onunhandledrejection = event => {console.warn('UNHANDLED PROMISE REJECTION:', ${event.reason});};window.addEventListener("unhandledrejection", function(e){e.preventDefault()console.log('捕获到异常:', e);});Promise.reject('promise error');
 
说明:如果去掉控制台的异常显示,需要加上 event.preventDefault() ;
Vue 错误
由于 Vue 会捕获到所有 Vue 单文件组件或者 Vue.extend 继承的代码,所以在 Vue 里面出现的错误并不会直接抛给 window.onerror ,而是会被 Vue 自身的 Vue.config.errorHandler 捕获。
Vue.config.errorHandler = (err, vm, info) => {console.error('通过vue errorHandler捕获的错误');console.error(err);console.error(vm);console.error(info);}
 
React 错误
React 16 提供了一个内置函数 componentDidCatch ,使用它可以轻松的捕获到 React 组件内部抛出的错误信息。
class ErrorBoundary extends React.Component {constructor(props) {super(props);this.state = { hasError: false };}componentDidCatch(error, errorInfo) {console.log('捕获到错误:', error, errorInfo);}render() {if (this.state.hasError) {return `Something went wrong.`;}return this.props.children; }
}
 
 
2、性能监控
- 不同用户和不同设备下的首屏加载时间,包括白屏时间;
 - HTTP 接口的响应时间;
 - 静态资源、包括图片的下载时间;
 
根据W3C性能小组引入的新的API(目前IE9以上的浏览器)--window.performance,实现前端性能监控

(function () {handleAddListener('load', getTiming)function handleAddListener(type, fn) {if (window.addEventListener) {window.addEventListener(type, fn)} else {window.attachEvent('on' + type, fn)}}function getTiming() {try {var time = performance.timing;var timingObj = {};var loadTime = (time.loadEventEnd - time.loadEventStart);if (loadTime < 0) {setTimeout(function () {getTiming();}, 200);return;}// 阶段耗时timingObj['DNS解析耗时'] = (time.domainLookupEnd - time.domainLookupStart);timingObj['TCP连接耗时'] = (time.connectEnd - time.connectStart);timingObj['SSL安全连接耗时'] = (time.connectEnd - time.secureConnectionStart);//针对httpstimingObj['网络请求耗时'] = (time.responseStart - time.requestStart);timingObj['数据传输耗时'] = (time.responseEnd - time.responseStart);timingObj['DOM解析耗时'] = (time.domInteractive - time.responseEnd);timingObj['资源加载耗时, 表示页面中的同步加载资源'] = (time.loadEventStart - time.domContentLoadedEventEnd);timingObj['前端onload执行时间'] = (time.loadEventEnd - time.loadEventStart);//性能指标(上报字段名)timingObj["首次渲染"] = time.responseEnd - time.fetchStart// timingObj["首屏时间"] =  first meaningful painttimingObj["首次可交互"] = time.domInteractive - time.fetchStarttimingObj["DOMReady"] = time.domContentLoadedEventEnd - time.fetchStarttimingObj["页面完全加载"] = time.loadEventStart - time.fetchStarttimingObj["首包时间"] = time.responseStart - time.domainLookupStartfor (item in timingObj) {console.log(item + ":" + timingObj[item] + '毫秒(ms)');}console.log(performance.timing);console.log(performance);} catch (e) {console.log(timingObj)console.log(performance.timing);}}
})(); 
3、用户行为监控-埋点
- PV / UV:PV 即 Page View ,也就是页面的浏览数量,没打开页面一次就会统计一次;UV 即 User View ,也就是不同用户访问的次数,在 PV 的基础上根据 User 信息的不同做了去重操作;
 - 用户在每个页面停留的时间信息。即从用户打开该页面到用户离开该页面的时间差,用于表示该页面对用户的留存程度;
 - 用户的来处。即从什么入口或什么渠道来到了当前页面,通常会在 URL 中添加查询参数来做区分统计;
 - 用户的页面操作行为。即用户在该页面点击了哪些按钮,或者从什么链接去到了某些页面等等,来分析用户的去向。
 
网站埋点的get请求可能会由于页面的跳转被中断掉,该如何解决?
目前只想到一个思路,把这些需要发送的参数先缓存起来,放到localStorage中,以时间戳作为key值保证不重复,请求发送成功之后再把这条记录删除掉。跳转到某个安全页面之后再把这些缓存的数据异步发出去。
一般来说get请求我们可以直接new Image()的方式进行,当然也可以采用CORS的方式,直接$.get(),不过这两种方式经测试都会在某些场景下被中断掉。
相关文章:
前端监控指的是什么?
前端监控分为三个方面: 异常监控(监控前端页面的报错)性能监控(监控页面的性能)用户行为监控(监控用户的行为,计算PV、UV、在线时间等、数据监控即我们常说的埋点 例子1 在后端突然上线了某个需…...
.net core 面试题 2023
文章目录1. 什么是 ASP.net core2. .net 术语3. 托管资源 和 非托管资源4. GC 和 垃圾回收5. .net中所有类的基类6. 如何实现对象的深拷贝7. 依赖注入,为什么使用依赖注入8. IOC容器的注入方法9. ASP.net core 中 服务生命周期10. scoped的 service 可以注入到 sing…...
和ChatGPT关于Swing music的一场对话(上篇)
什么是 Swing Music ? Swing Music 是一款漂亮的自托管音乐播放器,适用于您的本地音频文件。就像一个更酷的 Spotify …但带上你自己的音乐。 第一次在 reddit 上看到 Swing Music,就被其 UI 吸引了 但源码站点的releases 中只有 windows 和 …...
java版工程项目管理系统源码 Spring Cloud+Spring Boot+Mybatis+Vue+ElementUI+前后端分离 功能清单
ava版工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离 功能清单如下: 首页 工作台:待办工作、消息通知、预警信息,点击可进入相应的列表 项目进度图表:选择(总体或单个)项目显示1…...
debian 10 扩展分区容量
debian 10 扩展分区容量1、扩展分区原因2、添加一块磁盘3、命令记录3.1、新增加的磁盘是/dev/sdb3.2、使用磁盘/dev/sdb 创建物理卷3.3、 把物理卷/dev/sdb加入到卷组debian-vg中3.4、查看物理卷、逻辑卷3.5、扩展逻辑卷/tmp3.6、逻辑卷组debian-vg 空余空间被用掉10g 还剩90g可…...
【无功优化】基于改进遗传算法的电力系统无功优化研究【IEEE30节点】(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
LeetCode 218. 天际线问题
城市的 天际线 是从远处观看该城市中所有建筑物形成的轮廓的外部轮廓。给你所有建筑物的位置和高度,请返回 由这些建筑物形成的 天际线 。 每个建筑物的几何信息由数组 buildings 表示,其中三元组 buildings[i] [lefti, righti, heighti] 表示…...
Logstash:使用自定义正则表达式模式
有时 Logstash Grok 没有我们需要的模式。 幸运的是我们有正则表达式库:Oniguruma。在很多时候,如果 Logstash 所提供的正则表达不能满足我们的需求,我们选用定制自己的表达式。 定义 Logstash 是一种服务器端数据处理管道,可同时…...
常见的一致性问题及解决
什么是一致性 一致性问题主要是因为分布式系统中的多个节点之间可能存在网络延迟、故障等原因导致的。具体而言,分布式系统中的数据一致性问题可以分为以下几种类型: 强一致性:指在任何时间点,所有节点中的数据都是一致的。这种…...
vue下载文件
注意请求时加入:responseType: bloburl:写全了,因为前后端端口号不同downloadImage(imgUrl) {let formData new FormData();formData.append(fileName, this.getFilename(imgUrl)); // 用于后端下载文件的路径axios.post(http://localhost:8…...
人人都是数据分析师-数据分析之数据图表可视化(下)
当前的BI报表、运营同学的汇报报告中数据图表大多为 表格、折线图、柱状图和饼图,但是实际上还有很多具有代表性的可视化图表,因此将对常见的可视化图表进行介绍,希望这些图表可视化方法能够更好的提供数据的可用性。 人人都是数据分析师-数…...
考勤、充电,绑身份,你的人员定位系统就缺它了!
我们做人脸识别智能发卡充电柜是要解决什么问题? (1)工地、港口等场景,人员流动大,管理难 在工地、港口等场景,人员组成通常比较复杂。有来自施工方、客户、各劳务队、各管理层的人员,以及来自…...
RocketMQ水平扩展及负载均衡详解
文章目录 Broker端水平扩展Broker负载均衡commit logProducer负载均衡Consumer负载均衡集群模式广播模式RocketMQ是一个分布式具有高度可扩展性的消息中间件。本文旨在探索在broker端,生产端,以及消费端是如何做到横向扩展以及负载均衡的。 Broker端水平扩展 Broker负载均衡…...
java接口笔记
关键字:interface 定义形式:interface 接口名 { 接口体 } 细节: 1.接口里的方法可以为抽象方法,静态方法,默认方法(default 关键字) 2.接口里的方法只能是public ,可以不用写&a…...
安利安利-向大家推荐一个超级牛的etcd管理工具-EtcdKeeperFyne
etcd介绍 关于etcd的介绍大家可以看下这篇文章 etcd 开源仓库地址:EtcdKeeperFyne EtcdKeeperFyne 今天主要是向大家推荐一款使用起来特别方便的Etcd管理工具 EtcdKeeperFyne,具体运行起来的界面如下: 推荐原因 使用简单安装简单&…...
数字经济系列讲座-数字化平台(商业购物平台)
数字经济系列讲座 文章目录 钱的流向退货成本research questionLiterature review现金流发生在平台内侧平台商业模式转型Modelmodel 假设四种情形标记符利润函数&效用函数&平台效益模型构建利润对比图结论future directions讲座题目 To Adopt or not? The Impacts of…...
python3中collections模块详解
collections模块简介 collections包含了一些特殊的容器,针对Python内置的容器,例如list、dict、set和tuple,提供了另一种选择; namedtuple,可以创建包含名称的tuple; deque,类似于list的容器&a…...
护网面试题2.0
1.CSS和CSRF区别 通俗点讲的话: XSS通过构造恶意语句获取对方cookie, CSRF通过构造恶意链接利用对方cookie,但看不到cookie XSS比CSRF更加容易发生,但CSRF比XSS攻击危害更大 2.XSS原理 XSS(Cross-Site Scripting&…...
学习计算机组成原理第1天(计算机发展历程)
计算机发展历程计算机硬件发展计算机软件的发展经典例题计算机硬件发展 计算机的四代变化 1)第一代计算机(1946-1957年)电子管时代。特点:逻辑元件采用电子管;使用机器语言进行编程;主存用延迟线或磁鼓存储…...
二维字符数组与char** 关系 段错误打印
如下为错误,打印断错误。 具体原因参考 http://c.biancheng.net/view/2022.html 二维字符数组与char** 关系 原因: char a[2][20] ; 这是一个二维字符数组。 二维字符数组,这里相当于是两个一维字符串数组。这两个数组在内存的存放位置可以…...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...
AI编程--插件对比分析:CodeRider、GitHub Copilot及其他
AI编程插件对比分析:CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展,AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者,分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...
docker 部署发现spring.profiles.active 问题
报错: org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...
MFC 抛体运动模拟:常见问题解决与界面美化
在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...
Go语言多线程问题
打印零与奇偶数(leetcode 1116) 方法1:使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...
MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)
macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 🍺 最新版brew安装慢到怀疑人生?别怕,教你轻松起飞! 最近Homebrew更新至最新版,每次执行 brew 命令时都会自动从官方地址 https://formulae.…...
为什么要创建 Vue 实例
核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...
PHP 8.5 即将发布:管道操作符、强力调试
前不久,PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5!作为 PHP 语言的又一次重要迭代,PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是,借助强大的本地开发环境 ServBay&am…...
深度学习之模型压缩三驾马车:模型剪枝、模型量化、知识蒸馏
一、引言 在深度学习中,我们训练出的神经网络往往非常庞大(比如像 ResNet、YOLOv8、Vision Transformer),虽然精度很高,但“太重”了,运行起来很慢,占用内存大,不适合部署到手机、摄…...
uni-app学习笔记三十五--扩展组件的安装和使用
由于内置组件不能满足日常开发需要,uniapp官方也提供了众多的扩展组件供我们使用。由于不是内置组件,需要安装才能使用。 一、安装扩展插件 安装方法: 1.访问uniapp官方文档组件部分:组件使用的入门教程 | uni-app官网 点击左侧…...
