我的编程空间,编程开发者的网络收藏夹
学习永远不晚

如何在微信小程序中实现一个手动埋点和自动埋点功能

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

如何在微信小程序中实现一个手动埋点和自动埋点功能

如何在微信小程序中实现一个手动埋点和自动埋点功能?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

一、手动埋点

手动埋点就是在每一处需要的地方,都加一段上报埋点的代码。影响代码的阅读体验,且散落的埋点代码不方便管理。
以页面 pv 为例,我们此前是在每一个页面中上报 pv:

// class="lazy" data-src/manual/home/index.tsximport tracking from "./tracking";// pageSn 是前端和产品约定的「页面在埋点系统的唯一标识」,比如这个项目首页的标识符是数字 11664const 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 事件”。

可从数据量和有效性来说,「全埋」等于「不埋」,因为「全埋」一方面对数据存储量要求很高,另一方面会给我们负责数据清洗的同学带来大量工作。

所以接下来,还是从中寻求平衡,着重看半自动埋点。

1、页面曝光(pv)

页面曝光(pv),理想的上报方式是:

在一个统一的地方(如 trackingConf.ts),配置好每个要埋点的页面的标识符(即 pageSn)
页面显示后,自动判断下是否需要上报(是否在 trackingConf.ts 配置文件中),要就直接上报。

具体实现

(1)统一配置埋点字段,pageSn 表示页面在埋点系统中的标识符

// trackingConf.tsexport default { "auto/home/index": { pageSn: 11111, },};

当然,如果你的业务允许三七二十一,上报所有页面 pv(带上 path 让产品自己筛选),那(1)这步可以省了,直接看(2),这种方式可称为「pv 全自动埋点」。

(2)封装 usePv hook,在页面展示时,获取当前页面 pageSn、判断是否要埋 pv、要的话发送 pv

// usePv.ts// 获取当前页面 path,借助 Taro 的 getCurrentInstanceexport const getPath = () => { const path = Taro.getCurrentInstance().router?.path || ""; // 去掉开头的 /,比如将 '/auto/home/index' 改为 'auto/home/index' return path.match(/^\, "") : 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 即可实现「所有页面按需埋点」:

// class="lazy" data-src/auto/home/index.tsxconst Index = WrapPage(() => { return <View>自动埋点页面</View>;});

后续新开发一个页面,除了用 WrapPage 包裹外,只需要在第(1)步的 trackingConf.ts 中增加该页面的 pageSn 即可。

提问环节

好奇宝宝们可能要问了:

(1)WrapPage 里这样封装了 usePv(),应该如何支持上报自定义字段呢?
举个例子,产品希望 class="lazy" data-src/auto/home/index.tsx 这个页面上报 pv 的时候,额外上报一下 当前页面 URL 查询参数即 params。
很简单,就是这个页面不要用 WrapPage 包裹,而是拿到 params 后直接调用 usePv 函数:

// class="lazy" data-src/auto/home/index.tsxconst Index = () => { usePv({ getExtra: () => {  const params = Taro.getCurrentInstance().router?.params;  return { params }; }, }); return <View>自动埋点页面</View>;});

(2)这里每个页面组件,都要用 WrapPage 包裹一下,对业务还是有侵入型了,原生小程序可以改写 Page,在 Page 中直接 usePv()。Taro 项目应该也可以这么做,实现 0 业务侵入吧?

Taro 项目中,确实可以也可以和原生小程序一样,在 App 中统一拦截原生 Page,但这样的话,上面「某些页面要计算额外参数并上报」就不好解决了。

2、页面分享

微信小程序中,存在两种分享:

  • 分享给好友:useShareAppMessage。

  • 分享到朋友圈:useShareTimeline。小程序基础库 v2.11.3 开始支持,目前只在 Android 平台可用。

具体实现

以 useShareAppMessage 为例(useShareTimeline 同理):
(1)仍在 trackingConf.ts 统一配置文件中,增加分享埋点的标识字段 eleSn (及额外参数)

// trackingConf.tsexport default { "auto/home/index": { pageSn: 11111, shareMessage: { eleSn: 2222, destination: 0 }, // 增加 shareMessage 包含分享好友的 eleSn、业务额外参数 destination }};

