前段时间使用 React 与 Redux 重构了我们360netlab 的 开放数据平台。现将其中一些技术实践经验总结如下:
Universal 渲染
Universal (“同构”现在是公认的不准确的叫法)渲染是指在服务端与客户端使用一套代码进行渲染的技术。它所带来的优势如下:
- 与实现服务端渲染的传统应用相比,Universal 渲染中的客户端渲染减少了网络请求(主要是模板和静态资源的请求),提高了页面间切换的速度,可以看到页面之间的切换都是瞬间完成的。
- 与实现客户端渲染的传统 SPA(比如 Angular1.x 搭建的单页面应用)相比,Universal 渲染的服务端渲染提升了首屏加载速度,无须等待庞大的 Javascript 脚本加载完成后进行渲染,因此也无须使用欢迎界面了。
- 与使用不同语言实现服务端渲染+客户端渲染的应用(指的是后端语言为 Java、Python、PHP、前端语言为 JavaScript 的应用)相比,由于 Universal 渲染使用同一套代码(前后端均为 JavaScript),因此至少减少了一半的代码量。
Universal 渲染非常复杂,需要权衡的东西很多。不过这都是值得的,真正让网站达到了快如鬼魅的速度!顺便引用一句话:
According to research at Google, the difference of just 200 milliseconds in page load performance has an impact on user behavior.
根据 Google 的调查,在一个页面的加载过程中,仅仅200毫秒的差异就可以影响用户的行为。
延迟渲染
很多人抱怨 React 并没有大家说的那么快,其实 React 只是便于优化性能,在没有经验的新手手中,React确实可能会很慢。但如果你对 React 非常了解,那么快如鬼魅便不是虚言。React 性能优化的方法很多,网上也有无数的文章对其进行介绍(选择 React 的另一好处:活跃的社区),常见的方法主要是,使用不可变数据,快速进行变更检查,以避免不必要的重新渲染。但我们还要介绍一种方法——延迟渲染。
延迟渲染类似于分页或瀑布流,就是在一个有大量数据页面中,先渲染一部分,等用户滚动下去后,再进行渲染。
延迟渲染除了可以提升性能之外,还可以过滤掉不需要在服务端渲染的代码(服务端可没有re-render),以减少 Universal 的难度。
延迟渲染的方法很多,实现的轮子也很多,不再赘述了。
减小重量
在 React 与 Redux 的项目中,不可避免要引入一些第三方的库,因此最终打包的脚本重量很容易达到 500-800kb 以上(gzip 压缩前)。尽管首屏渲染速度不会受此影响(因为我们实现了 Universal 渲染中的服务端渲染,而浏览器又是自上而下解析的),但我们依然希望这个脚本的重量能够更小。现将一些可行的办法列举如下:
改变库的调用方式
写过NPM的包的同学很清楚,一个包通常会有一个入口文件,我们将所有的模块都放在这个入口文件中,以便其他开发者调用。但是如果仅仅只用了一个包中很少一个模块,那么从入口文件调用就会导致增加了很多多余的模块。为此,我们应该改变一些库的调用方式,来避免这种情况,比如:

