GTM 随机跳过单页应用中的初始网页浏览

GTM randomly skips initial pageview in single page app

我在 Google 跟踪 SPA 页面浏览量的跟踪代码管理器中有 Pageview 代码,与 this guide 中描述的代码相同。基本上是 Universal Analytics 与链接的 Google Analytics ID 在 History Change 上触发(在某些时候 All Pages 触发也没有成功添加)。

在我当前的应用程序中,GTM 会在所有没有异步解析器的路由的初始网页浏览中跳过 Pageview 标记。通常路由会触发标记 有时 (5 次中的 1 次),这可能会因条件(缓存与未缓存,本地主机与生产)而有所不同。

在具有持续时间较长(> 1 秒)的解析器的路由上,Pageview 标签总是在初始网页浏览时触发(5 次中的 5 次)。

Pageview 标签在应用程序初始化后在所有路由上正常触发 (pushState)。

此行为已通过 GTM 调试控制台和 GA 实时监控得到确认。

设置似乎是推荐的设置,GTM snippet<head>中加载,Angular2个应用程序在<body>末尾加载。

<html>
  <head>
    <script>/* Google Tag Manager snippet */</script>
    ...
  </head>

  <body my-app>
    ...
    <script src="my-app-bundle.js"></script>
  </body>
</html>

并且 Angular 2 像往常一样自举:

platformBrowserDynamic().bootstrapModule(MyAppModule);

我尝试在 my-app-bundle.js 之前和之后到处移动 GTM 片段,甚至用同步替换它:

<script>
  window.dataLayer = ...
</script>
<script src="https://www.googletagmanager.com/gtm.js?id=..."></script>

与默认代码段没有区别。

我通过反复试验发现,如果应用程序启动时有相当长的延迟(200-1000 毫秒),Pageviews 开始在初始页面浏览量上正常工作(起初似乎 DOMContentLoaded 确实如此技巧,但延迟还不够):

setTimeout(() => {
  platformBrowserDynamic().bootstrapModule(MyAppModule);
}, 1000);

我希望用 SPA/Angular 2 个应用程序完成 GTM 的专家熟悉这个问题。 不幸的是,我无法为这种情况提供 MCVE,但我相信它可以与任何 Angular 2 (2.3.1) 应用程序一起复制,其中包含路由和 Google 跟踪代码管理器帐户.

通常 Angular 2 个应用程序可以在 <body> 结束时安全地启动。

这是怎么回事?应该如何在没有竞争条件的情况下使用 GTM 正确处理网页浏览跟踪?


更新:当从 GTM 切换到直接使用 GA 时

router.events.subscribe(e => {
  if (e instanceof NavigationEnd)
    ga('send', 'pageview', location.pathname);
})

初始和后续页面浏览一切正常,没有竞争条件。


更新 2:

这是长运行路由解析器成功的情况下的时间表,gtm.jsmain.bundle.js在开始时加载(这无关紧要)按顺序),analytics.js(当 GA 调试器打开时 analytics_debug.js)在路由解析器完成并触发 Pageview 标记时加载,即在 ~10 秒后:

看起来分析脚本加载了 <script async=true>:

j.async = true;a.async = 1;

尝试删除 async 看看是否有帮助。

正如@kemsky 所建议的,GTM 生命周期与内部 gtm.load 事件相关,该事件发生在 window onload。所以 DOMContentLoaded 可能比 bootstrap 还早。

考虑到 GTM 脚本是在 SPA 脚本之前加载的,

window.addEventListener('load', () => {
  platformBrowserDynamic().bootstrapModule(MyAppModule);
});

回调将在 GTM 准备好接收历史更改事件时触发,并且不应存在竞争条件。

您可以将 UA 网页浏览代码的触发器从普通 'pageview' 更改为在 NavigationEnd

触发的自定义事件
router.events.subscribe(e => {
  if (e instanceof NavigationEnd) {
    dataLayer = window.dataL
    dataLayer.push({'event':'custom pageview event'});
  }
})