共计 5996 个字符,预计需要花费 15 分钟才能阅读完成。
编写 ” 谷歌扩大 ” 便捷 ” 自测 ” 埋点上报信息是否正确
举荐我之前写的谷歌扩大入门 &svelte 入门文章:
记一次前端 ”chrome 扩大 ” 简略易懂的实战分享会 (上)
记一次前端 ”chrome 插件 ” 根底实战分享会 (倡议珍藏)(下篇)
聊聊 Svelte.js 技术它做了什么以及如何实现的 (上)
聊聊 Svelte.js 技术它做了什么以及如何实现的(下)
背景
每次开发完我的项目的埋点性能后都须要进行埋点自测, 此时我只能通过在控制台的 Network
上进行筛选, 因为埋点的申请参数是个 ” 对象类型 ”, 须要将传参逐一点开并且找到 params
这个 key, 然而 params
是一个被 json 序列化的字符串, 须要进行 JSON.parse(xxxxx.params);
, 而后再关上它外面的 数组构造
因为可能是多个埋点信息一起上报所以 JSON.parse
后是个数据, 最初还要将外面的十个固有参数过滤掉只看咱们新增的埋点参数。
上述过程很有法则所以能够形象成一个工具查找的逻辑, 那咱们能够把问题拆解成 3 步:
- (展现)有适合的界面不便显示你想要的申请数据。
- (获取)拦挡到你想要的申请。
- (解决)将申请的参数按固定规定解析, 剔除不须要查看的参数与父级。
- (配置)可配置哪些申请须要被监测。
当然不只是 埋点
这个性能, 只有你有剖析 api 数据的需要都能够做相似的插件。
最终成果
一、模仿数据的定义
埋点上报数据我这里展现一个大略的数据结构, 大家依据业务自行调节, 假如上面的数据结构就是埋点上报 api 的上报参数
[
{
events: [
{
eventName: "事件名: 点击事件",
params:
'{"default1":"xxxxx","default2":"xxxxx","default3":"xxxxx","default4":"xxxxx","default5":"xxxxx","default6":"xxxxx","startTime":"xxxxx","endTime":"xxxxxxx","new1":"nnnnnn1","new2":"nnnnnn2"}',
xxxxxxxx: 1636179764881,
xxxxxxx: 0,
},
{
eventName: "事件名: 勾销事件",
params:
'{"default1":"xxxxx","default2":"xxxxx","default3":"xxxxx","default4":"xxxxx","default5":"xxxxx","default6":"xxxxx","startTime":"xxxxx","endTime":"xxxxxxx","new1":"nnnnnn2","new3":"nnnnnn3"}',
xxxxxxxx: 1636179764881,
xxxxxxx: 0,
},
],
user: {
userId: 123,
userName: "lulu",
},
header: {
app_id: 999,
os_name: "mac",
os_version: "10_15_7",
device_model: "Macintosh",
language: "zh-CN",
},
},
];
- 传参自身是个 ” 对象类型 ”
- 第一层次要是 ” 埋点事件 ”, “ 用户信息 ”, “ 设施信息 & 更多 ”
- “events” 是事件数组
- “eventName” 事件名称, “params” 外面是被 ”JSON 序列化 ” 的事件参数
- “params” 里有一些咱们不必看的默认值, 因为每个埋点都会带一些像 ” 门路信息 ”&” 停留事件 ”&” 用户操作门路 ” 等等的默认信息, 这些信息不必咱们手动退出所以也就不必每次都看他的正确性。
- “new1, new2, new3″ 是咱们新退出的参数, 也就是咱们这次重点验证的参数
二、模仿埋点数据的收回
编写两个按钮负责上报埋点申请, 不便咱们后续的验证, 新建一个 html 文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<button onclick="send(`https://zhangzhaosong1.com/`)"> 点击上报 1 </button>
<button onclick="send(`https://zhangzhaosong2.com/`)"> 点击上报 2 </button>
<script>
function send(url) {
fetch(url, {
method: "post",
headers: {"Content-Type": "application/json;charset=utf-8;",},
body: JSON.stringify([
{
events: [
{
eventName: "事件名: 点击事件",
params:
'{"default1":"xxxxx","default2":"xxxxx","default3":"xxxxx","default4":"xxxxx","default5":"xxxxx","default6":"xxxxx","startTime":"xxxxx","endTime":"xxxxxxx","new1":"nnnnnn1","new2":"nnnnnn2"}',
xxxxxxxx: 1636179764881,
xxxxxxx: 0,
},
{
eventName: "事件名: 勾销事件",
params:
'{"default1":"xxxxx","default2":"xxxxx","default3":"xxxxx","default4":"xxxxx","default5":"xxxxx","default6":"xxxxx","startTime":"xxxxx","endTime":"xxxxxxx","new1":"nnnnnn2","new3":"nnnnnn3"}',
xxxxxxxx: 1636179764881,
xxxxxxx: 0,
},
],
user: {
userId: 123,
userName: "lulu",
},
header: {
app_id: 999,
os_name: "mac",
os_version: "10_15_7",
device_model: "Macintosh",
language: "zh-CN",
},
},
]),
}).then(() => {});
}
</script>
</body>
</html>
下面 html 外面次要做的工作是增加两个 ” 按钮 ”, 每次点击收回埋点的模仿上报的 post 申请, 每个按钮上报的不一样所以有两个按钮。
三、创立一个谷歌插件我的项目 & 定义图标
没看过基础课的同学肯定要先看看根底文章, 否则没法转换思维。
主文件
manifest.json
{
"manifest_version": 2,
"name": "埋: 更不便的察看埋点数据",
"description": "更不便的察看埋点数据",
"version": "0.1",
"browser_action": {"default_icon": "images/logo.png"}
}
上述的图标大家自由发挥哈
引入插件
四、定义控制台 tab
在 manifest.json 文件外面减少
{
"manifest_version": 2,
"name": "埋: 更不便的察看埋点数据",
"description": "更不便的察看埋点数据",
"version": "0.1",
"browser_action": {"default_icon": "images/logo.png"},
"devtools_page": "devtools/index.html" // 这句是新增的
}
devtools/index.html
次要性能只是引入 js 文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script src="./index.js"></script>
</body>
</html>
devtools/index.js
次要性能是创立 tab
chrome.devtools.panels.create(
"埋点验证 tab, 还原埋点上报信息",
null,
"../panel/index.html",
function () {console.log("自定义面板创立胜利!");
}
);
在 panel/index.html
外面才是 tab 的内容区款式:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div> 创立胜利 </div>
</body>
</html>
五、初始化 svelte 我的项目
tab 外面的内容咱们懒得原生操作 dom, 应用 ”react” 框架有点重, 所以这次我抉择了 ”svelte 框架 ”, 具体它的益处能够看看我之前写的文章(文章放在文章头部了)。
初始我的项目
npx degit sveltejs/template devpanel
cd ./devpanel
yarn
咱们编辑一下 rollup.config.js
文件, 使得打包后的文件间接放入 panel
文件夹里。
output: {
sourcemap: false,
format: "iife",
name: "app",
file: production ? "../panel/index.js" : "public/build/bundle.js",
},
并且将 panel
外面的 index.html
文件的文件援用指向咱们的index.js 文件
, 以及引入款式 <link rel="stylesheet" href="./bundle.css">
在这里运行命令 yarn build
后的成果如下, 请点击刷新插件并且 ”F12″ 从新关上控制台:
开发时候在localhost:5000/
, 开发完打包就能够和插件一起上线了。
六、拦挡申请
外围性能就是拦挡申请, 让咱们应用onRequestFinished
api
chrome.devtools.network.onRequestFinished.addListener((res) => {})
下面的返回值 res 的数据格式如下图:
要害信息都有, 申请办法与 url 能够用来比对是否为须要拦挡的申请, 而咱们剩下的工作就是对 ”text” 的解析了。
要留神的是, svelte
外面无奈读取到 chrome
的值, 所以须要用 if (chrome) {}
包裹起来, 所以在 svelte 外面开发时我应用的是 mock 数据调试。
七、解决数据
<script>
const path = "https://zhangzhaosong.com/";
import getNowTime from "./getNowTime";
if (chrome) {
let checkEvent = "";
let dataList = [];
const baseKeyArr = [
"default1",
"default2",
"default3",
"default4",
"default5",
"default6",
"startTime",
"endTime",
];
chrome.devtools.network.onRequestFinished.addListener((res) => {
const req = res.request;
if (req.method === "POST" && req.url === path) {const eventsArr = JSON.parse(req.postData.text);
eventsArr.forEach((item) => {if (item.events) {item.events.forEach((event) => {const params = JSON.parse(event.params);
const res = {};
for (let i in params) {if (!baseKeyArr.includes(i)) {res[i] = params[i];
}
}
dataList.unshift({
res,
time: getNowTime(),
eventName: event.eventName,
});
dataList = dataList;
});
}
});
console.log("---", dataList);
}
});
}
</script>
<main>
<div>list</div>
</main>
<style>
</style>
baseKeyArr
这个数组外面是一些埋点默认的key
, 用来过滤掉咱们不关怀的值path
是要拦挡的申请地址, 当然也能够换成正则之类的getNowTime
获取以后的工夫
八、简略设计个款式
将下面失去的数组循环显示进去, 造成一个被拦挡的埋点事件的参数 list:
<main>
{#each Object.keys(dataList) as item}
<div>
<header>
<span>{dataList[item].time} : </span>
<span class="title">{dataList[item].eventName}</span>
</header>
<ul>
{#each Object.keys(dataList[item].res) as key}
<li>
<span>{key} :</span>
<span>{dataList[item].res[key]}</span>
</li>
{/each}
</ul>
</div>
{/each}
</main>
<style>
.title {background-color: bisque;}
</style>
九、过滤性能与革除性能
为了好用咱们能够增加一个过滤性能与革除性能, 这样查看起来更难受:
end
网站快卡炸了, 这次就是这样, 心愿与你一起提高。