ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

高手如何设计自定义维度?analyticsjs-boilerplate 的 9 维 6 指标体系完整拆解

高手如何设计自定义维度?analyticsjs-boilerplate 的 9 维 6 指标体系完整拆解

【免费下载链接】analyticsjs-boilerplate

Examples and best practices for using analytics.js

项目地址:https://gitcode.com/gh_mirrors/an/analyticsjs-boilerplate
点击查看免费下载

对于用 Google Analytics 做网站统计的工程师来说,"自定义维度(Custom Dimensions)"往往是最容易翻车的一环:维度没填值就丢行、改版后数据对不上、性能指标散落各处难汇总。开源项目 analyticsjs-boilerplate 正是为解决这些问题而生——它提供了一套可直接落地的 analytics.js 埋点最佳实践样板,其中完整设计了9 个自定义维度 + 6 个自定义指标的采集体系,覆盖页面性能、错误追踪、滚动深度等场景。本文将带你逐维拆解这套体系的设计思路。

一、先搞懂:自定义维度 vs 自定义指标是什么?

很多人分不清这两个概念,先花 1 分钟建立正确认知:

概念作用类比
自定义维度(dimension)给每次数据访问(hit)打上"标签",用于分类、筛选给包裹贴快递单(收件人、城市)
自定义指标(metric)记录一个"可求和/求平均"的数值记录包裹的重量、体积

以页面加载为例:"页面从哪个来源进入"是维度(文字标签),"页面加载耗时 3200ms"是指标(数字)。

在样板中,这两套映射表分别定义在 src/analytics/autotrack.js 中:

