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

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



这怎么可能?

无法简单地将所有<script>标签更改为使用async="true"defer="true",因为这会破坏几件事...


脚本仍然需要以正确的顺序加载(例如,您无法加载这些脚本中的document.write()调用需要起作用(显然,这些脚本在典型的异步脚本中不起作用)。
DOMContentLoaded事件怎么办?如果某些脚本在触发后加载,它们的事件处理程序是否会被触发?

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

#1 楼

CloudFlare用这种方式描述了Rocket Loader ...


Rocket Loader是一种通用异步JavaScript加载器
,它具有可以安全运行任何轻量级虚拟浏览器的功能
window.onload之后的JavaScript代码。

Rocket Loader做很多事情:


它确保页面上的所有脚本都不会阻止您的页面无法加载;
异步地加载页面上的所有脚本,包括第三方脚本;
将所有脚本请求捆绑到一个请求中,通过该请求可以流式传输多个响应;
使用大多数浏览器和几乎所有智能手机上的LocalStorage都可以更智能地存储脚本,因此除非有必要,否则就不会对其进行重新提取。

/>所以这很酷,但是它是如何实现的呢?

从我在自己的网站上运行CloudFlare + Rocket Loader所读到的内容中发现,它的运行方式很不错e ...


当从CloudFlare服务器请求HTML页面时,从原始Web主机加载HTML页面后,它将所有脚本标签重写为<script type=" text/rocketscript ">
浏览器自然会忽略脚本标签,因为它们不了解“文本/火箭脚本”格式。
CloudFlare还向执行魔术的页面中注入了额外的cloudflare.min.js脚本(请参见此处的格式化版本)。这是浏览器最初(异步)加载的唯一脚本。
此脚本将为页面解析任何类型为“ text / rocketscript”的脚本。
然后检查浏览器的本地存储中是否已存在这些脚本中的任何一个。如果不是,则从CloudFlare CDN向它们发出AJAX请求(组合成逻辑捆绑)。我不太确定如何将脚本分组在一起。
CDN服务器从其缓存或原始服务器中收集脚本(可能来自多个不同的服务器:Google,Twitter,Facebook,其他CDN等),然后将它们组合,缩小和压缩后再发送回到浏览器。

它们引用的这个虚拟浏览器必须仅仅是一些JavaScript,然后这些JavaScript才能以正确的顺序运行这些脚本,并执行以下操作:


捕获对document.write()的所有调用,并将该内容注入页面上的正确位置。 (可能是通过使用自定义函数覆盖浏览器的write()函数吗?)
重新触发诸如DOMContentLoaded和load之类的事件。有效(尽管可能并非总是如此)。但是在通常情况下,我认为开发人员不需要做任何特殊的事情来使其JavaScript兼容。 />

评论


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

– dan♦
2014年4月4日在23:54

虚拟浏览器可能是影子DOM,就像Backbone,Angular,Ember,Knockout等现代框架所使用的那样。

– kaiser
15年1月14日在22:57

如果我们转到任何启用了cloudfare的页面,并且启用了robotscript脚本,那么我们可以在控制台中看到document.write确实被更改了。我得到函数(b,d,e,g,h){if(u.getActivated())return c.apply(f,arguments); try {return j [a] .apply(f,arguments)} catch( i){返回j [a](b,d,e,g,h)}}作为字符串值。因此,document.write已被覆盖的假设确实是正确的。

–user3459110
2015年1月1日14:15在

上述职位的意大利语翻译(如果有人感兴趣):klayz.com/community/…

– Glauco Zega
16年1月2日在15:04

我注意到的一件事是,火箭装载机使用document.write。从Chrome 53开始,DevTools会针对有问题的document.write()语句发出警告,并且这种使用会触发警告。实际上,Chrome 53 +在2G连接上会阻止CloudFlare对document.write()的使用。有关更多信息,请参见Chrome开发人员。developers.google.com/web/updates/2016/08/…

– davemac
16-10-24在10:21