标签和标签管理器的最佳实践

发布时间:2021 年 7 月 29 日

标签是插入到网站中的第三方代码片段,通常通过标签管理器进行插入。标签最常用于营销和分析。

标签和标签管理器对性能的影响在不同网站之间差异很大。标签管理器可以比作信封:标签管理器提供了一个容器,但您在其中填充什么以及如何使用它主要取决于您自己。

在此,我们讨论了优化标签和标签管理器的性能和 Core Web Vitals 的技术。尽管本文档引用了 Google Tag Manager,但讨论的许多想法也适用于其他标签管理器。

对 Core Web Vitals 的影响

标签管理器通常会间接影响您的 Core Web Vitals,因为它会占用快速加载页面并保持响应能力所需的资源。带宽可能被用于下载您网站的标签管理器 JavaScript 或其后续调用。主线程上的 CPU 时间可能被用于评估和执行标签管理器和标签中包含的 JavaScript。

最大内容ful 绘制 (LCP) 在关键页面加载期间容易受到带宽争用的影响。此外,阻止主线程可能会延迟 LCP 渲染时间

累积布局偏移 (CLS) 可能会受到影响,原因可能是延迟在首次渲染之前加载关键资源,或者标签管理器将内容注入到页面中。

与下一次绘制的交互 (INP) 容易受到主线程上 CPU 争用的影响,并且我们已经看到标签管理器的大小与较差的 INP 分数之间存在关联。

选择正确的标签类型

标签对性能的影响因标签类型而异。一般来说,图像标签(“像素”)性能最高,其次是自定义模板,最后是自定义 HTML 标签。供应商标签因其允许的功能而异。

请记住,您使用标签的方式在很大程度上影响其性能影响。“像素”之所以性能很高,很大程度上是因为这种标签类型的性质对其使用方式施加了严格的限制;自定义 HTML 标签不一定总是对性能不利,但由于它们为用户提供了高度的自由,因此很容易被误用,从而对性能不利。

在考虑标签时,请记住规模:任何单个标签的性能影响可能微不足道,但当在同一页面上使用数十个或数百个标签时,性能影响可能会变得非常显著。

并非所有脚本都应使用标签管理器加载

标签管理器通常不是加载实现用户体验的即时视觉或功能方面(例如 Cookie 通知、主视觉图或站点功能)的资源的最佳方式。使用标签管理器加载这些资源通常会延迟它们的交付。这对用户体验不利,并且还会增加 LCP 和 CLS 等指标。

此外,一些用户会阻止标签管理器。使用标签管理器来实现 UX 功能可能会导致某些用户的网站损坏。

谨慎使用自定义 HTML 标签

自定义 HTML 标签已经存在多年,并在大多数网站上被大量使用。自定义 HTML 标签允许您输入自己的代码,几乎没有限制,因为尽管名称如此,但此标签的主要用途是将自定义 <script> 元素添加到页面。

自定义 HTML 标签可以以各种方式使用,并且它们的性能影响差异很大。在衡量网站的性能时,请注意,大多数工具将自定义 HTML 标签的性能影响归因于注入它的标签管理器,而不是标签本身。

Creating a custom tag in Google Tag Manager

自定义 HTML 标签可以将元素插入到周围的页面中。将元素插入到页面中的行为可能是性能问题的来源,并且在某些情况下,还会导致布局偏移。

  • 在大多数情况下,如果将元素插入到页面中,浏览器必须重新计算页面上每个项目的大小和位置。此过程称为布局。单个布局的性能影响很小,但当它过度发生时,可能会成为性能问题的来源。这种现象对低端设备和具有大量 DOM 元素的页面影响更大。
  • 如果可见页面元素在周围区域已经渲染后插入到 DOM 中,则可能会导致布局偏移。这种现象并非标签管理器独有,但由于标签通常比页面的其他部分加载得晚,因此它们通常在周围页面已经渲染后插入到 DOM 中。

使用自定义模板

自定义模板支持与自定义 HTML 标签相同的一些操作,但构建于 JavaScript 的沙盒版本之上,该版本为脚本注入和像素注入等常见用例提供了 API。顾名思义,它们允许由高级用户创建模板,高级用户可以考虑到性能来构建模板。然后,技术水平较低的用户可以使用该模板。这通常比提供完全自定义 HTML 访问权限更安全。

由于对自定义模板施加了更大的限制,因此这些标签不太可能出现性能或安全问题。出于同样的原因,自定义模板并不适用于所有用例。

A custom template in Google Tag Manager

正确注入脚本

使用标签管理器注入脚本是一种非常常见的用例。推荐的方法是使用自定义模板和 injectScript API。

