Jak faktycznie działa Rocket Loader CloudFlare (i jak deweloper może zapewnić zgodność)?

31

CloudFlare ma przełomową technologię o nazwie Rocket Loader (zarówno na kontach darmowych, jak i płatnych). Ale jak to właściwie działa?

Mają kilka z stron , które opisują technologię , ale nie wiele szczegółów technicznych. Jedną z kluczowych cech jest to, że sprawia, że wszystkie JavaScript ładowane są w sposób nieblokujący (asynchronicznie) , co jest niesamowitym wyczynem! Oznacza to, że HTML / CSS można renderować bez czekania na załadowanie i uruchomienie skryptów.

Schemat ładowarki rakietowej CloudFlare

Jak to możliwe?

Z pewnością nie można po prostu zmienić wszystkie <script>znaczniki do użycia async="true"lub defer="true"jak to złamie kilka rzeczy ...

  1. Skrypty nadal muszą ładować się w odpowiedniej kolejności (na przykład nie można załadować wtyczek jQuery, dopóki biblioteka jQuery nie zostanie załadowana).
  2. document.write()Wywołania w tych skryptach muszą działać ( najwyraźniej nie robią nic w typowych skryptach asynchronicznych ).
  3. Co ze zdarzeniem DOMContentLoaded? Jeśli niektóre skrypty zostaną załadowane po uruchomieniu, czy ich procedury obsługi zdarzeń nie zostaną uruchomione?

A jako programista, czy jest coś jeszcze, o czym muszę wiedzieć, aby zapewnić zgodność moich stron / skryptów / wtyczek z programem Rocket Loader?

Simon East
źródło

Odpowiedzi:

27

CloudFlare Rocket Loader opisuje jak to ...

Rocket Loader to asynchroniczny moduł ładujący JavaScript ogólnego zastosowania w połączeniu z lekką wirtualną przeglądarką, która może bezpiecznie uruchamiać dowolny kod JavaScript po window.onload.

Rocket Loader robi wiele rzeczy:

  1. Zapewnia, że ​​wszystkie skrypty na stronie nie będą blokować ładowania zawartości strony;
  2. Ładuje wszystkie skrypty na stronie, w tym skrypty innych firm, asynchronicznie;
  3. Pakuje wszystkie żądania skryptu w jedno żądanie, w którym można przesyłać strumieniowo wiele odpowiedzi;
  4. Wykorzystuje LocalStorage w większości przeglądarek i prawie wszystkich smartfonów do bardziej inteligentnego przechowywania skryptów, aby nie były ponownie uruchamiane, chyba że jest to konieczne.

To całkiem fajne, ale jak to osiągnąć?

Z tego, co przeczytałem i odkryłem po uruchomieniu CloudFlare + Rocket Loader na mojej stronie, działa mniej więcej tak:

  1. Gdy strona HTML jest żądana z serwera CloudFlare, po załadowaniu jej z hosta źródłowego przepisuje wszystkie tagi skryptu na <script type="text/rocketscript">

  2. Przeglądarki naturalnie ignorują tagi skryptów, ponieważ nie rozumieją formatu „text / rocketscript”

  3. CloudFlare wstrzykuje również dodatkowy cloudflare.min.jsskrypt na stronę, która wykonuje magię ( patrz tutaj sformatowana wersja ). Jest to jedyny skrypt początkowo załadowany przez przeglądarkę (asynchronicznie).

  4. Ten skrypt analizuje stronę pod kątem wszelkich skryptów typu „text / rocketscript”.

  5. Następnie sprawdza, czy którykolwiek z tych skryptów już istnieje w lokalnej pamięci przeglądarki. Jeśli nie, to wysyła do nich żądanie AJAX (połączone w logiczne pakiety) z CloudFlare CDN. Nie jestem do końca pewien, jak to działa, jak grupować skrypty razem.

  6. Serwery CDN zbierają skrypty (które mogą pochodzić z kilku różnych serwerów: Google, Twitter, Facebook, inne CDN itp.), Albo z ich pamięci podręcznej, albo z serwerów źródłowych, a następnie łączą je, minimalizują i GZIP przed wysłaniem z powrotem do przeglądarki.

  7. Ta wirtualna przeglądarka , do której się odnoszą, musi być po prostu JavaScriptem, który następnie uruchamia każdy z tych skryptów w odpowiedniej kolejności, wykonując takie czynności jak:

    • Przechwytywanie wszystkich wywołań document.write()i wstrzykiwanie tej zawartości w odpowiednie miejsce na stronie. (Być może poprzez zastąpienie funkcji przeglądarki write()niestandardową?)
    • Ponowne wyzwalanie zdarzeń, takich jak DOMContentLoaded i load .

Jestem całkiem wstrząśnięty, że działa (choć może to nie zawsze ). Ale w normalnych okolicznościach nie sądzę, aby programiści zrobili coś specjalnego, aby ich JavaScript był zgodny.

To jest wiki społeczności, więc edytuj i dodaj wszelkie brakujące szczegóły.

Simon
źródło
2
Jak wspomniano powyżej, może to powodować problemy i w konsekwencji może wymagać wyłączenia, dlatego przetestuj przed wdrożeniem.
dan
Przeglądarka wirtualny ewentualnie jest DOM cień jak te stosowane przez współczesnych ram, jak kręgosłup, kątowe, Ember, Knockout, itd.
Kaiser
3
Jeśli przejdziemy do dowolnej strony obsługującej chmurę, która ma włączoną tę funkcję rakietową, możemy zobaczyć w konsoli, która document.writejest rzeczywiście zmutowana. Otrzymuję 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)}}jako wartość ciągu. Tak więc hipoteza, która document.writezostała zastąpiona, jest rzeczywiście poprawna.
user3459110,
Włoskie tłumaczenie powyższego postu, jeśli ktoś jest zainteresowany: klayz.com/community/…
Glauco Zega
5
Jedną z rzeczy, które zauważyłem, jest to, że moduł ładujący rakiety używa document.write. Od Chrome 53 DevTools wydaje ostrzeżenia dla problematycznych instrukcji document.write () i takie użycie powoduje ostrzeżenie. W rzeczywistości użycie document.write () przez CloudFlare byłoby zablokowane przez Chrome 53 + na połączeniu 2G. Zobacz programistów Chrome, aby uzyskać więcej informacji developers.google.com/web/updates/2016/08/08/...
davemac