(2)封装 useShareAppMessage 方法,业务调用 Taro.useShareAppMessage 的地方全局替换为这个 useShareAppMessage。

// 分享给好友,统一埋点export const useShareAppMessage = ( callback: (payload: ShareAppMessageObject) => ShareAppMessageReturn) => { let newCallback = (payload: ShareAppMessageObject) => { const result = callback(payload) const currentPath = getPath(); // getPath 获取当前页面路径,可参考「1、页面曝光(pv)」中的 getPath // 从 trackingConf 中获取 pageSn、shareMessage 等 const { pageSn, shareMessage } = trackingConf[currentPath] const { eleSn, ...extra } = shareMessage || {} let page_el_sn = eleSn const { imageUrl: image_url, path: share_url } = result const { from: from_ele } = payload const reportInfo = {  from_ele,  share_to: 'friend', // 'friend' 表示分享给好友  image_url,  share_url,  ...extra } console.log('...useShareAppMessage tracking', { pageSn, page_el_sn, reportInfo }) sendImpr(pageSn, page_el_sn, reportInfo) // 可自行封装 sendImpr 方法,发送分享埋点信息 return result } Taro.useShareAppMessage(newCallback)}

这样,如果有个页面需增加分享好友的埋点,直接在 trackingConf.ts 中增加 shareMessage 的 eleSn 即可,useShareTimeline 同理。

提问环节

好奇宝宝们可能要问了:页面需要增加分享好友/朋友圈的埋点,可否 0 配置(即不用修改上述的  trackingConf.ts 文件)?
与前文中「pv 全自动埋点」类似,只要和产品约定好捞数据的方式也可以,比如笔者和产品约定了:
每个页面分享好友/朋友圈,eleSn 都是 444444,然后产品通过 pageSn 判断是哪个页面,通过 share_to 判断是分享好友 / 朋友圈,对于分享好友的场景,再通过 from_ele 判断通过右上角分享还是点击页面中的按钮分享。
这样页面分享也可以全自动埋点了。

3、元素埋点

元素自动埋点的调研遇到阻力,尚未落地。下文主要谈不同思路遇到的问题,有好的建议欢迎评论区沟通。

我们元素埋点,较高频的有曝光、点击事件,中低频的有滚动、悬停等事件。

手动埋点的方式就是在元素指定事件触发的时候,手动执行 sendImpr 上报埋点(带上页面唯一标识符 pageSn、 元素唯一标识符 eleSn)。

那这个环节是否可以省事一些呢?对业务无侵入,大概的做法还是:

在 Component 指定事件触发增加个 hook -> 判断是否要上报埋点 -> 满足条件则上报

问题一分为二:

(1)拦截元素事件回调

可以拦截并遍历小程序 Component 接收到的 options.methods,如果是一个自定义函数,则在函数被调用的时候判断第一个参数(假设命名为 e)的 type 是否等于 tap 等事件。这时候可以根据 e 等信息决定是否满足埋点上报条件了。
原生小程序中的实现,大致如下:

// App.jsApp({ onLaunch() { let old = Component Component = function(config) {  // 拦截业务传入的 config  const newConf = proxyConfig(config)  old(newConf) } }})const proxyConfig = function(conf) { const methods = conf.methods // 获取自定义方法(按需排除一些不埋点的方法) let diyMethods = Object.entries(methods).filter(function (method) { let methodName = method[0] return ![  "onLoad",  "onShow",  "onReady",  "onHide",  "onUnload",  "onPullDownRefresh",  "onReachBottom",  "onPageScroll",  "onShareAppMessage",  "onResize",  "onTabItemTap",  "observer", ].includes(methodName); }) diyMethods.forEach(function(method) { const [methodName, methodFn] = method // 修改 conf 中的 methods methods[methodName] = function (...args) {  const e = args && args[0]  if (e && e.type === 'tap') {  console.log('...tapping', methodName, args) // 触发点击事件的时候,按需上报埋点  }  methodFn.call(this,...args) } }); // 返回修改后的 conf return conf}

Taro 项目中,不能直接在组件代码里用 Component,但可以迂回一些的方式实现相同目的,比如:

