Wie funktioniert der Rocket Loader von CloudFlare tatsächlich (und wie kann ein Entwickler die Kompatibilität sicherstellen)?

31

CloudFlare hat eine bahnbrechende Technologie namens Rocket Loader (sowohl für kostenlose als auch für kostenpflichtige Konten). Aber wie geht das eigentlich?

Sie haben ein paar von Seiten , die die Technologie beschreiben , aber nicht viele technische Details. Eine wichtige Eigenschaft ist, dass das gesamte Javascript nicht blockierend (asynchron) geladen wird , was eine unglaubliche Leistung ist! Dies bedeutet, dass HTML / CSS gerendert werden kann, ohne auf das Laden und Ausführen von Skripten zu warten.

CloudFlare Rocket Loader-Diagramm

Wie ist das möglich?

Es kann doch nicht einfach alle ändern <script>Tags zu verwenden async="true"oder defer="true"als würde dies mehrere Dinge brechen ...

  1. Skripte müssen weiterhin in der richtigen Reihenfolge geladen werden (zum Beispiel können Sie jQuery-Plugins erst laden, wenn die jQuery-Bibliothek geladen wurde.)
  2. document.write()Aufrufe in diesen Skripten müssen funktionieren ( anscheinend tun diese in typischen asynchronen Skripten nichts ).
  3. Was ist mit dem Ereignis DOMContentLoaded? Wenn einige Skripte geladen werden, nachdem dies ausgelöst wurde, werden ihre Event-Handler nicht ausgelöst?

Und gibt es als Entwickler noch etwas, das ich beachten muss, um sicherzustellen, dass meine Websites / Skripte / Plugins mit Rocket Loader kompatibel bleiben?

Simon East
quelle

Antworten:

26

CloudFlare beschreibt Rocket - Loader wie dieses ...

Rocket Loader ist ein asynchroner Allzweck-JavaScript-Loader, der mit einem einfachen virtuellen Browser gekoppelt ist und nach window.onload jeden JavaScript-Code sicher ausführen kann.

Rocket Loader erledigt eine Reihe von Dingen:

  1. Dadurch wird sichergestellt, dass nicht alle Skripts auf Ihrer Seite das Laden des Inhalts Ihrer Seite blockieren.
  2. Lädt alle Skripts auf Ihrer Seite, einschließlich Skripts von Drittanbietern, asynchron.
  3. Bündelt alle Skriptanforderungen in einer einzigen Anforderung, über die mehrere Antworten gestreamt werden können.
  4. Verwendet LocalStorage in den meisten Browsern und auf fast allen Smartphones, um Skripts intelligenter zu speichern, sodass sie nur bei Bedarf erneut abgerufen werden können.

Das ist ziemlich cool, aber wie schafft es das?

Nach dem, was ich beim Ausführen von CloudFlare + Rocket Loader auf meiner eigenen Website gelesen und entdeckt habe, funktioniert es ungefähr so ​​...

  1. Wenn eine HTML-Seite von einem CloudFlare-Server angefordert wird, schreibt sie nach dem Laden vom Ursprungswebhost alle Skript-Tags neu in <script type="text/rocketscript">

  2. Browser ignorieren natürlich die Skript-Tags, da sie das Format "text / rocketscript" nicht verstehen.

  3. CloudFlare fügt außerdem ein zusätzliches cloudflare.min.jsSkript in die Seite ein, das die Magie ausführt ( siehe formatierte Version hier ). Dies ist das einzige Skript, das ursprünglich vom Browser geladen wurde (asynchron).

  4. Dieses Skript analysiert die Seite nach Skripten vom Typ "text / rocketscript".

  5. Anschließend wird überprüft, ob eines dieser Skripts bereits im lokalen Speicher des Browsers vorhanden ist. Andernfalls wird eine AJAX-Anforderung für sie (in logischen Paketen zusammengefasst) vom CloudFlare-CDN gesendet. Ich bin nicht ganz sicher, wie es funktioniert, um die Skripte zu gruppieren.

  6. Die CDN-Server erfassen die Skripte (die von verschiedenen Servern stammen können: Google, Twitter, Facebook, andere CDNs usw.) entweder aus ihrem Cache oder von den Ursprungsservern und kombinieren, verkleinern und GZIP-Dateien, bevor sie zurückgesendet werden zum Browser.

  7. Bei diesem virtuellen Browser , auf den sie verweisen, muss es sich lediglich um JavaScript handeln, mit dem jedes dieser Skripte in der richtigen Reihenfolge ausgeführt wird.

    • Abfangen aller Aufrufe document.write()und Einfügen dieser Inhalte an der richtigen Stelle auf der Seite. (Möglicherweise durch Überschreiben der Browserfunktion write()mit einer benutzerdefinierten?)
    • Ereignisse wie DOMContentLoaded erneut auslösen und laden .

Ich bin eigentlich ziemlich schockiert , dass es funktioniert (obwohl vielleicht es nicht immer ). Aber unter normalen Umständen glaube ich nicht, dass Entwickler etwas Besonderes tun müssen, um ihre JavaScript-Kompatibilität zu gewährleisten.

Dies ist ein Community-Wiki. Bearbeiten Sie die fehlenden Details und fügen Sie sie hinzu.

Simon
quelle
2
Wie oben erwähnt, kann dies zu Problemen führen und muss möglicherweise deaktiviert werden. Testen Sie dies daher vor der Bereitstellung.
Dan
Der virtuelle Browser ist möglicherweise ein Schatten DOM wie die von modernen Frameworks wie Backbone verwendete, eckig, Ember, Knockout, usw.
kaiser
3
Wenn wir zu einer Cloudfare-fähigen Seite gehen, auf der dieses Rocketscript-Ding aktiviert ist, können wir in der Konsole sehen, dass document.writees tatsächlich mutiert ist. Ich bekomme 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)}}als String den Wert. Die document.writeüberschriebene Hypothese ist also in der Tat richtig.
user3459110
Italienische Übersetzung des obigen Beitrags, falls jemand interessiert ist: klayz.com/community/…
Glauco Zega
5
Eine Sache, die mir aufgefallen ist, ist, dass der Raketenlader document.write verwendet. Seit Chrome 53 gibt DevTools Warnungen für problematische document.write () -Anweisungen aus und diese Verwendung löst eine Warnung aus. Tatsächlich würde CloudFlares Verwendung von document.write () bei einer 2G-Verbindung von Chrome 53+ blockiert. Siehe Chrome - Entwickler für weitere Informationen developers.google.com/web/updates/2016/08/...
davemac