Every company that wants to grow its users needs to collect and analyze data about their actions, so burying them is essential. For the front-end career development, the traditional manual burying point, is undoubtedly tedious and boring things, can simplify to simplify.
One, manual burying point
Manual burying is to add a code to report the burying point at each place where it is needed. It affects the reading experience of the code, and the scattered buried code is not convenient to manage.
Take page PV as an example, we reported PV in each page previously:
// src/manual/home/index.tsx
import tracking from "./tracking";
// pageSn is the unique identifier of the page in the buried point system agreed by the front end and the product. For example, the identifier of the front page of this project is the number 11664
const pageSn = 11111;
export default() = > {// useDidShow is an Taro proprietary Hook, equivalent to the native componentDidShow lifecycle, which is called when the page is displayed.
useDidShow(() = > {
// sendPv buried points through unified encapsulation sendPv method
sendPv(pageSn);
});
return <View>Manual burying page</View>;
};
Copy the code
Two, automatic burying point
Automatic burying point can be divided into automatic burying point and semi-automatic burying point. Fully automatic burying is to bury all points, whether needed or not. The front end must be happy “don’t look for me after burying some products”, but the data students will cry chiri.
For example, Tencent and the Taro team jointly launched Tencent Wowu automation points, which are super easy to access. For example, set proxyPage to true to report browse, Leave, share, and other events on all pages. Set autoTrack to true to automatically report tap, change, Longpress, and Confirm events of all elements.
In terms of data volume and validity, “full burying” is equal to “no burying”, because “full burying” on the one hand has a high requirement for data storage, on the other hand, it will bring a lot of work to our classmates who are responsible for data cleaning.
So next, or to seek balance, focus on semi-automatic buried point.
1. Page exposure (PV)
Page exposure (PV), the ideal reporting method is:
- In a unified place (e.g
trackingConf.ts
), configure the identifier for each page to be buried (i.epageSn
) - After the page is displayed, it automatically determines whether to report (whether to report in
trackingConf.ts
Configuration file), if you want to report directly.
The specific implementation
(1) Uniformly configure the buried field. PageSn represents the identifier of the page in the buried system
// trackingConf.ts
export default {
"auto/home/index": {
pageSn: 11111,}};Copy the code
Of course, if your business allows thirty-seven twenty-one, reported all pages PV (with path to let the product screening), that (1) this step can be saved, directly look at (2), this way can be called “PV automatic buried point”.
(2) Package usePv hook. When the page is displayed, obtain the pageSn of the current page, judge whether to bury PV or not, and send PV if necessary
// usePv.ts
// Get the current page path using Taro's getCurrentInstance
export const getPath = () = > {
constpath = Taro.getCurrentInstance().router? .path ||"";
// Remove the leading /, such as '/auto/home/index' to 'auto/home/index'.
return path.match(/ ^ \ / * /)? path.replace(/ ^ \ / * /."") : path;
};
// Get the pageSn of the current page, determine whether to bury PV, if yes, send PV
GetExtra supports additional arguments
const usePv = ({ getExtra, }: { getExtra? : () = >any;
} = {}) = > {
// Page exposure
useDidShow(() = > {
const currentPath = getPath();
// Get pageSn from trackingConf
constpageSn = trackingConf[currentPath]? .pageSn;console.log("Automatically get pageSn", currentPath, pageSn);
if (pageSn) {
constextra = getExtra? . ();// sendPv buried points through unified encapsulation sendPv methodextra ? sendPv(pageSn, extra) : sendPv(pageSn); }}); };Copy the code
(3) Then wrap the page component WrapPage, using the usePv() above:
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;
Copy the code
(4) Finally, in all page components, package a layer of WrapPage to achieve “all pages on demand burying point” :
// src/auto/home/index.tsx
const Index = WrapPage(() = > {
return <View>Automatic buried page</View>;
});
Copy the code
In addition to wrapping a new page with WrapPage, you only need to add the pageSn of the page in the trackingconf.ts of step (1).
For questions
Curious babies might want to ask:
(1) WrapPage encapsulates usePv(), how should we support reporting custom fields?
For example, the product wants the SRC /auto/home/index. TSX page to report pv, in addition to reporting the current page URL query parameter params.
Instead of wrapping the page with WrapPage, call the usePv function when you get params:
// src/auto/home/index.tsx
const Index = () = > {
usePv({
getExtra: () = > {
constparams = Taro.getCurrentInstance().router? .params;return{ params }; }});return <View>Automatic buried page</View>;
});
Copy the code
(2) here each Page component, have to use WrapPage package, or have an invasion of the business, native small program can rewrite Page, in the Page directly usePv(). The Taro project should be able to do the same, to achieve zero business intrusion, right?
In the Taro project, it is possible and possible to uniformly intercept native pages in the App like native applet, but in this case, “some pages need to calculate additional parameters and report” is not easy to solve.
2. Page sharing
There are two kinds of sharing in wechat mini programs:
- Share with friends:
useShareAppMessage
. - Share on moments:
useShareTimeline
. Applet base library v2.11.3 start support, currently only available on the Android platform.
The specific implementation
Take useShareAppMessage as an example (the same is true for useShareTimeline) :
(1) Add the identification field eleSn (and additional parameters) of sharing buried point in trackingconf. ts unified configuration file.
// trackingConf.ts
export default {
"auto/home/index": {
pageSn: 11111.shareMessage: { eleSn: 2222.destination: 0 }, // Add shareMessage containing the eleSn of the shared friend and the extra business parameter destination}};Copy the code
(2) Encapsulate the useShareAppMessage method, and globally replace the place where businesses call Taro. UseShareAppMessage with the useShareAppMessage.
// Share it with your friends
export const useShareAppMessage = (
callback: (payload: ShareAppMessageObject) => ShareAppMessageReturn
) = > {
let newCallback = (payload: ShareAppMessageObject) = > {
const result = callback(payload)
const currentPath = getPath(); // getPath To obtain the current page path, see getPath in 1. Page Exposure (PV)
// Get pageSn, shareMessage, etc from trackingConf
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' means to share with friendsimage_url, share_url, ... extra }console.log('... useShareAppMessage tracking', { pageSn, page_el_sn, reportInfo })
sendImpr(pageSn, page_el_sn, reportInfo) // Can encapsulate sendImpr method, send share buried point information
return result
}
Taro.useShareAppMessage(newCallback)
}
Copy the code
In this way, if a page needs to add a buried point for sharing friends, add the eleSn of shareMessage in Trackingconf. ts and useShareTimeline.
For questions
Curious kids may want to ask: if the page needs to be added to share friends/circle of friends, can 0 be configured (i.e. the above trackingconf.ts file is not modified)?
Similar to the previous article “PV automatic burying point”, as long as the product and the agreement on the way to retrieve data can also be, such as the author and the product agreement:
Each page shares friends/circle of friends, eleSn is 444444, and the product determines which page it is by pageSn, and determines which page it is to share friends/circle of friends by share_to. For the scene of sharing friends, Then use from_ele to determine whether to share through the upper right corner or click the button in the page.
This page sharing can also be fully automatic buried point.
3. Element burial point
The investigation of the automatic burying point of elements has encountered resistance and has not yet landed. The following is mainly about the problems encountered in different ideas, and good suggestions are welcome to communicate in the comment section.
Our element burying point, high frequency has exposure, click events, low frequency has rolling, hovering and other events.
The method of manual burying point is to manually execute sendImpr to report burying point (with page unique identifier pageSn and element unique identifier eleSn) when the element specified event is triggered.
Can this link save some trouble? No intrusion on the business, the general approach is:
Add a hook to Component to trigger the event -> determine whether to report the buried point -> report the event if the condition is met
The problem is divided into two parts:
(1) Intercepting element event callbacks
You can intercept and iterate over options.methods received by the Component applet and, if it’s a custom function, determine when the function is called whether the type of the first argument (let’s say named e) is equal to tap, etc. At this time, we can decide whether to meet the conditions of burying point reporting according to e and other information.
Native applet implementation, roughly as follows:
// App.js
App({
onLaunch() {
let old = Component
Component = function(config) {
// Intercepts the config passed by the service
const newConf = proxyConfig(config)
old(newConf)
}
}
})
const proxyConfig = function(conf) {
const methods = conf.methods
// Get custom methods (exclude some unburied methods as needed)
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
// Modify methods in conf
methods[methodName] = function (. args) {
const e = args && args[0]
if (e && e.type === 'tap') {
console.log('... tapping', methodName, args) // When the click event is triggered, the buried point is reported as required
}
methodFn.call(this. args) } });// Returns the modified conf
return conf
}
Copy the code
In the Taro project, you can’t use Component directly in Component code, but you can do the same thing in a roundabout way. For example:
// myProxy.js
module.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) {
// Do what you want to do, such as rewriting the conf, etc
methodFn.call(this. args) } } })return OriginPage(conf)
})(
(Component = function(conf) {
const methods = conf.methods
methods.forEach(function(e) {
// Do what you want to do, such as rewriting the conf, etc
})
OriginComponent(conf)
})
)
})()
Copy the code
Add myproxy.js directly to app.tsx
(2) How to automatically generate unique identifiers of elements
At present, elements are uniquely identified by eleSn applied in the buried point system. If automatic identification is required, it can be subdivided into:
XPath
: It works fine in PC/Mobile, but XPath to get nodes directly/get nodes by XPath is not supported in applets.Can wechat applet support DOM element acquisition through XPath?- Automatic access to
Component method name
In the Taro project, methods are propped up and the name of the method is displayed after the event is triggeredeh
. AST
Analyze the source code to identify elements by analyzing the page name, method name and corresponding annotation of the method: The Taro project can only use this method visually, but the cost is high, and “whether the stock data can still be used after the code is constantly iterated” is also a problem, so the author did not try.
Third, summary
This article summarizes the idea of wechat small program (Taro) from manual burying point to automatic burying point. And according to the page buried point (PV, share) and element buried point, analysis of the implementation method:
- Page pv:
- encapsulation
usePv
, read pageSn from the configuration file based on the current page path - Encapsulating page components
WrapPage
callusePv()
- encapsulation
- Share friends or circles of friends: Customize the useShareAppMessage and useShareTimeline. Read the pageSn and share eleSn from the configuration file according to the path of the current page. Then obtain the input parameters and report them
- Element burying: Provides the idea of rewriting Component methods to intercept event callbacks, but is not suitable for automatic burying because element unique identifiers cannot be obtained automatically.