// myProxy.jsmodule.exports = (function() { let OriginPage = Page let OriginComponent = Component return (Page = function(conf) { conf.forEach(function(e) {  let [methodName, methodFn] = e  if (typeof methodFn === 'function') {  conf[methodName] = function(...args) {   // 做你想做的事,如改写 conf 等   methodFn.call(this, ...args)  }  } }) return OriginPage(conf) })( (Component = function(conf) {  const methods = conf.methods  methods.forEach(function(e) {  // 做你想做的事,如改写 conf 等  })  OriginComponent(conf) }) )})()

然后在 app.tsx 中直接引入 myProxy.js 即可

(2)如何自动生成元素唯一标识符

目前是通过埋点系统中申请下来的 eleSn 来唯一标识元素的,如果想要自动标识,可细分为:

  • XPath:在 pc / mobile 中还可以,但在小程序中不支持直接获取节点的 XPath / 根据 XPath 获取节点。微信小程序可否支持通过 XPath 获取 DOM 元素?

  • 自动获取 组件方法名:原生小程序中,因为直接拦截了 Component options 中的 methods,所以在事件触发时可以获取到原始的方法名,但 Taro 项目中不行,因为 methods 被代理了一道,事件触发后,你看到的方法名都是 eh。

  • AST 解析源码分析出页面名、方法名和方法对应的注释来标识元素:Taro 项目中目测只能用这个方法,但成本较大,且「在代码不断迭代后,存量数据是否还能用」也是个问题,所以笔者未做尝试。

关于如何在微信小程序中实现一个手动埋点和自动埋点功能问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注编程网行业资讯频道了解更多相关知识。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

如何在微信小程序中实现一个手动埋点和自动埋点功能

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

如何在微信小程序中实现一个手动埋点和自动埋点功能

如何在微信小程序中实现一个手动埋点和自动埋点功能?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。一、手动埋点手动埋点就是在每一处需要的地方,都加一段上报埋点的代码。影响代码的
2023-06-06

支付宝小程序从手动埋点到自动埋点如何实现

本篇内容主要讲解“支付宝小程序从手动埋点到自动埋点如何实现”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“支付宝小程序从手动埋点到自动埋点如何实现”吧!手动埋点现在小程序埋点需要手动添加埋点事件触
2023-06-29

怎么在微信小程序中实现一个文字滚动功能

怎么在微信小程序中实现一个文字滚动功能?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。具体内容如下wxml:显示完后再显示:
2023-06-14

怎么在微信小程序中实现一个水平垂直滚动功能

怎么在微信小程序中实现一个水平垂直滚动功能?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。具体内容如下要点swiper内部套scroll-view注意:1.scroll竖直滚
2023-06-14

PHP开发微信小程序:如何实现自动回复功能?

PHP开发微信小程序:如何实现自动回复功能?微信小程序是一种轻量级的应用程序,非常适用于移动设备。在开发微信小程序时,自动回复功能是一个非常重要的功能,可以提供更好的用户体验。本文将介绍如何使用PHP语言开发微信小程序的自动回复功能,并提供
2023-10-27

微信小程序中如何实现一个计算器功能

这期内容当中小编将会给大家带来有关微信小程序中如何实现一个计算器功能,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。index.wxml
2023-06-20

如何使用PHP实现微信小程序的自动签到功能?

如何使用PHP实现微信小程序的自动签到功能?随着微信小程序的快速发展,越来越多的企业和个人开始使用微信小程序来为用户提供便捷的服务。其中,自动签到功能在很多场景中都非常常见,比如学校、企业、健身房等。本文将介绍如何使用PHP来实现微信小程序
2023-10-26

微信小程序实战中位置闹铃如何实现监控点状态迁移功能

这篇文章给大家介绍微信小程序实战中位置闹铃如何实现监控点状态迁移功能,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。接近监控点enterAlarmCheck: function (distance, accuracy){
2023-06-19

Android开发中如何实现一个应用程序开机自启动功能

今天就跟大家聊聊有关Android开发中如何实现一个应用程序开机自启动功能,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。Android在开机时自动启动一个应用程序在启动时自动启动一个
2023-05-31

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录