Burying points, or monitoring user behavior at the application presentation layer, is critical for product iterations. Buried data analysis is the source of product requirements and the proof that the function is up to expectation. The front end is closer to the user than the service end, this small white will be here on the front end of the buried point statistical scheme.

Buried point data can be collected for the following analysis (taking Baidu statistics as an example) :

Transform user attributes and user behaviors into various visual charts:

Different products pay different attention to data, which can be collected on demand. For example, information flow products pay more attention to the duration of stay (statistics page visit & jump time), mall pay more attention to “re-purchase rate” (statistics new and old users), and advertising is more in pursuit of maximum.

Buried point statistics usually fall into two categories:

  • Page View Statistics

  • Function click statistics


Page View Statistics

Page view statistics generally fall into two categories:

  • PV: indicates the number of page accesses

  • UV: number of page visitors

Page views are not determined by content appeal alone, but by entry appearance, location, depth, and so on (regardless of need). The appearance of the entrance belongs to the category of UI design. The position of the entrance can be adjusted by analyzing the user’s click on the thermal map, and the depth of the entrance can be adjusted by analyzing the user’s access path.

The thermal map of user click is as follows:

Put the core page entry in the red zone of the thermal map?

The collection page is loaded from and to to obtain the user access path:

According to the analysis, we can know the user’s universal access depth, each depth & the loss rate of each page, etc., and adjust the core page entry source and entry depth according to the results.

Page views, too, are not solely determined by product design. If THE PAGE view of PV is stable, it is necessary to consider the success rate of its load (perhaps a technical bug).


How to realize global PV statistics in front end, taking Vue application as an example.

Plan a

Define router. beforeEach globally in the entry file index.js:

import App from './app'
import Router from './router'

Router.beforeEach((to, from, next) = > {
    App.logEvent({
        type: 'visit'.name: to.name,
        time: new Date().valueOf(),
        params: {
            from: {
                name: from.name,
                path: from.path,
                query: from.query
            },
            to: {
                name: to.name,
                path: to.path,
                query: to.query
            }
        }
    })
    next()
})
Copy the code

The stay duration can be obtained from (skip page time – current page time), but how to calculate the stay duration when closing the application? Disable onbeforeUnload + onunload?

Where app. logEvent is method in the custom Vue plug-in App, which is used to initiate buried point reporting request to the server:

import Request from './utils/request'

const App = {
    // ...
    logEvent (opts) {
        Request({
            url: '/log/event'.method: 'POST'.data: {
                type: opts.type,
                name: opts.name,
                time: opts.time,
                params: opts.params || {}
            }
        })
    }
}
App.install = (Vue, options) = > {
    Vue.prototype.$app = {
        // ...
        logEvent: App.logEvent
    }
}

export default App
Copy the code

Scheme 2

Blend in beforeRouteEnter, beforeRouteLeave objects by registering globally in the entry file index.js:

import Vue from 'vue'

Vue.mixin({
    beforeRouteEnter (to, from, next) {
        next(vm= > {
            vm.$app.logEvent({
                type: 'visit'.name: to.name,
                time: new Date().valueOf(),
                params: {
                    from: {
                        name: from.name,
                        path: from.path,
                        query: from.query
                    },
                    to: {
                        name: to.name,
                        path: to.path,
                        query: to.query
                    }
                }
            })
        })
    },
    beforeRouteLeave (to, from, next) {
        this.$app.logEvent({
            type: 'visit'.name: to.name,
            time: new Date().valueOf(),
            params: {
                from: {
                    name: from.name,
                    path: from.path,
                    query: from.query
                },
                to: {
                    name: to.name,
                    path: to.path,
                    query: to.query
                }
            }
        })
        next()
    }
})
Copy the code

Is beforeRouteLeave triggered when closing the application?

The above scheme has obvious defects:

  • Official said with caution global mixed object!!

  • Merge page hook functions beforeRouteEnter and beforeRouteLeave How do next?

  • BeforeRouteEnter, beforeRouteLeave, PV invisible double…

