Как на самом деле работает Rocket Loader от CloudFlare (и как разработчик может обеспечить совместимость)?

31

CloudFlare обладает довольно революционной технологией под названием Rocket Loader (как для бесплатных, так и для платных аккаунтов). Но как это на самом деле работает?

У них есть несколько из страниц , которые описывают технологию , но не много технических деталей. Одной из ключевых особенностей является то, что он загружает весь Javascript неблокирующим образом (асинхронно) , что является невероятным подвигом! Это означает, что HTML / CSS можно рендерить, не дожидаясь загрузки и запуска скриптов.

Схема ракетного погрузчика CloudFlare

Как это возможно?

Конечно, он не может просто изменить все <script>теги, чтобы использовать, async="true"или defer="true"как это может сломать несколько вещей ...

  1. Скрипты по-прежнему нужно загружать в правильном порядке (например, вы не можете загружать плагины jQuery, пока не загрузится библиотека jQuery).
  2. document.write()вызовы в этих скриптах должны функционировать ( очевидно, они ничего не делают в типичных асинхронных скриптах ).
  3. Как насчет события DOMContentLoaded? Если некоторые сценарии загружаются после того, как это сработало, их обработчики событий остаются без запуска?

И как разработчику, есть ли что-то еще, что мне нужно знать, чтобы мои сайты / скрипты / плагины оставались совместимыми с Rocket Loader?

Саймон Ист
источник

Ответы:

27

CloudFlare описывает Rocket Loader следующим образом ...

Rocket Loader - это асинхронный загрузчик JavaScript общего назначения в сочетании с легковесным виртуальным браузером, который может безопасно запускать любой код JavaScript после window.onload.

Rocket Loader делает кучу вещей:

  1. Это гарантирует, что все скрипты на вашей странице не будут блокировать загрузку содержимого вашей страницы;
  2. Загружает все скрипты на вашей странице, включая сторонние скрипты, асинхронно;
  3. Объединяет все запросы сценариев в один запрос, по которому можно передавать несколько ответов;
  4. Использует LocalStorage в большинстве браузеров и почти на всех смартфонах для более интеллектуального хранения сценариев, поэтому они не перезагружаются без необходимости.

Так что это круто, но как этого добиться?

Из того, что я прочитал и обнаружил при запуске CloudFlare + Rocket Loader на моем собственном сайте, он работает примерно так ...

  1. Когда HTML-страница запрашивается с сервера CloudFlare, после загрузки ее с исходного веб-хоста она переписывает все теги сценария в <script type="text/rocketscript">

  2. Браузеры, естественно, игнорируют теги скрипта, так как они не понимают формат «text / rocketscript»

  3. CloudFlare также добавляет cloudflare.min.jsна страницу дополнительный скрипт, который выполняет магию ( см. Отформатированную версию здесь ). Это единственный скрипт, изначально загруженный браузером (асинхронно).

  4. Этот скрипт анализирует страницу для любых скриптов с типом "text / rocketscript".

  5. Затем он проверяет, существует ли какой-либо из этих сценариев в локальном хранилище браузера. Если нет, то он делает запрос AJAX для них (объединенный в логические пакеты) из CDN CloudFlare. Я не совсем уверен, как это работает, как сгруппировать сценарии вместе.

  6. Серверы CDN собирают сценарии (которые могут поступать с нескольких разных серверов: Google, Twitter, Facebook, других CDN и т. Д.), Либо из их кэша, либо с исходных серверов, а затем объединять, минимизировать и GZIP их перед отправкой обратно в браузер.

  7. Это виртуальный браузер , на который они ссылаются, должен быть просто JavaScript, который затем запускает каждый из этих сценариев в правильном порядке, выполняя такие вещи как:

    • Перехват всех звонков document.write()и вставка этого контента в правильное место на странице. (Возможно, переписав write()функцию браузера с пользовательской?)
    • Перезапуск событий, таких как DOMContentLoaded и load .

Я на самом деле очень шокирован, что это работает (хотя, возможно, это не всегда ). Но в нормальных условиях я не думаю, что разработчикам нужно делать что-то особенное, чтобы сделать их JavaScript-совместимыми.

Это вики сообщества, поэтому, пожалуйста, отредактируйте и добавьте любые дополнительные детали, которые отсутствуют.

Simon
источник
2
Как отмечалось выше, это может привести к проблемам и, следовательно, может потребоваться отключение, поэтому проверьте перед развертыванием.
Дан
Виртуальный браузер , возможно , является тенью DOM , как те , которые используются современными методиками , как Backbone, Угловое, Ember, Knockout и т.д.
Кайзер
3
Если мы перейдем на любую страницу с включенным облачным сервисом, на которой включена функция rocketscript, мы увидим, что консоль document.writeдействительно изменена. Я получаю function (b,d,e,g,h){if(u.getActivated())return c.apply(f,arguments);try{return j[a].apply(f,arguments)}catch(i){return j[a](b,d,e,g,h)}}в качестве строкового значения. Таким образом, гипотеза, document.writeкоторая была переписана, действительно верна.
user3459110
Итальянский перевод вышеуказанного поста, если кто-то заинтересован: klayz.com/community/…
Glauco Zega
5
Одна вещь, которую я заметил, - то, что ракетный загрузчик использует document.write. Начиная с Chrome 53, DevTools выдает предупреждения для проблемных операторов document.write (), и его использование вызывает предупреждение. На самом деле, использование CloudFlare document.write () было бы заблокировано Chrome 53 + при соединении 2G. Смотрите Chrome разработчиков для получения дополнительной информации developers.google.com/web/updates/2016/08/...
davemac