有关使用 injectScript API 转换现有自定义 HTML 标签的信息,请参阅转换现有标签

如果您必须使用自定义 HTML 标签,请记住

  • 应使用 script 标签(例如,<script src="external-scripts.js">)加载库和大型第三方脚本,该标签下载外部文件,而不是直接将脚本的内容复制粘贴到标签中。尽管放弃使用 <script> 标签消除了单独的往返行程来下载脚本的内容,但这种做法会增加容器大小,并阻止浏览器单独缓存脚本。
  • 许多供应商建议将其 <script> 标签放在 <head> 的顶部。但是,对于使用标签管理器加载的脚本,这通常是不必要的。在大多数情况下,当标签管理器执行时,浏览器已经完成解析 <head>

使用像素

有时,第三方脚本可以用图像或 iframe 像素代替。与基于脚本的对应物相比,像素可能支持较少的功能,因此通常被视为不太理想的实现。但是,当在标签管理器内部使用时,像素可以更动态,因为它们可以在触发器上触发并传递不同的变量。

像素是最具性能和安全性的标签类型,因为在触发后没有 JavaScript 执行。像素的资源大小非常小(小于 1 KB),并且不会导致布局偏移。

请咨询您的第三方提供商,以获取有关他们对像素支持的更多信息。此外,您可以尝试检查他们的代码以查找 <noscript> 标签。如果供应商支持像素,他们通常会将像素包含在 <noscript> 标签中。

Custom image tag in Google Tag Manager

像素的替代方案

像素之所以流行,很大程度上是因为它们曾经是在服务器响应不相关的情况下(例如,在向分析提供商发送数据时)发出 HTTP 请求的最便宜和最可靠的方式之一。navigator.sendBeacon()fetch() keepalive API 旨在解决相同的用例,但可以说比像素更可靠。

继续使用像素没有任何问题 - 它们得到很好的支持,并且性能影响最小。但是,如果您正在构建自己的信标,则值得考虑使用这些 API 之一。

sendBeacon()

navigator.sendBeacon() API 旨在在服务器响应无关紧要的情况下,将少量数据发送到 Web 服务器。

const url = "https://example.com/analytics";
const data = JSON.stringify({
    event: "checkout",
    time: performance.now()
});

navigator.sendBeacon(url, data);

sendBeacon() 具有有限的 API:它仅支持发出 POST 请求,并且不支持设置自定义标头。所有现代浏览器都支持它。

Fetch API keepalive

keepalive 是一个标志,允许使用 Fetch API 发出非阻止请求,例如事件报告和分析。它通过在传递给 fetch() 的参数中包含 keepalive: true 来使用。

const url = "https://example.com/analytics";
const data = JSON.stringify({
  event: "checkout",
  time: performance.now()
});

fetch(url, {
    method: 'POST',
    body: data,
    keepalive: true
});

如果 fetch() keepalivesendBeacon() 看起来非常相似,那是因为它们确实如此。实际上,在 Chromium 浏览器中,sendBeacon() 现在构建于 fetch() keepalive 之上。

fetch() keepalivesendBeacon() 之间进行选择时,重要的是要考虑您需要的功能和浏览器支持。fetch() API 明显更灵活;但是,与 sendBeacon() 相比,keepalive 的浏览器支持较少。

了解标签的作用

标签通常是按照第三方供应商提供的指南创建的。如果不清楚供应商的代码在做什么,请考虑咨询了解情况的人。征求第二意见可以帮助确定标签是否有可能造成性能或安全问题。

我们建议在标签管理器中用所有者标记标签。很容易忘记谁拥有标签,从而导致害怕删除,以免破坏某些东西!

触发器

在高层面上,优化标签触发器通常包括确保不要过度触发标签,并选择一个平衡业务需求与性能成本的触发器。

触发器是 JavaScript 代码,它会增加标签管理器的大小和执行成本。虽然大多数触发器都很小,但累积效应会累加。例如,拥有多个点击事件或计时器触发器可能会显著增加标签管理器的工作负载。

选择适当的触发事件

标签的性能影响可能会有所不同。一般来说,标签触发得越早,对性能的影响就越大。资源通常在初始页面加载期间受到限制,因此加载或执行特定资源(或标签)会占用其他资源的资源。

虽然为所有标签选择适当的触发器很重要,但对于加载大型资源或执行长脚本的标签来说,这一点尤其重要。

标签可以在页面浏览(通常是 Page load,在 DOM Ready 时,在 Window Loaded 时)或基于自定义事件触发。为避免影响页面加载,请在 Window Loaded 之后触发非必要标签。

使用自定义事件

