GoogleTagManagerの優先度(priority)とAdobeDataCollectionの優先度(Order)の挙動の違い

catch-img

GoogleTagManager(以下GTM)には、「タグ配信の優先度」という機能がありますよね。

タグの詳細設定の箇所にある設定で、その名の通りタグ配信における優先度を決めます。

(値が大きいほど、先に処理を開始します。)

細かいことについては 【GTM】タグ配信の優先度 / タグの順序付け と 非同期処理を待つ実装 で説明していますのでご覧ください。

一方で、AdobeDataCollection(旧: Adobe Launch | 以下 ADC) にも優先度の項目があります。

この記事では、両者の挙動がどう異なるのか、あるいはほぼ同じなのか、のようなことを深堀りしていきます。

目次[非表示]

  1. 1.用語整理
  2. 2.ADCの優先度設定
  3. 3.GTM:優先度の挙動
  4. 4.ADC: 優先度の挙動
    1. 4.1.第1フェーズ
    2. 4.2.第2フェーズ
    3. 4.3.各registry は orderを担保している
    4. 4.4.Ruleの発火
  5. 5.GTMとADCの異なる点
  6. 6.まとめ
    1. 6.1.パフォーマンス面の違い

用語整理

GTMについてはよく知っている方も多いと思いますが

今回ADCについても触れますので簡単に対応表を書くと以下のような形です。

レイヤー

GTM

Adobe Data Collection

対応関係

補足

実行単位(入れ物)

タグ(Tag)

ルール(Rule)

完全一致ではない

Ruleは Event / Condition / Action をまとめる箱

実行処理(本体)

タグ(Tag)

アクション(Action)

ここが実質対応

GTMのタグに最も近いのは Adobe の Action

発火タイミング

トリガー(Trigger)

イベント(Event)

一部対応

PageView, DOMReadyなど / Adobeでは条件判定が Condition に分離される

発火条件

トリガー内条件 / 例外トリガー

条件(Condition)

分離対応

pageUrlなど / GTMではTriggerに含まれがちな条件を、Adobeでは独立要素として扱う

データ取得・加工

変数(Variable)

データ要素(Data Element)

ほぼ1:1

値の取得・加工・参照に使う

実際の画面を見たほうがわかりやすいですかね。

Ruleの設定画面は以下のような感じです。

Ruleという箱の中下記が設定されています。

  • Events:発火タイミング / GTMの ページビュー, DOMReady, ウィンドウの読み込み

  • Conditions: 条件 / GTMのPageURLやPagePathなどの条件

  • Actions: 実行されるもの / GTMの カスタムHTMLや、Google広告テンプレートなどのタグ

ADCの優先度設定

さて、ADCにも優先度の設定があるといいましたが、どこにあるのでしょうか。

GTMはタグ単位での設定でしたね。

実は ADCは Rule単位や Action単位ではなく、

「Rule × Events の組み合わせ(ペア)単位」で決まります。

ん?どゆこと?

まず、優先度を設定できる項目は「Events」になります。

「Rule」単位や「Action」単位ではありません。

例えば、先程の添付画像に「Page Top」の Eventsがありますが

その中で Order を指定できます。

なお、ADCは「order」の値が小さい方が優先度が高いです。(GTMとは逆です。)

また、先程の画像に「DOM Ready」もありましたね。

当然、そちらも同様に order を設定できます。

もう1度先程の画像を貼りますね。

GTMと決定的に異なるところは

Eventsごとに優先度を変えられるという点です。

上の画像の Rule は Events(GTMのトリガー)として

PageTop(GTMのページビュー)と DOM Ready が or 条件として設定してあります。

つまり、ページビューのタイミングとDOM Readyのタイミングで発火します。

そして、Eventsそれぞれに Order(優先度)を設定できます。

例えば、

ページビューとして発火するときは Order 50

DOM Ready として発火するときは Order 20

のように 同じルールでも「どのイベントとして発火するか」によって Order を変えることができるわけです。

というわけで、ADCの優先度は 「Rule x Events のペア単位」で決まるというわけです。

もう少し正確にいうと、「そのルールをどのイベントで発火させるか、その組み合わせに対して Order を設定できる」という言い方になるかと思います。

GTM:優先度の挙動

コードベースで挙動を追ってみましょう。

