Google Tag Managerのスクリプトを噛み砕いて理解する

Google Tag ManagerをWebページにインストールするためには以下のスクリプトを挿入する([参考](https://support.google.com/tagmanager/answer/14847097?hl=ja))。

```html
<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-ABCDEFGH');</script>
<!-- End Google Tag Manager -->
```

挿入するコードは圧縮されているため、何が行われるか直感的に分からない。

理解の補助として、`script`タグの改行と`function`の宣言を整理する。
```html
<script>
  (function (w,d,s,l,i) {
    w[l]=w[l]||[];w[l].push({'gtm.start':
    new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
    j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
    'https://www.googletagmanager.com/gtm.js? id='+i+dl;f.parentNode.insertBefore(j,f);
  })(window,document,'script','dataLayer','GTM-ABCDEFGH');
</script>
```
`window`や`document`などの情報や、Google Tag ManagerのID等を引数何らかの関数を叩いていることが読み取れるようになった。

関数で行われていることが気になるので、JavaScriptの部分にbiomeをかける([実行内容](https://biomejs.dev/playground/?code=KABmAHUAbgBjAHQAaQBvAG4AIAAoAHcALABkACwAcwAsAGwALABpACkAIAB7AAoAIAAgAHcAWwBsAF0APQB3AFsAbABdAHwAfABbAF0AOwB3AFsAbABdAC4AcAB1AHMAaAAoAHsAJwBnAHQAbQAuAHMAdABhAHIAdAAnADoACgAgACAAbgBlAHcAIABEAGEAdABlACgAKQAuAGcAZQB0AFQAaQBtAGUAKAApACwAZQB2AGUAbgB0ADoAJwBnAHQAbQAuAGoAcwAnAH0AKQA7AHYAYQByACAAZgA9AGQALgBnAGUAdABFAGwAZQBtAGUAbgB0AHMAQgB5AFQAYQBnAE4AYQBtAGUAKABzACkAWwAwAF0ALAAKACAAIABqAD0AZAAuAGMAcgBlAGEAdABlAEUAbABlAG0AZQBuAHQAKABzACkALABkAGwAPQBsACEAPQAnAGQAYQB0AGEATABhAHkAZQByACcAPwAnACYAbAA9ACcAKwBsADoAJwAnADsAagAuAGEAcwB5AG4AYwA9AHQAcgB1AGUAOwBqAC4AcwByAGMAPQAKACAAIAAnAGgAdAB0AHAAcwA6AC8ALwB3AHcAdwAuAGcAbwBvAGcAbABlAHQAYQBnAG0AYQBuAGEAZwBlAHIALgBjAG8AbQAvAGcAdABtAC4AagBzAD8AIABpAGQAPQAnACsAaQArAGQAbAA7AGYALgBwAGEAcgBlAG4AdABOAG8AZABlAC4AaQBuAHMAZQByAHQAQgBlAGYAbwByAGUAKABqACwAZgApADsACgB9ACkAKAB3AGkAbgBkAG8AdwAsAGQAbwBjAHUAbQBlAG4AdAAsACcAcwBjAHIAaQBwAHQAJwAsACcAZABhAHQAYQBMAGEAeQBlAHIAJwAsACcARwBUAE0ALQBBAEIAQwBEAEUARgBHAEgAJwApADsA))。

```html
<script>
  (function (w, d, s, l, i) {
    w[l] = w[l] || [];
    w[l].push({ "gtm.start": new Date().getTime(), event: "gtm.js" });
    var f = d.getElementsByTagName(s)[0],
      j = d.createElement(s),
      dl = l != "dataLayer" ? "&l=" + l : "";
    j.async = true;
    j.src = "https://www.googletagmanager.com/gtm.js? id=" + i + dl;
    f.parentNode.insertBefore(j, f);
  })(window, document, "script", "dataLayer", "GTM-ABCDEFGH");
</script>
```

`window`のプロパティに何かをpushしていたり、HTML要素の作成が行われていそうだ。

さらに分かりやすくするために変数の名前を変更する。それに伴い行が長くなったものの改行と、変数の宣言を`const`で分けて行うようにする。
```html
<script>
  (function (window, document, elementName, dataLayerName, gtmID) {
    window[dataLayerName] = window[dataLayerName] || [];
    window[dataLayerName].push({
      "gtm.start": new Date().getTime(),
      event: "gtm.js"
    });
    
    const firstElement = document.getElementsByTagName(elementName)[0];
    const newElement = document.createElement(elementName);
    const dataLayerParam = dataLayerName != "dataLayer"
      ? "&l=" + dataLayerName
      : "";
        
    newElement.async = true;
    newElement.src =
      "https://www.googletagmanager.com/gtm.js?id="
        + gtmID
        + dataLayerParam;
    firstElement.parentNode.insertBefore(
      newScript,
      firstElement
    );
  })(window, document, "script", "dataLayer", "GTM-ABCDEFGH");
</script>
```
最初のブロックでは`window`に`"dataLayer"`プロパティを配列を生やして、現在時刻と合わせて`gtm.js`というイベント名を持ったオブジェクトを追加している。

次のブロックではドキュメントの先頭にある`script`タグの特定と、新たな`script`タグを生成している。
そして、`dataLayerName`が`"dataLayer"`なので`dataLaterParam`は空文字列を持つようになっている(一見意味がなさそうだが、dataLayerNameを独自で持つようにすると必要となる)。

最後のブロックは先ほど作成した`script`タグに`src`属性と`async`属性を追加して、それを先頭の`script`タグの前に挿入している。
作成した`script`タグは`DOMContentLoaded`とは独立して、`https://www.googletagmanager.com/gtm.js?id=GTM-ABCDEFGH`を読み込み、Google Tag Mangarを有効化する。

つまり、このスクリプトはGoogle Tag Managerを利用するための準備から有効にするためのスクリプトの準備までを行うためのものであった。