使用自定义事件来响应 Google Tag Manager 内置触发器未涵盖的页面事件来触发触发器。例如,许多标签使用页面浏览触发器。但是,DOM ReadyWindow Loaded 之间的时间可能很长,因此难以微调标签触发的时间。自定义事件可能是解决此问题的方法。

首先,创建自定义事件触发器并更新您的标签以使用此触发器。

Custom Event trigger in Google Tag Manager

要触发触发器,请将相应的事件推送到数据层。

// Custom event trigger that fires after 2 seconds
setTimeout(() => {
  dataLayer.push({
    'event' : 'my-custom-event'
  });
}, 2000);

使用特定触发条件

定义特定触发条件以避免在不必要时触发标签。最简单有效的方法之一是确保标签仅在实际使用的页面上触发。

Trigger conditions in Google Tag Manager

内置变量可以合并到触发条件中以限制标签触发。

在适当的时间加载您的标签管理器

您可以通过调整标签管理器本身的加载时间来提高性能。触发器(无论如何配置)在标签管理器加载后才能触发。尝试调整标签管理器的加载时间,因为这可能产生同等甚至更大的影响。此决定会影响页面上的所有标签。

通过稍后加载标签管理器,您可以避免未来的性能问题,因为它可以防止意外地过早加载标签。

变量

使用变量从页面读取数据。它们在触发器和标签本身中都很有用。

与触发器一样,变量会将 JavaScript 代码添加到标签管理器,因此可能会导致性能问题。变量可能相对较小,例如读取 URL、Cookie、数据层或 DOM 部分的代码。它们还可以包括具有无限能力(和大小)的自定义 JavaScript。

尽量减少变量的使用,因为标签管理器会不断评估它们。删除不再使用的旧变量,以减少标签管理器脚本的大小及其使用的处理时间。

标签管理

有效使用标签可以降低性能问题的风险。

使用数据层

数据层是一个 JavaScript 对象数组,其中包含有关页面的信息。这些对象包含您要传递给 Google Tag Manager 的所有信息。

数据层也可以用于触发标签。

// Contents of the data layer
window.dataLayer = [{
    'pageCategory': 'signup',
    'visitorType': 'high-value'
  }];

// Pushing a variable to the data layer
window.dataLayer.push({'variable_name': 'variable_value'});

// Pushing an event to the data layer
window.dataLayer.push({'event': 'event_name'});

尽管可以在没有数据层的情况下使用 Google Tag Manager,但强烈建议使用数据层。数据层将第三方脚本可以访问的数据整合到一个位置,从而更好地了解其使用情况。除其他事项外,这可以帮助减少冗余变量计算和脚本执行。

通过使用数据层,您可以控制标签访问哪些数据,而不是提供完全的 JavaScript 变量或 DOM 访问权限。

数据层的性能优势可能不直观,因为更新数据层会导致 Google Tag Manager 重新评估所有容器变量并可能触发标签,这需要执行 JavaScript。尽管可能会滥用数据层,但总的来说,如果数据层似乎是性能问题的根源,则容器本身可能存在性能问题。数据层使这些问题更加明显。

删除重复和未使用的标签

当标签除了通过标签管理器注入外,还包含在页面的 HTML 标记中时,可能会发生重复标签。

应暂停或删除未使用的标签,而不是通过使用触发器例外来阻止它们。暂停或删除标签会从容器中删除代码;阻止不会。

删除未使用的标签后,请查看触发器和变量,以确定它们是否也可以删除。

暂停的标签会影响容器大小,但是,总有效负载小于标签处于活动状态时。

使用允许和拒绝列表

使用允许和拒绝列表,对页面上允许的标签、触发器和变量配置高度精细的限制。这可以用于帮助实施性能最佳实践和其他策略。

允许和拒绝列表通过数据层配置。

window.dataLayer = [{
  'gtm.allowlist': ['<id>', '<id>', ...],
  'gtm.blocklist': ['customScripts']
}];

例如,您可以阻止使用自定义 HTML 标签、JavaScript 变量或直接 DOM 访问。这意味着只能使用像素和预定义标签,以及来自数据层的数据。虽然这具有限制性,但它可以产生性能更高且更安全的标签管理器实现。

考虑使用服务器端标记

值得考虑切换到服务器端标记,特别是对于希望更好地控制其数据的大型网站。服务器端标记从客户端删除供应商代码,并随之将处理从客户端卸载到服务器。

例如,当使用客户端标记时,将数据发送到多个分析帐户意味着客户端为每个端点启动单独的请求。使用服务器端标记,客户端向服务器端容器发出单个请求,然后从那里将此数据转发到不同的分析帐户。

请记住,服务器端标记仅适用于某些标签。标签兼容性因供应商而异。

