每一个公司要想用户增长,都要收集和分析用户操作数据,因此埋点是必不可少的事情。
而对于前端职业发展来说,传统的手动埋点,无疑是繁琐又无聊的事情,能简化就简化。
手动埋点就是在每一处需要的地方,都加一段上报埋点的代码。影响代码的阅读体验,且散落的埋点代码不方便管理。
以页面 pv 为例,我们此前是在每一个页面中上报 pv:
// src/manual/home/index.tsx import tracking from "./tracking"; // pageSn 是前端和产品约定的「页面在埋点系统的唯一标识」,比如这个项目首页的标识符是数字 11664 const pageSn = 11111; export default () => { // useDidShow 是 Taro 专有的 Hook,等同于小程序原生 componentDidShow 生命周期,会在页面展示的时候调用。 useDidShow(() => { // 通过统一封装的 sendPv 方法发送 pv 埋点 sendPv(pageSn); }); return <View>手动埋点页面</View>; };
二、自动埋点自动埋点可分为全自动埋点和半自动埋点。全自动埋点则是不管需不需要,将所有的点都埋了。前端肯定开心了 “以后埋点产品都不要不要找我啦”,可数据同学就哭唧唧了。
比如,腾讯和 Taro 团队共同推出 腾讯有数自动化埋点,接入超级简单。比如配置 proxyPage 为 true 即可 “上报所有页面的 browse 、leave、share 等事件”,配置 autoTrack 为 true 即可 “自动上报所有元素的 tap、change、longpress、confirm 事件”。
可从数据量和有效性来说,「全埋」等于「不埋」,因为「全埋」一方面对数据存储量要求很高,另一方面会给我们负责数据清洗的同学带来大量工作。
所以接下来,还是从中寻求平衡,着重看半自动埋点。
页面曝光(pv),理想的上报方式是:
在一个统一的地方(如 trackingConf.ts),配置好每个要埋点的页面的标识符(即 pageSn)
页面显示后,自动判断下是否需要上报(是否在 trackingConf.ts 配置文件中),要就直接上报。
具体实现
(1)统一配置埋点字段,pageSn 表示页面在埋点系统中的标识符
// trackingConf.ts export default { "auto/home/index": { pageSn: 11111, }, };
当然,如果你的业务允许三七二十一,上报所有页面 pv(带上 path 让产品自己筛选),那(1)这步可以省了,直接看(2),这种方式可称为「pv 全自动埋点」。
(2)封装 usePv hook,在页面展示时,获取当前页面 pageSn、判断是否要埋 pv、要的话发送 pv
// usePv.ts // 获取当前页面 path,借助 Taro 的 getCurrentInstance export const getPath = () => { const path = Taro.getCurrentInstance().router?.path || ""; // 去掉开头的 /,比如将 '/auto/home/index' 改为 'auto/home/index' return path.match(/^\/*/) ? path.replace(/^\/*/, "") : path; }; // 获取当前页面 pageSn、判断是否要埋 pv、要的话发送 pv // 入参 getExtra 支持携带额外参数 const usePv = ({ getExtra, }: { getExtra?: () => any; } = {}) => { // 页面曝光 useDidShow(() => { const currentPath = getPath(); // 从 trackingConf 中获取 pageSn const pageSn = trackingConf[currentPath]?.pageSn; console.log("自动获取 pageSn", currentPath, pageSn); if (pageSn) { const extra = getExtra?.(); // 通过统一封装的 sendPv 方法发送 pv 埋点 extra ? sendPv(pageSn, extra) : sendPv(pageSn); } }); };
(3)然后封装页面组件 WrapPage ,使用上述的 usePv():
import React from "react"; import { View } from "@tarojs/components"; import usePv from "./usePv"; function WrapPage(Comp) { return function MyPage(props) { usePv(); return ( <View> <Comp {...props} /> </View> ); }; } export default WrapPage;
(4)最后在所有页面组件,包一层 WrapPage 即可实现「所有页面按需埋点」:
// src/auto/home/index.tsx const Index = WrapPage(() => { return <View>自动埋点页面</View>; });
后续新开发一个页面,除了用 WrapPage 包裹外,只需要在第(1)步的 trackingConf.ts 中增加该页面的 pageSn 即可。
提问环节
好奇宝宝们可能要问了:
(1)WrapPage 里这样封装了 usePv(),应该如何支持上报自定义字段呢?
举个例子,产品希望 src/auto/home/index.tsx 这个页面上报 pv 的时候,额外上报一下 当前页面 URL 查询参数即 params。
很简单,就是这个页面不要用 WrapPage 包裹,而是拿到 params 后直接调用 usePv 函数: