Google Analytics async コードは、JavaScriptコードの実行に非常に異なるデザインパターンを使用します。
コードはライブラリに依存しており、ライブラリがロードされているかどうかはわかりません。ライブラリがまだロードされていない場合は、すべてのコマンドをArrayオブジェクトにキューイングするだけです。ライブラリがロードされると、_gaqオブジェクトが作成され、含まれている順序ですべてのコマンドが実行されます。次に、プッシュ機能を上書きして、将来のコマンドがすぐに実行されるようにします。
アイデアは、コマンドがキューに入れられたときにコマンドを非常に高速に実行することです。コードは、後でライブラリがロードされたときにのみ実際に評価されます。
また、パラメータasync=true
を使用してライブラリをロードします。これにより、実際のページの読み込み時間にほとんど影響がありません。
コマンドは同期バージョンと同じように見えますが、最初の文字列は関数名であり、次のパラメーターはその関数パラメーターです。関数をこの配列にプッシュすることもでき、関数はnullコンテキストで順番に実行されます。したがって、ライブラリと同期して何かを行う必要がある場合は、関数をプッシュして_gaq内でこれを行うことができます。
これは非常に賢い解決策だと思いますが、私はこれまで見たことがありません。このデザインパターンの名前や、Google Analyticsのトラッキングコード以外に使用されている場所を知っている人はいますか?
私はこれを「非同期関数キューイング」と呼んでいますが、あまりキャッチーな名前ではなく、デザインパターンの正式な名前でもありません。
興味深いのは、この特定のパターンが以前に使用されたことはありませんでしたが、GoogleがGoogle Analyticsに採用したため、非同期ジュースを利用しようとしているさまざまなプラットフォームで広く採用されていることです(Disqusが思い浮かびます)。
この ブログ投稿 は、私が読んだ非同期Google Analytics構文の最も詳細な調査であり、パターンを複製する方法のかなり詳細な説明が含まれています。
ブログ投稿から:
var GoogleAnalyticsQueue = function () {
this.Push = function () {
for (var i = 0; i < arguments.length; i++) try {
if (typeof arguments[i] === "function") arguments[i]();
else {
// get tracker function from arguments[i][0]
// get tracker function arguments from arguments[i].slice(1)
// call it! trackers[arguments[i][0]].apply(trackers, arguments[i].slice(1));
}
} catch (e) {}
}
// more code here…
};
// get the existing _gaq array
var _old_gaq = window._gaq;
// create a new _gaq object
window._gaq = new GoogleAnalyticsQueue();
// execute all of the queued up events - apply() turns the array entries into individual arguments
window._gaq.Push.apply(window._gaq, _old_gaq);
また、async
属性をサポートするブラウザーは多くありませんが、使用されるインジェクションの方法により、ほとんどのブラウザーでスクリプトが非同期に読み込まれ、役立つグラフが含まれていることにも注意してください。
Javascriptの読み込み戦略の優れた記事はこちらから入手できます http://friendlybit.com/js/lazy-loading-asyncronous-javascript/
そして私が覚えている限り、ga.js非同期構文は Steve Souders に触発されています。彼のプロジェクトの1つである ControlJS を見ることができます
データをグローバル配列にプッシュするだけです
var _qaq = _qaq || [];
_qaq.Push(stuff);
基本的に、ライブラリがロードされる前に処理するデータをバッファリングできます。
このパターンがあまり使用されない主な理由は、他のライブラリは通常、何かを実行する前にロードするリソースを必要とするためです。 jQueryコマンドのバッファリングを開始しても意味がありません。
これは、単にデータをグローバルスコープに格納し、これを処理するのは他の誰かの仕事だと言っているパターンではありません。いつ処理してもかまいません。
ただし、何かがロードまたは準備ができたときにわからないという事実に対処するための賢い方法です。一般的な代替手段はDOMReadyブロックです。
2014年、Ilya Grigorikは、 スクリプトが挿入された「非同期スクリプト」が有害であると見なされた というタイトルの投稿を書きました。その投稿はこの質問にリンクしており、GoogleAnalyticsで使用されるデザインパターンの名前として「非同期関数キューイング」というフレーズを使用しています。
非同期関数のキューイングは、フェッチインジェクションのような、グローバルに定義されたキューを必要としない、または必要としない最近のデザインパターンとは異なります。 Fetch Injectモジュール に実装され、ドキュメント内のリソースを非同期的にダウンロードするために使用されるFetchInjectionの例を次に示します。
フェッチインジェクションデザインパターンは、JavaScriptに加えてCSSを並行してロードできることに注意してください。これにより、CSSOMとWebフォントのダウンロードのブロック動作が排除され、知覚される待ち時間が大幅に短縮されます。スクリプトの実行順序は、わかりやすいAPIを使用して完全に保持されるため、プログラムによる完全な制御により、複雑なリソースグループの読み込みを簡単に管理できます。