首屏SSR服务端渲染(同构)

服务端渲染、Ajax、React和Vue

服务端渲染:

QQ20181204-090919@2x

缺陷:每一次页面切换都要重新下载刷新

Ajax

QQ20181204-090929@2x

缺陷:用户需要等待API请求成功才能看到第一条有意义的内容,并且性能有极限。对DOM树的直接操作都是很耗浏览器性能、更难以优化

Vue、React

使用虚拟DOM和浏览器路由等解决了上面的问题。

性能指标

TTFP(Time To First Paint):从网页HTTP请求发出,到用户可以看到的第一个有意义的内容渲染出来的时间。
显然我们希望TTFP越小越好。

代驾webapp为例:现在我们开发的时候,都是设定一个空的HTML架子,然后内嵌js文件的形式进行开发。
这样至少需要三次HTTP请求来能满足TTFP的时间点:

  1. 获取空的HTML架子
  2. 获取js文件
  3. 访问API服务器获取数据,然后重新渲染。

从这三点我们得思考,哪里可以进行优化:

  1. 能不能直接返回有内容的HTML架子?这个HTML架子需要多大,如果包含太多的数据,这个HTML页面对性能也会有影响
  2. 是否考虑代码分片?毕竟功能很多的话,将所有页面打包成一个js文件中,如果用户第一次访问网页,就需要很长的下载时间。当然代码分片会增加js资源数。对于来自同一个域名的资源,浏览器同时下载的个数是有限制的。

有内容的HTML架子有利于搜索引擎优化

首屏服务端渲染优化

定义:同一份既能在浏览器端渲染也能在服务端渲染产生HTML文件。

实际开发中,即把页面的展示内容和交互写在一起,让代码执行两次。在服务器端执行一次,用于实现服务器端渲染,在客户端再执行一次,用于接管页面交互。
QQ20181204-091004@2x
vue.renderToString

服务器渲染产生的React组件HTML被浏览器下载,浏览器加载完js等资源后重新渲染一遍。在渲染完成之前,用户就已经可以看到有内容的网页内容。

浏览器首屏生成的虚拟 DOM 树(virtual DOM tree)如果和从服务器渲染的 DOM 结构(DOM structure)不匹配的话,将会浏览器会覆盖掉服务器返回的HTML。闪烁,这样用户体验就很好了。

如何保证浏览器自己渲染的内容和服务器保持一致?

脱水和注水

  • 服务端生成脱水数据,
  • 客户端使用脱水数据进行注水。
    同构脚手架

脱水数据不要很大,会占用网页大小,如果脱水数据过大,影响性能,那首屏渲染也就失去意义。

是否有必要同构?

使用SSR渲染带来的弊端:

  • 项目复杂,可维护性降低
  • 代码的问题比较难以追溯。服务端那里出错?还是客户端这里代码写错了?

项目特别依赖搜索引擎流量,或者对首屏时间有特殊的要求。否则看你自己喜欢。