定制开发电商网站建设多少钱,免备案空间主机,网站建设与管理pdf,广州市企业网站制作公司前端监控分为三个方面#xff1a;
异常监控#xff08;监控前端页面的报错#xff09;性能监控#xff08;监控页面的性能#xff09;用户行为监控#xff08;监控用户的行为#xff0c;计算PV、UV、在线时间等、数据监控即我们常说的埋点
例子1 在后端突然上线了某个需… 前端监控分为三个方面
异常监控监控前端页面的报错性能监控监控页面的性能用户行为监控监控用户的行为计算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加载错误都能被捕获 ✅scriptwindow.addEventListener(error, (error) {console.log(捕获到异常, error);}, true)/script// fetch错误不能捕获 ❌scriptwindow.addEventListener(error, (error) {console.log(未捕获到异常, error);}, true)/scriptscriptfetch(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 / UVPV 即 Page View 也就是页面的浏览数量没打开页面一次就会统计一次UV 即 User View 也就是不同用户访问的次数在 PV 的基础上根据 User 信息的不同做了去重操作用户在每个页面停留的时间信息。即从用户打开该页面到用户离开该页面的时间差用于表示该页面对用户的留存程度用户的来处。即从什么入口或什么渠道来到了当前页面通常会在 URL 中添加查询参数来做区分统计用户的页面操作行为。即用户在该页面点击了哪些按钮或者从什么链接去到了某些页面等等来分析用户的去向。
网站埋点的get请求可能会由于页面的跳转被中断掉该如何解决
目前只想到一个思路把这些需要发送的参数先缓存起来放到localStorage中以时间戳作为key值保证不重复请求发送成功之后再把这条记录删除掉。跳转到某个安全页面之后再把这些缓存的数据异步发出去。
一般来说get请求我们可以直接new Image()的方式进行当然也可以采用CORS的方式直接$.get()不过这两种方式经测试都会在某些场景下被中断掉。