性能监控计算——封装带性能计算并上报的npm包(第三章)
⭐前言
大家好,我是yma16,本文分享 性能监控计算——封装带性能计算并上报的npm包(第三章)。
背景:
为了实现前端性能耗时的数据监控,前端对外发布js的sdk,sdk的功能主要是性能耗时计算和数据上报。同时使用vue3和node开发一个数据监控的后台管理系统,主要功能是展示数据,提供一个api_key和token对外暴露的api接口去添加数据监控数据。
功能:封装性能耗时并上报的npm包。
rollup打包js
Rollup 是一个用于 JavaScript 的模块打包工具,它将小的代码片段编译成更大、更复杂的代码,例如库或应用程序。它使用 JavaScript 的 ES6 版本中包含的新标准化代码模块格式,而不是以前的 CommonJS 和 AMD 等特殊解决方案。ES 模块允许你自由无缝地组合你最喜欢的库中最有用的个别函数。
node系列往期文章
node_windows环境变量配置
node_npm发布包
linux_配置node
node_nvm安装配置
node笔记_http服务搭建(渲染html、json)
node笔记_读文件
node笔记_写文件
node笔记_连接mysql实现crud
node笔记_formidable实现前后端联调的文件上传
node笔记_koa框架介绍
node_koa路由
node_生成目录
node_读写excel
node笔记_读取目录的文件
node笔记——调用免费qq的smtp发送html格式邮箱
node实战——搭建带swagger接口文档的后端koa项目(node后端就业储备知识)
node实战——后端koa结合jwt连接mysql实现权限登录(node后端就业储备知识)
node实战——koa给邮件发送验证码并缓存到redis服务(node后端储备知识)
koa系列项目文章
前端vite+vue3结合后端node+koa——实现代码模板展示平台(支持模糊搜索+分页查询)
node+vue3+mysql前后分离开发范式——实现对数据库表的增删改查
node+vue3+mysql前后分离开发范式——实现视频文件上传并渲染
koa-vue性能监控到封装sdk系列文章
性能监控系统搭建——node_koa实现性能监控数据上报(第一章)
性能监控系统搭建——vue3实现性能监控数据展示(第二章)
⭐ rollup + ts 初始化
💖npm init
package
{"name": "web-performance","version": "1.0.0","description": "","type": "module","main": "./src/main.ts","scripts": {"test": "echo \"Error: no test specified\" && exit 1","build": "rollup --config"},"keywords": ["performance"],"author": "yma16","license": "ISC","dependencies": {"axios": "^1.7.2"},"devDependencies": {"@rollup/plugin-commonjs": "^25.0.8","@rollup/plugin-json": "^6.1.0","@rollup/plugin-node-resolve": "^15.2.3","@rollup/plugin-terser": "^0.4.4","@rollup/plugin-typescript": "^11.1.6","rollup-plugin-babel": "^4.4.0","rollup-plugin-commonjs": "^10.1.0","rollup-plugin-terser": "^7.0.2","rollup-plugin-typescript2": "^0.36.0","typescript": "^5.4.5"}
}
💖src目录编写 main.ts 逻辑上报fmp
main.ts
import { setToken, report } from "./api/index";
type PerfEnum = "fmp_count" | "dns_count" | "dcl_count" | "tcp_count";
type PerfType = {fmp_count: number;dcl_count: number;dns_count: number;tcp_count: number;
};class WebPerformance {// performanceprivate performanceConfig: PerfType = {fmp_count: 0,dcl_count: 0,dns_count: 0,tcp_count: 0,};// api header的tokenprivate token: string = "";// 完成计算private isFinishClalcPerf = false;/*** 构造函数* @param {*} options*/constructor(options: { token: string }) {if (options.token) {this.setTokenAction(options.token);}this.clacPerf();}/*** 配置请求的token* @param {*} token*/public setTokenAction(token: string) {this.token = token;setToken(this.token);if (this.isFinishClalcPerf) {this.reportAction({...this.getPerformance(),name: "appRelaunch",type: "appRelaunch",path: location.href,});}}/*** 上报* @param {*} params*/public reportAction(params: any) {if (!this.token) {return console.warn("no token");}report({ params });}/*** 计算耗时*/private clacPerf() {const observer = new PerformanceObserver((list) => {list.getEntries().forEach((entry: any) => {// 使用performance计算默认耗时const domContentLoadedTime =entry.domContentLoadedEventEnd - entry.domContentLoadedEventStart;const dnsLoadedTime = entry.domainLookupEnd - entry.doaminLookupStart;const tcpLoadedTime = entry.connectEnd - entry.connectStart;const fmpLoadedTime = entry.domContentLoadedEventEnd - entry.startTime;this.setPerformance("fmp_count", fmpLoadedTime);this.setPerformance("dns_count", dnsLoadedTime);this.setPerformance("tcp_count", tcpLoadedTime);this.setPerformance("dcl_count", domContentLoadedTime);this.isFinishClalcPerf = true;// 延时上报setTimeout(() => {this.reportAction({...this.getPerformance(),name: "appRelaunch",type: "appRelaunch",path: location.href,});});});});observer.observe({ type: "navigation", buffered: true });}/*** 获取performance* @returns*/getPerformance() {return this.performanceConfig;}/*** 配置performance* @param {*} key* @param {*} value*/private setPerformance(key: PerfEnum, value: number) {this.performanceConfig[key] = value;}
}export { WebPerformance };
api 调用axios
import axios from 'axios';
// 添加请求拦截器
axios.interceptors.request.use(function(config) {// 在发送请求之前做些什么return config;
}, function(error) {// 对请求错误做些什么return Promise.reject(error);
});// 添加响应拦截器
axios.interceptors.response.use(function(response) {// 2xx 范围内的状态码都会触发该函数。// 对响应数据做点什么return response;
}, function(error) {// 超出 2xx 范围的状态码都会触发该函数。// 对响应错误做点什么return Promise.reject(error);
});// 创建实例时配置默认值
const instance = axios.create({baseURL: ''
});export default instance
接口上报report
import request from "./request";export const setToken = (token: string) => {request.defaults.headers.common["Authorization"] = `${token}`;
};export const report: any = (params: any) => {return request.post("/cloudApi/perf/list", params);
};
💖tsconfig配置
tsconfig.json配置
{"compilerOptions": {"moduleResolution": "node","target": "es5","module":"es2015","lib": ["es2015", "es2016", "es2017", "dom"],"strict": true,"sourceMap": true,"declaration": true,"allowSyntheticDefaultImports": true,"experimentalDecorators": true,"emitDecoratorMetadata": true,"declarationDir": "dist/types","resolveJsonModule": true,"outDir": "dist/es","typeRoots": ["node_modules/@types",]},"include": ["src",], // 包含要编译的文件
}
💖rollup 配置
rollup.config.js
// rollup.config.js
import typescript from '@rollup/plugin-typescript';
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import json from '@rollup/plugin-json';
import babel from 'rollup-plugin-babel';
// import terser from '@rollup/plugin-terser';
export default {input: 'src/main.ts',output: [{file: 'dist/index.js',sourcemap: false // 生成 source map // format: 'iife', // 输出的格式 }],plugins: [typescript(),resolve(),commonjs(),babel(),json(),],// axios太大 排除打包external: ['axios']
};
⭐打包结果
打包json格式化index.js,其中类型已经自动转移到types目录下
💖npm使用
import {WebPerformance} from 'web-performance-tool';
new WebPerformance({token:'token字符串自动上报'});
💖查看上报的数据
⭐结束
💖数据分布展示效果
本文分享到这结束,如有错误或者不足之处欢迎指出!
👍 点赞,是我创作的动力!
⭐️ 收藏,是我努力的方向!
✏️ 评论,是我进步的财富!
💖 最后,感谢你的阅读!