FaceBook的NoScript策略

大家都知道FaceBook发明了BigPipe,把页面分为多个PageLet来加载,让服务端运算与客户端加载并行进行,使得页面可交互时间往前提了不少。我这里不谈如何实现BigPipe,而是分析下FaceBook如何处理不支持JavaScript的场景。

对于不支持BP的浏览器,服务端必须一次生成所有HTML,每个模块用到的JS和CSS也需要合并。那怎么让服务器尽早知道客户端不支持JS呢?FaceBook的办法是在BP模式的HTML里加上了NoScript标签和Meta跳转:

<noscript><meta http-equiv="refresh" content="0; URL=/?_fb_noscript=1" /></noscript>

这样,如果用户的浏览器不支持JS,那访问FaceBook的任何一个页面,都会重定向原URL,并带上_fb_noscript=1这个参数。接着,服务端根据这个标记就可以按照非BP模式输出完整的页面。

如果用户访问每一个页面都需要多一次重定向,是不是很浪费时间和带宽呢?确实如此!FaceBook已经考虑到这个问题了:服务端在收到_fb_noscript=1标记时,会给客户端设置noscript=1的Cookie,这样下次请求哪怕没有URL参数标记,服务端也可以根据Cookie标记适配到非BP模式。

但是,如果客户端突然又支持JS了呢?这种情况多半是在测试,理论上继续用非BP模式也没什么问题,但FaceBook还是很厚道的处理了这种情况:在非BP模式的HTML里有这么一段JS:

onloadRegister(function (){document.cookie="noscript=; path=\/; domain=.facebook.com;"});
onloadRegister(function (){window.location.href="http:\/\/www.facebook.com\/"});

这样,假如客户端不小心又可以执行JS了,之前种下的cookie标记会被这段JS清除,同时页面重定向,确保URL里不包含noscript标记,这样用户又会看到BP模式输出了。

今天要讨论的就是这些了。大家如果访问不了FaceBook,禁用JS刷新我的博客也能体验这个流程。之前为了让图片更彻底的lazyLoad,我在服务器把所有图片src都替换为空白图,再用JS去加载可视范围内的。这样如果浏览器不支持JS就看不到图片了。现在加上了本文提到的NoScript策略,就很好的解决了这个问题。

update @ 2014.02.10,因为本博客系统改动,已经不支持本文提到的这个策略了。

本文链接:参与评论 »

--EOF--

提醒:本文最后更新于 1914 天前,文中所描述的信息可能已发生改变,请谨慎使用。

专题「Web 产品思考」的其他文章 »

Comments