SSR (Server Side Rendering,服务端渲染)
希望的是:服务端第一次只把渲染好的 HTML 发给客户端,这样客户端就能直接显示出来网页的样式,首次绘制(First Paint)就很快
然后,客户端再根据 HTML 需要的 js 向服务端请求 js,然后客户端再把 js 装到已经绘制好的 HTML 上
所谓服务端渲染,就发生在把 HTML 发给客户端之前,服务端先实时将 JSP、PHP 等渲染成 HTML 再发给客户端
CSR (Client Side Rendering,客户端渲染)
最终效果是:服务端把 html 发给客户端后,客户端是先请求剩余的 js,再绘制网页
并不是故意这么做的,非要阻塞绘制的进程,实在是因为那个 html 本来就是空的
看我们使用的前端框架就理解了,React 里用的是 jsx,也就是 js 执行到那一步才会创建 dom 元素
区别
听名字 SSR 和 CSR 是对立的两种,一个啥都是服务端做,一个啥都是客户端做,其实这种理解并不准确
它们所被应用的场景是不同的
前者应用于 JSP、PHP 这种,其中的“渲染”不是真的渲染,只是把发过去的 HTML 达到能让客户端直接渲染的程度,渲染本身还是要客户端来做的
后者应用于 Vue React 这类,由于页面究竟长什么样藏在 js 里面,必须靠浏览器拿到 js 后现场解析才知道,然后再渲染出来,这里的“渲染”是要真的渲染
从时间上来看,SSR 比较早,CSR 是后来才出现的
优势和劣势
CSR 的优势有
- 增进前端开发体验
- 增加页面互动性
相对于 SSR 的劣势有
- 页面空白,不仅是用户体验,更重要的是不利于 SEO
- 越来越大的 Javascript Bundle Size
改进:SSR 和 CSR 结合
要是把 SSR 和 CSR 的优点结合起来就好了
首次渲染用 SSR,这样就不耽误 SEO 了,之后再用 CSR 实现良好的交互性
对于 React 这种适用于 CSR 的来说,实现首次渲染用 SSR 需要一些技术
React 里的每个 component 有专门的地方放 dom 样式,所以说把这部分单独抽出来是可行的。而且,React 里自带一个 ReactDOMServer.renderToString(element)
函数,把 component 传进去就能返回一个 HTML 字符串
服务端要做的就是把这个节点字符串插入到基础 HTML 文件的 body 之中,同时也可以操作其中的 title,script 等节点
这样,发给客户端的就是能立刻用的 HTML 了,从而实现了 SSR
脱水(dehydrate)与注水(hydrate)
上面说的,服务端将 HTML 片段提炼出来的过程就称为脱水
相应的,注水是在客户端要做的事,把只有样子的 HTML 恢复其功能
React 有一个 ReactDOM.hydrate()
方法,可以实现注水。 ReactDOM.hydrate()
和 ReactDOM.render()
差不多,只是会复用已经存在的 DOM 节点,只进行事件绑定