Discover created, destroyed and this.$route on created objects.

Bewildering output, print times consistent with the length of the routing table

This.$app.logEvent (vm.$app.logEvent) = app.logEvent


How to select a global PV statistical scheme?

  • SPA application: only single entry, globally define Router in entry file. BeforeEach convenient and feasible.

  • MPA application: multiple entries, defining Router in each entry file. BeforeEach? Encapsulates common logic (masquerading as a single entry), eliminating the cost of constructing repeated entries.

  • SPA + MPA hybrid applications: EMMMmmm… Statistical scheme of MPA application is adopted.

  • SSR application: Server rendering (SSR) for better SEO. In the case of Jinja (Python template), the call to TemplateView is to render the page (unlike the front and back separated items, the server cannot know the relationship between the interface call and page rendering). The number of calls and TemplateName indicates that the page IS PV.

As for UV, PV data collection userId can be repeated. If no user management system is applied, COLLECTING IP and deviceId can also roughly know UV (inaccurate).


Function click statistics

Different functions have different clicks, and different areas of the same function have different clicks:

The number of button clicks, affecting factors include the appearance of the button, position, entrance, etc. (not considering the rigid need here). The appearance of the button belongs to the category of UI design. The position of the button can be adjusted by analyzing the user click thermal map, and the entrance of the button can be adjusted by analyzing the trigger source distribution.

Take an example:

Operation students will cut a picture into N regions, click on each region to recommend different products. Click the coordinates of the statistical area, and adjust the commodity ranking according to the thermal map in order to maximize the benefits.


How does the front end realize function click count?

I classify function clicks into two categories:

  • Request with business interface

  • No service interface request

Plan a

The embedded point report is mixed with the business interface request. If there is no interface request, the customized report is adopted:

Param keys indicates the key list of service request parameters to be reported (not all parameters must be reported along with buried points).

The above scheme greatly saves the number of requests, but has obvious drawbacks:

  • If buried point reporting is mixed with service interfaces, statistical data is lost and main functions are affected.

  • Statistics and business are highly coupled and try not to mix them in the same service.

Scheme 2

All click events are regarded as the same category and go through the unified reporting interface:

logEvent (opts) {
    Request({
        url: '/log/event'.method: 'POST'.data: {
            type: opts.type,
            name: opts.name,
            time: opts.time,
            params: opts.params || {}
        }
    })
}
Copy the code

The above schemes also have obvious drawbacks:

  • Double the number of requests: But when the statistics and business services are split, the requests are not handled by the same set of servers.

  • All click event functions to be reported need to call logEvent: encapsulate a component with buried point reporting. Take Vue as an example.

<template>
    <div class="vc-trace" @click="triggerClick">
        <slot></slot>
    </div>
</template>

<script>
import Request from './utils/request'

export default {
    name: 'Trace'.props: {
        type: {
            type: String.default: ' '
        },
        name: {
            type: String.default: ' '
        },
        from: {
            type: String.default: ' '
        },
        params: {
            type: Object.default: (a)= >({})}},methods: {
        triggerClick () {
            Request({
                url: 'XXX/log/event'.method: 'POST'.data: {
                    type: this.type,
                    name: this.name,
                    from: this.from,
                    time: new Date().valueOf(),
                    params: this.params
                }
            })
        }
    }
}
</script>
Copy the code

The scheme has no advantages and disadvantages, but it is more important to be suitable. Product design, product usage, service utilization rate and so on should be considered comprehensively. For low-usage applications, statistics and services can be mixed into the same service to save costs. For high-usage applications, local caching and batch reporting can be adopted to reduce service pressure. However, does batch reporting increase statistical errors?

This article is just the tip of the iceberg, welcome to comment on your valuable experience ~

2018/12/19 further more

Saw a few good articles:

Discussion on the problem of statistical data loss when the page jumps

Lifecycle API tutorial


Author: Silly love kitten

My garden: sunmengyuan. Making. IO/garden /

My Github: github.com/sunmengyuan

The original link: sunmengyuan. Making. IO/garden / 2018…