【GTM】タグ配信の優先度 / タグの順序付け と 非同期処理を待つ実装 でも記載したコードを抜粋します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
var fireTagsForEvent = function (firingMap, eventContext) {                                                                                                                                                                 
  var pendingTags = [];  // ソート・実行待ちのタグリスト                                                                                                                                                                
                                                                                                                                                                                                                              
  for (var tagIndex = 0; tagIndex < allTagDefinitions.length; tagIndex++) {                                                                                                                                         
    if (firingMap[tagIndex]) {  // このイベントで発火すべきタグか?                                                                                                                                                         
                                                                                                                                                                                                                              
      var tagDef = allTagDefinitions[tagIndex];  //  タグの定義オブジェクト                                                                                                                                      
      var completionCallback = makeCompletionCallback(eventContext.ld);
                                                                                                                                                                                                                              
      try {    
        // setUp/cleanUp チェーンを含む「実行クロージャ」を組み立てる                                                                                                                                                      
        var executeClosureOrNull = buildExecuteClosure(                                                                                                                                                                     
          tagIndex,                                                                                                                                                                                                         
          { onSuccess: completionCallback, onFailure: completionCallback, terminate: completionCallback },                                                                                                                  
          eventContext,                                                                                                                                                                                                     
          tagIndex
        );                                                                                                                                                                                                 
                 
        if (executeClosureOrNull) {                                                                                                                                                                                         
          var tagTypeName = tagDef[Ff.Va];  // タグタイプ名(例: "__html", "__googtag" など)
          var templateMeta = sandboxedTemplates[tagTypeName];  // テンプレート定義(ない場合は undefined)                                                                                                      
                                                                                                                                                                                                                              
          pendingTags.push({                                                                                                                                                                                                
            tagIndex: tagIndex,  // ソートの第2キー(同優先度なら定義順)                                                                                                                                              
            priority: (templateMeta ? templateMeta.priorityOverride || 0 : 0)                                                                                                                                               
                      || getEntityPriority(tagTypeName, 1)
                      || 0,                                                                                                                                                                                                 
            execute: executeClosureOrNull                                                                                                                                                                                   
          });                                                                                                                                                                                                               
        } else {
          // 発火できない状態(ブロック済みなど)→ 完了通知だけ送る
          reportTagSkipped(tagIndex, eventContext);
          completionCallback();                                                                                                                                                                                             
        }                                                                                                                                                                                                                   
      } catch (err) {                                                                                                                                                                                                       
        completionCallback();
      }
    }                                                                                                                                                                                                                       
  }
                                                                                                                                                                                                                              
  pendingTags.sort(comparePriority);  // 優先度降順、同値なら tagIndex 昇順                                                                                                                                            
  for (var i = 0; i < pendingTags.length; i++) {
    pendingTags[i].execute();  // 同期的に順番に呼ぶだけ                                                                                                                                                                    
  }                                                                                                                                                                                                                         
 
  return pendingTags.length > 0;     

重要なところはここですね

1
2
3
4
pendingTags.sort(comparePriority);  // 優先度降順、同値なら tagIndex 昇順                                                                                                                                            
for (var i = 0; i < pendingTags.length; i++) {
  pendingTags[i].execute();  // 同期的に順番に呼ぶだけ                                                                                                                                                                    
}    

やっていることは単純で

タグ実行関数の配列を優先度順に並び替えて

それを頭から順番に実行する、というだけです。

ではこのコードは「いつ」実行されるのでしょうか?

簡潔にいいますと「トリガータイミングで毎回タグのソートが走る」です。

(正確には dataLayerの1イベント単位で毎回稼働する)

例えば

「ページビュー」のタイミングになったら、トリガー条件を満たすタグがかき集められる

↓

それらのタグに対して 上記の fireTagsForEvent が実行される

↓

fireTagsForEventの中で sort されて順番にタグ配信される

↓

「DOM Ready」のタイミングになったら、トリガー条件を満たすタグがかき集められる

↓

それらのタグに対して 上記の fireTagsForEvent が実行される

↓

fireTagsForEventの中で sort されて順番にタグ配信される

↓

「ウィンドウの読み込み」タイミングになったら、トリガー条件を満たすタグがかき集められる

↓

それらのタグに対して 上記の fireTagsForEvent が実行される

↓

fireTagsForEventの中で sort されて順番にタグ配信される

・・・のような形で各イベントごとに

イベント発火 → タグ抽出 → ソート処理 → 順次タグ配信(execute)

というのを毎回処理しています。

つまり、GTMはイベントのたび(より正確には event 付きの dataLayer.push が処理されるたび)毎回ルール条件を確認し、「このイベントで発火すべきタグ」を集めて、さらにソートしてからタグ配信、というのを繰り返す仕組みになっています。

もう少し丁寧に表現してみると・・・

前提として、GTM はコンテナ読み込み時点で、タグ・ルール・条件を内部の一覧表として持っている。

dataLayer.push({ event: "..." }) が来ると、その時点の dataLayer の状態を使って「イベント名は一致するか」「URL は条件に合うか」「クリック要素は対象か」などの条件チェックを行い、発火すべきタグを選び、ソートして実行する。

ADC: 優先度の挙動

第1フェーズ

ADCの場合は、ページ読み込み時(launch.js の初期化時)に 1度だけ

全ルールの全イベントが { rule, event} のペアとして展開され

その後 event の Order に従ってイベントタイプを横断してグローバルソートされます。

つまりソート時点では ページビューなのか DOMReadyなのかなどは見ていなく

event の Order だけをみて {rule, event} を並び替えるということです。

具体的には以下のようなことをしています。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function buildRuleExecutionOrder(rules) {
  var pairs = [];
 
  // 全ルールのイベントを {rule, event} のペアに展開
  rules.forEach(function (rule) {
    rule.events.forEach(function (event) {
      pairs.push({ rule: rule, event: event });
      // rule: conditions と actions を持つ
      // event:  modulePath と ruleOrder を持つ
    });
  });
 
  // ruleOrder 昇順でソート(イベントタイプ横断のグローバルソート)
  pairs.sort(function (a, b) {
    return a.event.ruleOrder - b.event.ruleOrder;
  });
 
  return pairs;
}

modulePath というのは 「その event がどのタイミング(ページビューなのか DOMReadyなのか?)で発火するのかを教えてくれるもの」と思ってください。

このコードでやっていることを例を使って示します。

まず、以下のように rules の配列があります。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
var rules = [
    {
      name: "Rule A",
      events: [
        {
          modulePath: "core/src/lib/events/windowLoaded.js",
          ruleOrder: 10
        }
      ],
      conditions: [...],
      actions: [...]
    },
    {
      name: "Rule B",
      events: [
        {
          modulePath: "core/src/lib/events/domReady.js",
          ruleOrder: 90
        }
      ],
      conditions: [...],
      actions: [...]
    },
    {
      name: "Rule C",
      events: [
        {
          modulePath: "core/src/lib/events/libraryLoaded.js", // Page Top
          ruleOrder: 50
        }
      ],
      conditions: [...],
      actions: [...]
    },
    {
      name: "Rule D",
      events: [
        {
          modulePath: "core/src/lib/events/pageBottom.js",
          ruleOrder: 20
        }
      ],
      conditions: [...],
      actions: [...]
    },
    {
      name: "Rule E",
      events: [
        {
          modulePath: "core/src/lib/events/domReady.js",
          ruleOrder: 5
        }
      ],
      conditions: [...],
      actions: [...]
    }
  ];

これを buildRuleExecutionOrder(rules) が、まず { rule, event } に展開します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
var pairs =   [
    {
      rule: RuleA,
      event: {
        modulePath: "core/src/lib/events/windowLoaded.js",
        ruleOrder: 10
      }
    },
    {
      rule: RuleB,
      event: {
        modulePath: "core/src/lib/events/domReady.js",
        ruleOrder: 90
      }
    },
    {
      rule: RuleC,
      event: {
        modulePath: "core/src/lib/events/libraryLoaded.js", // Page Top
        ruleOrder: 50
      }
    },
    {
      rule: RuleD,
      event: {
        modulePath: "core/src/lib/events/pageBottom.js",
        ruleOrder: 20
      }
    },
    {
      rule: RuleE,
      event: {
        modulePath: "core/src/lib/events/domReady.js",
        ruleOrder: 5
      }
    }
  ]

その後、pairs.sort でソートした結果が以下です。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
[
    {
      rule: RuleE,
      event: {
        modulePath: "core/src/lib/events/domReady.js",
        ruleOrder: 5
      }
    },
    {
      rule: RuleA,
      event: {
        modulePath: "core/src/lib/events/windowLoaded.js",
        ruleOrder: 10
      }
    },
    {
      rule: RuleD,
      event: {
        modulePath: "core/src/lib/events/pageBottom.js",
        ruleOrder: 20
      }
    },
    {
      rule: RuleC,
      event: {
        modulePath: "core/src/lib/events/libraryLoaded.js", // Page Top
        ruleOrder: 50
      }
    },
    {
      rule: RuleB,
      event: {
        modulePath: "core/src/lib/events/domReady.js",
        ruleOrder: 90
      }
    }
  ]

先ほど書いたように、イベントタイプを横断して ruleOrder だけをみて並び替えます。

なので、この順序だけ見ると、windowLoaded が pageTop や domReady よりも前にくることも余裕であります。

第2フェーズ

各イベントに対応した Ruleを保持するためのオブジェクトが定義されます。

具体的には pageBottom, DOM Ready, Window Loaded のタイミングで発火するRuleを格納するオブジェクトが作られます。

※pageTop(ページビュー)は保持はされず別処理で queue に入りますがここでは詳細は言及しません。また、DirectCallやClickイベントなども別の処理です。

1
2
3
4
5
registry = {
  PAGE_BOTTOM: [],
  DOM_READY: [],
  WINDOW_LOADED: []
};

そして先程ソートした配列が forループ で回されて

各イベントタイプに対応した配列に push されていきます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
registerPageBottomTrigger: function (trigger) {
  registry[PAGE_BOTTOM].push({
    trigger: trigger
  });
},
registerDomReadyTrigger: function (trigger) {
  registry[DOM_READY].push({
    trigger: trigger,
    syntheticEventFn: createSyntheticEvent.bind(null, document)
  });
},
registerWindowLoadedTrigger: function (trigger) {
  registry[WINDOW_LOADED].push({
    trigger: trigger,
    syntheticEventFn: createSyntheticEvent.bind(null, window)
  });
}

modulePath が domReady.js であれば、registerDomReadyTrigger が呼ばれます。

modulePath が windowLoaded であれば、registerWindowLoadedTrigger が呼ばれます。

そして例えば DOMReadyであれば

1
2
3
4
registry[DOM_READY].push({
      trigger: trigger,
      syntheticEventFn: createSyntheticEvent.bind(null, document)
    });

という形で registry[DOM_READY] の配列に push されていくわけです。

trigger というのは複雑なのですが、「イベントが発火したので 『この Rule』 を実行しよう」というのを定義している callback だと思ってください。

syntheticEventFn については eventオブジェクトを作るための関数です。ここでは詳細には踏み込みません。

端的に言えば、registerDomReadyTrigger() は、

DOM Ready 用の registry[DOM_READY] に「あとで Rule を実行するための callback」を順番に push しています。

さて、一連の push が終わったあとどうなっているでしょうか。

ここでは 上記の「trigger」とか「syntheticEventFn」とか「callback」とかは分かりづらいので置いておいて、

シンプルに「どの Ruleがどこの配列に入ったか」を分かりやすく示したいと思います。

前述のように PageTopは registry には保持されなく、queue に積まれます。(詳細は言及しないため無視してもらっても構いません)

処理順

Rule

イベント

ruleOrder

登録先

1

RuleE

DOM Ready

5

registry[DOM_READY]

2

RuleA

Window Loaded

10

registry[WINDOW_LOADED]

3

RuleD

Page Bottom

20

registry[PAGE_BOTTOM]

4

RuleC

Page Top / Library Loaded

50

queue(registry には入らない)

5

RuleB

DOM Ready

90

registry[DOM_READY]

初期化後の状態

保存先

中身

registry[DOM_READY]

RuleE → RuleB

registry[WINDOW_LOADED]

RuleA

registry[PAGE_BOTTOM]

RuleD

queue

RuleC(Page Top / Library Loaded)

さて、ADCの話の一番最初に以下のように記載しました。

ADCの場合は、ページ読み込み時(launch.js の初期化時)に 1度だけ

全ルールの全イベントが { rule, event} のペアとして展開され

その後 event の Order に従ってイベントタイプを横断してグローバルソートされます。

実は、ページ読み込み時(launch.js の初期化時)に、ここまで説明したことが実行されます。

つまり、すべてのRuleに対して、DOMReady で発火する Ruleの配列を registry[DOM_READY] にセット、

WindowLoaded で発火する Ruleの配列をregistry[WINDOW_LOADED]にセット・・・(以下略)

というところまで「初期化の時点」で完了しているわけです。

※厳密には「Rule自体の配列」ではないですが分かりやすく表現しております。

各registry は orderを担保している

この1つ1つの registry[DOM_READY] や registry[WINDOW_LOADED] などが Order を担保していることが分かりますか?

例えば、元々以下のようなRuleの集まりだったとします。

※本来は第1フェーズ、第2フェーズで記載したような オブジェクトの持ち方をしていますが、

わかりやすさ重視で、情報として { rule名, タイミング , order} を記載していると思ってください。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[
  { ruleA,  pageBottom,   order: 45 },
  { ruleB,  windowLoaded, order: 10 },
  { ruleC,  domReady,     order: 55 },
  { ruleD,  pageBottom,   order: 25 },
  { ruleE,  windowLoaded, order: 60 },
  { ruleF,  domReady,     order: 15 },
  { ruleG,  pageBottom,   order: 50 },
  { ruleH,  windowLoaded, order: 5 },
  { ruleI,  domReady,     order: 40 },
  { ruleJ,  pageBottom,   order: 30 },
  { ruleK,  windowLoaded, order: 20 },
  { ruleL,  domReady,     order: 35 }
]

これを Order順でソートするとこうなるのでした。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[
  { ruleH,  windowLoaded, order: 5 },
  { ruleB,  windowLoaded, order: 10 },
  { ruleF,  domReady,     order: 15 },
  { ruleK,  windowLoaded, order: 20 },
  { ruleD,  pageBottom,   order: 25 },
  { ruleJ,  pageBottom,   order: 30 },
  { ruleL,  domReady,     order: 35 },
  { ruleI,  domReady,     order: 40 },
  { ruleA,  pageBottom,   order: 45 },
  { ruleG,  pageBottom,   order: 50 },
  { ruleC,  domReady,     order: 55 },
  { ruleE,  windowLoaded, order: 60 }
]

この時点で、完全に Order が小さい順に並んでいます。

そして、上記配列を順番に ループを回していって、domReady なら registry[DOM_READY] に pushする、

windowLoaded なら registry[WINDOW_LOADED] に pushする、ということをします。

最初は { ruleH, windowLoaded, order: 5 } なので
registry[WINDOW_LOADED] = [{ ruleH, order: 5 }]

次は { ruleB, windowLoaded, order: 10 } なので
registry[WINDOW_LOADED] = [{ ruleH, order: 5 },{ ruleB, order: 10 }]

次は { ruleF, domReady, order: 15 } なので
registry[DOM_READY] = [{ ruleF, order: 15 }]

次は { ruleK, windowLoaded, order: 20 } なので
registry[WINDOW_LOADED] = [{ ruleH, order: 5 },{ ruleB, order: 10 },{ ruleK, order: 20 }]

次は { ruleD, pageBottom, order: 25 } なので
registry[PAGE_BOTTOM] = [{ ruleD, order: 25 }]

次は { ruleJ, pageBottom, order: 30 } なので
registry[PAGE_BOTTOM] = [{ ruleD, order: 25 },{ ruleJ, order: 30 }]

次は { ruleL, domReady, order: 35 } なので
registry[DOM_READY] = [{ ruleF, order: 15 },{ ruleL, order: 35 }]

次は { ruleI, domReady, order: 40 } なので
registry[DOM_READY] = [{ ruleF, order: 15 },{ ruleL, order: 35 },{ ruleI, order: 40 }]

次は { ruleA, pageBottom, order: 45 } なので
registry[PAGE_BOTTOM] = [{ ruleD, order: 25 },{ ruleJ, order: 30 },{ ruleA, order: 45 }]

次は { ruleG, pageBottom, order: 50 } なので
registry[PAGE_BOTTOM] = [{ ruleD, order: 25 },{ ruleJ, order: 30 },{ ruleA, order: 45 },{ ruleG, order: 50 }]

次は { ruleC, domReady, order: 55 } なので
registry[DOM_READY] = [{ ruleF, order: 15 },{ ruleL, order: 35 },{ ruleI, order: 40 },{ ruleC, order: 55 }]

次は { ruleE, windowLoaded, order: 60 } なので
registry[WINDOW_LOADED] = [{ ruleH, order: 5 },{ ruleB, order: 10 },{ ruleK, order: 20 },{ ruleE, order: 60 }]

そして、最終的には以下のように分かれるわけです。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
registry = {
  [WINDOW_LOADED]: [
    { ruleH, order: 5 },
    { ruleB, order: 10 },
    { ruleK, order: 20 },
    { ruleE, order: 60 }
  ],
  [DOM_READY]: [
    { ruleF, order: 15 },
    { ruleL, order: 35 },
    { ruleI, order: 40 },
    { ruleC, order: 55 }
  ],
  [PAGE_BOTTOM]: [
    { ruleD, order: 25 },
    { ruleJ, order: 30 },
    { ruleA, order: 45 },
    { ruleG, order: 50 }
  ]
}

見ていただいて分かるように、

registry[DOM_READY] の配列は order順に並んでいますよね?(15→35→40→55)

registry[WINDOW_LOADED] も 5→10→20→60 と order順です。

pageBottom も同様です。

考えてみれば当たり前なのですが、元々の配列が

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[
  { ruleH,  windowLoaded, order: 5 },
  { ruleB,  windowLoaded, order: 10 },
  { ruleF,  domReady,     order: 15 },
  { ruleK,  windowLoaded, order: 20 },
  { ruleD,  pageBottom,   order: 25 },
  { ruleJ,  pageBottom,   order: 30 },
  { ruleL,  domReady,     order: 35 },
  { ruleI,  domReady,     order: 40 },
  { ruleA,  pageBottom,   order: 45 },
  { ruleG,  pageBottom,   order: 50 },
  { ruleC,  domReady,     order: 55 },
  { ruleE,  windowLoaded, order: 60 }
]

と完全に order 順になっていて、それを forループで回して

先頭から処理していくのですから(つまり order順に処理していくわけなので)

同じ domReady であれば 15→ 35 → 40 → 55 と order順に pushされていく = orderは担保された状態で維持される、というわけです。

Ruleの発火

Ruleの発火については非常にシンプルで

例えば DOMReady のタイミングになったら

先ほどの registry[DOM_READY] の配列をループさせて、先頭から順番に実行していく、ということになります。

registry[DOM_READY] の配列が既に Order順に並んでいるわけですから、

先頭から順番に処理していけば、それがOrder(優先度)を加味した処理順ということになります。

同様に、WindowLoaded のタイミングであれば、registry[WINDOW_LOADED] の配列をループさせて順番に実行していきます。

GTMとADCの異なる点

GTMのpriority と ADC の Order を差異を

まとめると以下のような感じになるかと思います。

GTM priority

ADC Order

ソートのタイミング

イベントが起こるたびに毎回、発火対象のタグを並べる

ページロード時に1回だけ、全 rule event を並べる

並べる基準

タグに設定された priority

event に設定された ruleOrder

数値の意味

値が大きいほど先に実行される

値が小さいほど先に登録される

対象単位

タグ単位

rule 単位ではなく、rule に紐づく event 単位

発火時の処理

発火時に対象タグを priority 順に並べて実行する

発火時には基本的に再ソートせず、ページロード時に登録された順番で実行する

まとめ

いかがでしたでしょうか。

簡単ではありますが、GTMの優先度(priority)と ADCの優先度(Order)の仕組み上の違いについて記載しました。

大きな違いとしてはやはり「ソートのタイミング」が挙げられるかと思います。

GTMの方はイベントがトリガーされる度に、発火させるタグを集めて、ソートして、順次実行する、というのを毎回行っています。

ADCの場合は、ページロード時(launch.jsの初期化時)に一度だけ、すべての{Rule, Event} のペアをソートして、各イベントタイプごとの配列にPushしていきます。

そして、例えば、実際に DOMReadyのタイミングになったら、DOMReady用の配列から順番に取り出して実行していく、ということになります。

パフォーマンス面の違い

パフォーマンスだけを見ると、構造上は、ADCの方が発火時の処理範囲を絞りやすいです。

GTM

ADC

発火時に見る範囲

event ごとにルール表を見直す

そのイベントタイプに登録済みの trigger が中心

ソート

event ごとに発火候補タグを sort

初期化時に sort 済み。発火時は再 sort しない

条件評価

event ごとに必要な条件を評価

trigger 実行時に rule conditions を評価

実用上の差

通常は体感しにくい

通常は体感しにくい

ただし、この違いは多くのサイトでは体感差にはなりにくいと思います。

タグ数や条件数が極端に多い場合を除けば、設計上・構造上の実行速度の体感差はほとんどないと思います。

以上です。

これが分かったらかなんだ?という話は特になく

動きとしてどう差異があるのだろうというのを調べてみた記事でした。

何かの参考になれば!

Bye, bye.

Tomonaga
Tomonaga

人気記事ランキング

タグ一覧