有关更多信息,请参阅服务器端标记简介

容器

标签管理器通常允许在其设置中存在多个实例,通常称为容器。可以在一个标签管理器帐户中控制多个容器。

每个页面仅使用一个容器

单个页面上的多个容器可能会造成严重的性能问题,因为它会引入额外的开销和脚本执行。至少,它会复制核心标签代码本身,而核心标签代码作为容器 JavaScript 的一部分交付,无法在容器之间重用。

很少能有效地使用多个容器。但是,在控制良好的情况下,有时可以使用,例如:

  • 包括一个较轻的“早期加载”容器和一个较重的“后期加载”容器,而不是一个大型容器。
  • 为技术水平较低的用户使用受限容器,为更复杂标签使用限制较少但控制更严格的容器。

如果您必须在每个页面上使用多个容器,请遵循 Google Tag Manager 关于设置多个容器的指南

如果需要,使用单独的容器

如果您将标签管理器用于多个属性(例如 Web 应用程序和移动应用程序),则您使用的容器数量可能会帮助或损害您的工作流程效率。它还会影响性能。

如果站点在使用和结构上相似,则单个容器可以有效地跨多个站点使用。例如,虽然品牌的移动应用程序和 Web 应用程序可能提供类似的功能,但应用程序的结构可能不同,因此通过单独的容器进行更有效的管理。

过于广泛地重用单个容器可能会增加容器的复杂性和大小,从而迫使复杂的逻辑来管理标签和触发器。

关注容器大小

容器的大小由其标签、触发器和变量决定。虽然小容器仍然可能对页面性能产生负面影响,但大容器几乎肯定会产生负面影响。

在优化标签使用情况时,容器大小不应是最重要的指标。但是,较大的容器大小通常是容器维护不善且可能被误用的警告信号。

Google Tag Manager 限制容器大小为 300 KB,并在容器大小达到大小限制的 70% 后发出警告。

大多数网站都应力求使其容器小于限制。为了进行比较,中位数站点容器约为 50 KB。就其本身而言,Google Tag Manager 库压缩后约为 33 KB。

命名您的容器版本

容器版本是容器在特定时间点的内容快照。使用有意义的名称并包含对有意义更改的简短描述,可以大大简化调试未来性能问题的难度。

标签工作流程

管理对标签的更改非常重要,以使其不会对页面性能产生负面影响。

部署前进行测试

在部署之前测试您的标签,以便在它们发布之前捕获问题(性能问题或其他问题)。

测试标签时需要考虑的事项包括:

  • 标签是否正常工作?
  • 标签是否会导致任何布局偏移?
  • 标签是否加载任何资源?这些资源有多大?
  • 标签是否会触发长时间运行的脚本?

预览模式

预览模式 允许您在实际网站上测试标签更改,而无需先将其部署到公共环境。预览模式包含一个调试控制台,提供有关标签的信息。

由于在调试控制台中公开信息需要额外的开销,因此在预览模式下运行时,Google Tag Manager 的执行时间会有所不同(稍慢)。因此,不建议将预览模式下收集的 Web Vitals 指标与生产环境中收集的指标进行比较。但是,这种差异不应影响标签本身的执行行为。

独立测试

测试标签的另一种方法是设置一个空页面,其中包含一个容器,容器中只有一个标签——您正在测试的标签。这种测试设置不太真实,并且不会捕获某些问题(例如,标签是否会导致布局偏移)——但是,它可以更轻松地隔离和衡量标签对脚本执行等方面的影响。请查看 Telegraph 如何使用这种隔离方法来提高 第三方代码的性能。

监控标签性能

Google Tag Manager Monitoring API 可用于收集有关特定标签的执行时间的信息。此信息将报告到您选择的端点。

有关更多信息,请参阅 如何构建 Google Tag Manager 监控器

要求批准容器更改

第一方代码通常在部署前会经过审查和测试。同样对待您的标签。

添加两步验证(需要管理员批准容器更改)是实现此目的的一种方法。或者,如果您不想要求两步验证,但仍想关注更改,则可以设置容器通知,以接收有关您选择的容器事件的电子邮件警报。

定期审核标签使用情况

使用标签的挑战之一是它们往往会随着时间的推移而累积:标签会被添加,但很少被删除。定期审核标签是扭转这种趋势的一种方法。执行此操作的理想频率取决于您的网站标签的更新频率。

标记每个标签,使所有者显而易见,这样可以更容易地识别谁负责该标签,并可以说明是否仍然需要该标签。

审核标签时,请记住清理触发器和变量。它们也常常是性能问题的原因。

有关更多信息,请参阅控制第三方脚本