Как называется асинхронный шаблон проектирования Google Analytics и где он используется? - PullRequest
47 голосов
/ 06 августа 2011

Асинхронный код Google Analytics использует очень четкий шаблон проектирования для выполнения кода JavaScript.

Код зависит от библиотеки и не знает, загружена библиотека или нет. Если библиотека еще не загружена, она просто помещает все команды в очередь в объект Array. Когда библиотека загружается, она просто создает объект _gaq и выполняет все команды в той последовательности, в которой она была включена. Затем он перезаписывает функцию push, чтобы будущие команды выполнялись сразу.

Идея состоит в том, чтобы заставить команды работать очень быстро, когда они находятся в очереди. Код действительно проверяется позже, когда библиотека загружена.

Они также загружают библиотеку с параметрами async=true. Это практически не влияет на фактическое время загрузки страницы.

Команды выглядят так же, как их версии синхронизации, но первая строка - это имя функции, а следующие параметры - это параметры функции. Вы также можете вставить функции в этот массив, и они будут выполняться последовательно с нулевым контекстом. Так что если вам нужно сделать что-то синхронное с библиотекой, вы можете нажать функцию, чтобы сделать это внутри _gaq.

Я думаю, что это очень умное решение, но я никогда не видел его раньше. Кто-нибудь знает название этого шаблона или где он используется, кроме кода отслеживания Google Analytics?

Ответы [ 4 ]

45 голосов
/ 06 августа 2011

Я назвал это «очередью асинхронных функций», но это не совсем броское имя и, конечно, не формальное имя шаблона проектирования.

Интересно то, что, хотя я не видел, чтобы этот конкретный шаблон использовался ранее, так как 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, используемый метод внедрения делает асинхронную загрузку сценария в большинстве браузеров и содержит полезную диаграмму:

enter image description here

3 голосов
/ 09 августа 2011

Хорошая запись стратегий загрузки javascript доступна здесь http://friendlybit.com/js/lazy-loading-asyncronous-javascript/

И, насколько я помню, асинхронный синтаксис ga.js был вдохновлен Steve Souders . Вы можете посмотреть на ControlJS , один из его проектов

3 голосов
/ 06 августа 2011

Все, что он делает, это помещает данные в глобальный массив

var _qaq = _qaq || [];
_qaq.push(stuff);

Это в основном позволяет вам буферизовать данные для обработки до загрузки библиотеки.

Основная причина, по которой этот шаблон используется не так часто, заключается в том, что другим библиотекам обычно нужны ресурсы для загрузки, прежде чем они смогут что-либо делать. Не было бы никакого смысла начинать буферизацию команд jQuery.

Это не шаблон, он просто хранит данные в глобальном масштабе и говорит, что это обрабатывается кем-то другим, мне все равно, когда вы обрабатываете это.

Однако это умный способ справиться с тем фактом, что вы не знаете, когда что-то загружено или готово, общей альтернативой является блок DOMReady.

1 голос
/ 15 июня 2017

В 2014 году Илья Григорик написал пост под названием Внедренные скриптами «асинхронные скрипты» считаются вредными . Эта публикация ссылается на этот вопрос и использует фразу «организация очереди асинхронных функций» в качестве имени шаблона проектирования, используемого Google Analytics.

Организация очереди асинхронной функции отличается от более поздних шаблонов проектирования, таких как Fetch Injection , которые не требуют или не требуют глобально определенной очереди. Вот пример Fetch Injection, реализованный в модуле Fetch Inject и используемый для асинхронной загрузки ресурсов в документ:

enter image description here

Обратите внимание, что шаблон проектирования Fetch Injection способен загружать CSS в дополнение к JavaScript параллельно, устраняя блокирующее поведение CSSOM и загрузку веб-шрифтов, значительно уменьшая предполагаемую задержку. Порядок выполнения скриптов полностью сохраняется с помощью простого в понимании API, что упрощает управление загрузкой сложных групп ресурсов с полным программным контролем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...