⭐前言
大家好,我是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 {
// performance
private performanceConfig: PerfType = {
fmp_count: 0,
dcl_count: 0,
dns_count: 0,
tcp_count: 0,
};
// api header的token
private token: string = "";
// 完成计算
private isFinishCalPerf = 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.isFinishCalPerf ) {
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.isFinishCalPerf = 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字符串自动上报'});
💖查看上报的数据
⭐结束
💖数据分布展示效果
本文分享到这结束,如有错误或者不足之处欢迎指出!
👍 点赞,是我创作的动力!
⭐️ 收藏,是我努力的方向!
✏️ 评论,是我进步的财富!
💖 最后,感谢你的阅读!