const dimensions = { TRACKING_VERSION: 'dimension1', CLIENT_ID: 'dimension2', // ... 共 9 个维度 }; const metrics = { RESPONSE_END_TIME: 'metric1', // ... 共 6 个指标 };

💡 注意:Google Analytics 后台要求先创建好维度/指标,代码中的dimension1~dimension9、metric1~metric6必须与后台编号一一对应。

二、9 个自定义维度逐个拆解

完整的 9 维定义见 src/analytics/autotrack.js,基础版 src/analytics/base.js 则是 8 维(少了第 9 维):

编号维度名含义采集时机
dimension1TRACKING_VERSION埋点版本号(如'1')页面加载时
dimension2CLIENT_IDGoogle 自动分配的客户端 ID页面加载时
dimension3WINDOW_ID本次打开窗口的 UUID页面加载时
dimension4HIT_ID每一次 hit 的唯一 UUID每次发送前
dimension5HIT_TIME每次 hit 的时间戳每次发送前
dimension6HIT_TYPEhit 类型(pageview/event 等)每次发送前
dimension7HIT_SOURCEhit 来源(pageload / 插件名)发送时按场景
dimension8VISIBILITY_STATE发送时页面可见性状态每次发送前
dimension9URL_QUERY_PARAMS被剥离的 URL 查询参数autotrack 插件写入

可以看到一个巧妙的设计:9 个维度被分成两类采集时机——

  • 页面级维度(1~3):只在页面加载时设置一次,描述"这次会话是谁、用什么版本";
  • hit 级维度(4~8):每次发送数据前动态注入,描述"这一条数据本身"。

高手技巧 1:用buildHitTask钩子给每条数据"盖章"

hit 级维度是整套体系最精华的部分。在 src/analytics/base.js 中,样板替换了 tracker 的buildHitTask方法——这是 analytics.js 提供的"数据发送前最后拦截点":

ga((tracker) => { const originalBuildHitTask = tracker.get('buildHitTask'); tracker.set('buildHitTask', (model) => { const qt = model.get('queueTime') || 0; model.set(dimensions.HIT_TIME, String(new Date - qt), true); model.set(dimensions.HIT_ID, uuid(), true); model.set(dimensions.HIT_TYPE, model.get('hitType'), true); model.set(dimensions.VISIBILITY_STATE, document.visibilityState, true); originalBuildHitTask(model); }); });

无论后续代码通过哪个插件发出 pageview、event 还是 timing 数据,都会在发送前自动补上这 4 个字段。好处是:

  1. 每条 hit 有唯一HIT_ID——排查重复数据、去重统计时是硬通货;
  2. HIT_TIME扣除了queueTime——数据在队列里排队的时间不算入时间戳,报表更准确(这是 0.2.0 版本专门修复的点,见 CHANGELOG.md);
  3. VISIBILITY_STATE能帮你区分"用户切后台后发来的数据",过滤脏数据。

高手技巧 2:版本号维度,改版数据不"串味"

TRACKING_VERSION看起来不起眼,却是报表排障的救命稻草。当埋点逻辑发生破坏性变更时,把版本号'1'改为'2',就能在后台用维度筛选只隔离新逻辑采集的数据,新旧数据互不污染。这个思路在 src/analytics/base.js 的注释中写得明明白白。

三、6 个自定义指标:把性能数据搬进 GA

6 个指标定义在 src/analytics/autotrack.js:

编号指标名含义
metric1RESPONSE_END_TIME服务器响应结束耗时
metric2DOM_LOAD_TIMEDOM 加载完成耗时
metric3WINDOW_LOAD_TIME窗口 load 完成耗时
metric4PAGE_VISIBLE页面是否可见(0/1)
metric5MAX_SCROLL_PERCENTAGE用户最大滚动深度(%)
metric6PAGE_LOADS页面加载次数

前 3 个:Navigation Timing 性能三件套

sendNavigationTimingMetrics 函数从performance.timing取出三个时间戳,统一换算成"相对 navigationStart 的毫秒数"后,通过一条 event 命中一次性上报:

const responseEnd = Math.round(nt.responseEnd - navStart); const domLoaded = Math.round(nt.domContentLoadedEventStart - navStart); const windowLoaded = Math.round(nt.loadEventStart - navStart);

这里有两个细节值得抄作业:

  • 等 load 事件触发后再上报:如果页面还没加载完,就先挂监听,避免拿到 0 值;
  • 数据合法性校验:allValuesAreValid会拦截浏览器偶发的 0、负数或"未来时间"等异常值(要求0 < value < 6e6),防止脏数据拉偏均值。

后 3 个:交给 autotrack 插件自动填充

PAGE_VISIBLE、MAX_SCROLL_PERCENTAGE、PAGE_LOADS分别由pageVisibilityTracker和maxScrollTracker插件写入。插件初始化见 requireAutotrackPlugins,其中有个实用小函数getDefinitionIndex(autotrack.js#L258):

const getDefinitionIndex = (definition) => +/\d+$/.exec(definition)[0];

它把'metric5'转成数字5,让插件配置和维度映射表共用同一份定义,避免编号写两遍、改一处漏一处。

四、一个关键防坑设计:(not set)兜底值

Google Analytics 有个"坑":维度值为空的行会被直接从报表中丢弃。如果某次事件没带HIT_SOURCE,整行数据可能"人间蒸发"。

样板的解法非常朴素——在 trackCustomDimensions 中,先把所有维度统一预置为'(not set)':

Object.keys(dimensions).forEach((key) => { ga('set', dimensions[key], NULL_VALUE); });

之后真正有值的字段再按需覆盖。这样每条数据都"有话说",报表行数才可信——新手最容易忽略、但影响最大的一条实践。

五、三个版本样板,难度阶梯式递进

项目提供了三份逐步增强的样板,入口切换只需改 src/index.js 中的一行import路径:

版本文件特性维度/指标规模
基础版src/analytics/base.js错误追踪 + 维度体系 + 性能事件8 维 / 3 指标
自动追踪版src/analytics/autotrack.js增加 5 个 autotrack 插件9 维 / 6 指标
多追踪器版src/analytics/multiple-trackers.jsprod/test 双追踪器隔离9 维 / 6 指标

多追踪器版:测试数据不污染生产报表

multiple-trackers.js 定义了prod和test两组 tracker,并用createGaProxy工厂生成了gaAll/gaProd/gaTest三个代理函数(L87-L108):

  • gaAll(...)→ 两个 tracker 都发,用于基础行为数据;
  • gaTest(...)→ 只发测试 tracker,用于先在测试属性里验证新数据是否合理(比如滚动深度插件就只挂在 test 上);
  • gaProd(...)→ 只发生产 tracker,Navigation Timing 数据就只用它上报。

这套"先试后发"的工作流,让埋点上线像代码发布一样有了灰度验证环节。

六、跑起来看看:本地体验完整样板

  1. 克隆仓库并安装依赖:

    git clone https://gitcode.com/gh_mirrors/an/analyticsjs-boilerplate cd analyticsjs-boilerplate npm install npm start
  2. 浏览器打开 localhost:8080,按 F12 打开开发者控制台;

  3. 由于 index.html 加载的是analytics_debug.js调试版,每条 hit 的完整参数(包括所有 dimension/metric)都会打印在控制台——不用后台就能看到 9 维 6 指标全部就位。

⚠️ 上线前记得把analytics_debug.js换回analytics.js,这一点 index.html 的注释里特意标红提醒了。

七、给你的 5 条落地清单

学完这套体系,可以直接搬走的经验:

  1. ✅维度/指标集中映射:用一张dimensions/metrics表管住全部编号,别让dimension7散落在各文件里;
  2. ✅buildHitTask钩子加 hit 级字段:一次钩住所有 hit,零遗漏;
  3. ✅空值兜底(not set):防止 GA 静默丢行;
  4. ✅埋点版本号维度:改版时用筛选器隔离新旧数据;
  5. ✅性能数据先校验再上报:拒绝 0、负数、未来时间等异常值。

这套样板代码量不大,却把"自定义维度怎么设计才经得起长期运营"这件事讲透了——维度负责回答"这条数据是谁、何时、从哪来",指标负责回答"有多快、多深、多少次"。照着 9 维 6 指标的思路搭一套自己的埋点骨架,你的 Google Analytics 报表质量会立刻上一个台阶。

【免费下载链接】analyticsjs-boilerplate

Examples and best practices for using analytics.js

项目地址:https://gitcode.com/gh_mirrors/an/analyticsjs-boilerplate
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进