CloudFlare的Rocket Loader实际如何工作(开发人员如何确保兼容性)?


31

CloudFlare拥有一项颇具突破性的技术,称为Rocket Loader(包括免费和付费帐户)。但是它实际上如何工作?

他们有一对夫妇网页描述的技术,但不是很多的技术细节。一个关键特性是,它使所有Javascript以非阻塞方式(异步)加载,这是一个了不起的壮举!这意味着可以在不等待脚本加载和运行的情况下呈现HTML / CSS。

CloudFlare火箭装载机图

那怎么可能?

当然,它不能简单地更改所有<script>要使用的标签,async="true"否则defer="true"会破坏几件事...

  1. 脚本仍然需要按正确的顺序加载(例如,在jQuery库加载之前,您无法加载jQuery插件。)
  2. document.write()这些脚本中的调用需要起作用(显然,这些命令在典型的异步脚本中不起作用)。
  3. DOMContentLoaded事件呢?如果触发加载了一些脚本,它们的事件处理程序是否未触发?

作为开发人员,我还有其他需要注意的内容,以确保我的网站/脚本/插件与Rocket Loader保持兼容吗?

Answers:


26

CloudFlare的描述火箭装载机 这样 ...

Rocket Loader是一种通用异步JavaScript加载器,结合了轻量级的虚拟浏览器,可以在window.onload之后安全地运行任何JavaScript代码。

火箭装载机可以做很多事情:

  1. 它确保页面上的所有脚本都不会阻止页面内容的加载;
  2. 异步加载页面上的所有脚本,包括第三方脚本;
  3. 将所有脚本请求捆绑为一个请求,通过该请求可以流式传输多个响应;
  4. 在大多数浏览器和几乎所有智能手机上使用LocalStorage来更智能地存储脚本,因此除非必要,否则不会重新提取脚本。

这很酷,但是如何实现呢?

从我在自己的网站上运行CloudFlare + Rocket Loader所读并发现的内容来看,它的工作原理大致如下:

  1. 当从CloudFlare服务器请求HTML页面时,从原始Web主机加载HTML页面后,它将所有脚本标签重写为 <script type="text/rocketscript">

  2. 浏览器自然会忽略脚本标签,因为它们不了解“文本/ rocketscript”格式

  3. CloudFlare还向cloudflare.min.js执行魔术的页面中注入了其他脚本(请参见此处的格式化版本)。这是浏览器最初(异步)加载的唯一脚本。

  4. 该脚本将解析页面中所有类型为“ text / rocketscript”的脚本。

  5. 然后,它检查浏览器的本地存储中是否已经存在任何这些脚本。如果不是,则从CloudFlare CDN向它们发出AJAX请求(组合成逻辑捆绑)。我不太确定如何将脚本分组在一起。

  6. CDN服务器从其缓存或原始服务器中收集脚本(可能来自多个不同的服务器:Google,Twitter,Facebook,其他CDN等),然后将它们组合,缩小和压缩后再发送回浏览器。

  7. 这种虚拟浏览器的东西,他们是指必须仅仅是一些JavaScript代码运行,然后在每一个正确的顺序执行这些脚本,做这样的事情:

    • 捕获所有呼叫document.write()并将该内容注入到页面上的正确位置。(可能是通过write()自定义功能覆盖浏览器的功能吗?)
    • 触发事件,例如DOMContentLoadedload

实际上,我很震惊,它的作品(虽然也许 并不 总是)。但是在正常情况下,我认为开发人员不需要做任何特殊的事情来使其JavaScript兼容。

这是社区Wiki,因此请编辑并添加所有缺少的其他详细信息。


2
如上所述,这可能会导致问题,因此可能需要将其禁用,因此请在部署之前进行测试。

虚拟浏览器可能是一个影子DOM像现代框架,如骨干,角,灰烬,淘汰赛等所使用的那些
凯泽

3
如果我们转到任何启用了cloudfare的页面,并且启用了robotscript脚本,那么我们可以在控制台中看到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 2015年

上述帖子的意大利语翻译(如果有人感兴趣):klayz.com/community/…– Glauco Zega
2016年

5
我注意到的一件事是,火箭装载机使用document.write。从Chrome 53开始,DevTools会针对有问题的document.write()语句发出警告,并且这种使用会触发警告。实际上,Chrome 53 +在2G连接上将阻止CloudFlare对document.write()的使用。有关更多信息,请参见Chrome开发人员
。developers.google.com/web/updates/2016/08/…
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.