Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

对单页应用埋点的坑

  现在的 Web 发展越来越倾向于单页应用,很多原本在传统 Web 中可用方案到现代 Web 上就未必可用,埋点统计就是一个典型的例子。最近在纠结 PV 记录的问题,可是对于单页应用而言,什么才算是 PV 呢?地址栏变得不可靠的话是不是应该重新定义一下 PV 的概念了?

各种方式与各种坑

  在 IE8 上实现单页应用的话地址栏中通常都用「#」来确保页面不跳转。以传统 Web 的视角来看这个问题的话,整站就是一个锚点很多的页面而已。现代浏览器中已经可以用 History API 来替代「#」了,但实际上概念还是没有改变,只是让地址栏变得更漂亮了而已。所谓单页应用,说白了就是「以锚点的形式来切换页面功能」,或者也可以说得高大上点叫「前端路由系统」。
  这些锚点的分布粒度是没有标准的,有些开发者可能不喜欢用锚点,就直接使用程序做内容切换;有些开发者可能对锚点情有独钟,可能就会做出鼠标点任意按钮都会改变地址栏的程序。无论是何种极端,它们都已经脱离的 PV 的概念,而且这些极端是很难避免的,无法量化出一套标准来让开发者作为修改地址栏的依据。所以我认为,地址栏在单页应用中是不可靠的。
  除了地址栏,还有模板渲染也可能被认为是 PV 的依据。但模板未必是页面,modal、popover 这些小控件都可能有自己的模板,它们的模板概念只是一个 HTML 片段,同样不能作为 PV 的依据。不过模板还是比较容易区分页面和片段的,如果真把它作为 PV 的依据,应该是比地址栏可靠的。
  PV 的本意就是想知道用户浏览了多少数据。以数据加载来作为 PV 的依据应该是比模板更靠谱的。但数据加载也有坑,因为数据同地址栏一样无法量化细分的粒度,而且比地址栏更坑的是各种数据同步和缓存。其实数据是足以作为 PV 依据的,只是计算起来比较复杂而已。

前面都是扯蛋,现在进入正题

  在单页应用中,大部分数据都是异步加载的。甚至可能是从不同的服务器加载的。如果在地址栏改变时就立即记录为 PV,就会导致很多异步加载没有完成而无法在记录中带上相应的数据。如果在由地址栏改变而产生的所有异步请求完成之后再记录 PV 的话,又可能会漏掉很多记录。最可靠的做法就是对每个异步请求分别做记录,于是又产生了另外的问题:如何在记录时将这些异步的数据请求和地址栏关联起来?
  假如用户先浏览了 A 地址,点击按钮后切换到了 B 地址,然后又从 B 地址链回了 A 地址。这个行为即使在传统 Web 中也很难说它是几次 PV。其实纠结它是否是 PV 应该是数据分析相关部门的问题,我们要做的只是在这种行为发生时准确地记录下来,不要把第一次浏览的 A 和从 B 链回的 A 搞混即可。
  如果只是简单地在每次异步数据加载完成时记录,那会产生一堆奇怪的东西,因为网络请求的时间是不可估算的。比如第一个 A 地址的请求可能在用户浏览完 B 地址跳转回 A 地址后才完成。或者用户可能同时打开两个浏览器选项卡同时浏览某个页面。这些奇怪的情况会导致统计出现奇怪的结果,所以需要一个方案来解决这个问题。
  我的解决方案是引入一个 PV Hash 的概念,一旦地址栏发生变化就更新 PV Hash 的值。每个异步请求发起时都记录当前的 PV Hash,然后在完成请求需要记录时带上这个值。这样就可以准确描述每一个数据请求来自哪个 PV Hash。至于值,可以是一个随机数或随机字符串,只要确保唯一性即可。统计时只需要将 PV Hash 相同的记录归类就可以看到每个地址每次浏览时加载了哪些数据。
  其实这也只是我一拍脑子想出的方案,看起来也许比较低端。网络上目前对单页 Web 应用统计相关的资料比较缺乏,希望大家能多多分享自己的做法。

网名:
3.80.32.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^