Как тег Google Universal Analytics позволяет мне вызывать методы, пока скрипт еще загружается?

Я создаю платформу в стиле Google Analytics, которая работает с довольно стандартным потоком:

  1. Пользователи получают и настраивают фрагмент JS с уникальными параметрами учетной записи.
  2. Они встраивают этот фрагмент JS на свой веб-сайт, который асинхронно загружает мою основную библиотеку.
  3. После загрузки библиотеки пользователи могут вызывать ее методы для отправки данных в мое веб-приложение.

Изучив несколько различных реализаций того, как разные компании справляются с описанным выше потоком, я обнаружил, что новый от Google Тег Universal Analytics кажется наиболее элегантным по следующей причине:

Кажется, это позволяет пользователям вызывать методы, пока основная библиотека все еще асинхронно загружается, и все это внутри одного тега <script type="text/javascript">.

Пример этого можно найти прямо в коде быстрого старта:

<!-- Google Analytics -->
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');

ga('create', 'UA-XXXX-Y', 'auto');
ga('send', 'pageview');

</script>
<!-- End Google Analytics -->

Я пытаюсь понять, как это позволяет пользователю вызывать ga('create' ... ) и ga('send' ... ), в то время как основная анонимная функция все еще предположительно манипулирует DOM и вставляет/загружает скрипт analytics.js.

Кто-нибудь знает, как работает приведенный выше шаблон?

Попытка обратного проектирования их минимизированного кода, по-видимому, предполагает, что они могут создавать пустой объект ga, который эффективно действует как очередь сообщений, пока не загрузится основная библиотека. Затем, когда библиотека загружается, она, похоже, анализирует объект очереди и делает то, что ему нужно (поскольку она сможет фактически выполнять свои задачи, учитывая, что библиотека загружена).

Я не уверен на 100%, правильно ли вышеизложенное, так как немного сложно перепроектировать весь их код.

Я создал аналогичную реализацию, в которой я использую объект window.tempDataWhileLibraryHasntLoaded для хранения всех данных, вызываемых такими методами, как ga("send" ...), до загрузки библиотеки. Затем библиотека анализирует этот объект, обрабатывает то, что ей нужно, и обнуляет объект, однако это не так. не кажется таким же чистым, как реализация Google.


person dbau    schedule 21.01.2014    source источник


Ответы (1)


Итак, распаковав минифицированный скрипт, он выглядит так (с удаленным кодом для вставки тега скрипта):

window.GoogleAnalyticsObject = 'ga';

window.ga = window.ga || function(){
    ( window.ga.q = window.ga.q || [] ).push(arguments);
}

window.ga.l = 1 * new Date();

Они создают window.ga и назначают его функции, которая помещает любые аргументы в массив, window.ga.q. || или операторы, чтобы убедиться, что вещи не перезаписаны, если они уже были созданы.

Поэтому, когда вы вызываете ga('foo', 'bar'), он просто сохраняет эти аргументы в массиве. Когда скрипт загрузится, он будет искать массив window.ga.q и перебирать его значения, находя «foo» и «bar» и вызывая соответствующие функции в загруженном скрипте.

person imcg    schedule 21.01.2014
comment
Спасибо дружище, отличное объяснение! - person dbau; 22.01.2014