脸书对全球用户部署了最新版本的网页接口,并且公开最新的网页设计堆栈,其使用声明性JavaScript函数库React,以及GraphQL用户端Relay,来重新打造Facebook.com,完成可快速启动以及提供更丰富用户体验的目的。
Facebook.com在2004年上线时,是一个服务器渲染的PHP网站,但随着时间的发展,加入许多新技术以及新功能,在叠床架屋的情况下,使得网站速度越来越慢,而且也难以加入新的功能,包括深色模式以及更多动态消息操作等用户体验。
脸书意识到现有技术堆栈已经无法支持他们想要的应用程序功能以及性能,因此才计划以最新的浏览器技术,打造一个全新的网页应用程序,脸书提到,整个打掉重练的例子很少,但是过去十年技术变化太大,他们必须整个重写才能实现他们想要完成的性能目标,以及未来的功能发展。
新的脸书网页其中一个重要的设计想法,便是只在需要的时刻,后端仅交付需要的资料,而这个想法也让脸书可在初始渲染首页时,减少80%的CSS,以及大幅减少初始JavaScript页面渲染程序代码。
在旧的脸书网站,当加载首页时,会需要加载超过400 KB的压缩CSS,这些CSS在未压延时容量更高达2 MB,不过,这么大的CSS文件,在初始渲染时仅使用了10%,脸书提到,他们一开始也没有这么多CSS,是随着时间发展一点一滴增加,而增加的原因部分是因为要增加新功能,就必需要添加新的CSS。
脸书解决这个问题的方法,是在构建时期产生原子CSS,原子CSS样式只会以对数曲线增长,也就是说,相同的样式声明只会存在一份,因此总数量不会因开发团队撰写的功能数和重复样式而增加,脸书将整个网站产生的原子CSS,组合成一个单一的小型共享样式表,让新首页下载CSS的量不到旧网站的20%,而且网站也能支持深色模式和动态字体大小,并且提高了图像渲染性能。
而且脸书还通过拆分JavaScript以提高网页的性能,脸书提到,程序代码的大小是JavaScript单页面应用程序性能最重要的考量点,因为JavaScript的大小会严重影响页面加载的性能,所以脸书利用增量程序代码下载来解决这个问题,当用户在等待页面加载时,脸书会先呈现页面的用户接口骨架,立即让用户感受到反馈。
脸书提到,因为框架需要的资源最少,因此当把所有程序代码都打包在一起,便无法提早渲染框架,因此脸书根据页面显示顺序,将程序代码拆分成多个程序包,但脸书表示,直接这么做无法提升性能,反而会伤害性能,重点在于他们使用静态可分析的API,将JavaScript初始加载分为三层。
第一层是首页的基本布局,包括初始加载状态的用户接口骨架,第二层则为显示所有首页内容需要的JavaScript,在第二层之后,所有屏幕上显示的内容,就不会产生任何视觉变化,而第三层则包含不用于显示的所有资料,这些资料不会影响屏幕上的像素,包括日志程序代码和更新资料的订阅等。
这个做法使原本500 KB的JavaScript页面下载资料量,重新分配为第一层50 KB,在第二层则是150 KB,第三层为300 KB,由于第三层的资料不影响屏幕上的像素,因此渲染时间仅发生在第一层和第二层,进而减少首次页面搭建和可视化的时间。
另外,资料截取也是一个重点,脸书提到,虽然在旧的网站上,在某些功能已经使用GraphQL截取资料,但大多数临时获取的资料,都还是由服务器端PHP渲染处理,而在新网站中,他们完全改用GraphQL。
由于许多网页应用程序,都需要等到JavaScript下载完之后,才能知道需要向服务器请求哪些资料,因此会增加画面搭建时间,但Relay可以静态地知道页面需要的资料,也就是说,一旦服务器收到页面请求,便可以立刻准备需要的资料,并且和需要的程序代码平行下载,而这样能够减少额外的往返,所以能更快速地呈现最终页面内容。