小尝试!腾讯新闻React同构直出的优化实践

背景

前端同学都知道,页面性能优化是一个不断探索的过程。而在React同构直出这样一个复杂场景下的性能优化,更是需要一定的深度和实践经验。本文将结合腾讯新闻的实战经验,分享React同构直出的一些优化实践。

直出流程回顾

先简单回顾一下React同构直出的流程:

  1. 服务器收到请求后,根据路由和参数等信息,调用对应的React组件(Server Side Rendering)。
  2. 生成HTML模板,并把SSR得到的HTML代码插入其中。
  3. 把HTML模板返回给浏览器。

直观感受来看,React同构直出相比单纯从客户端渲染,省去了浏览器下载JS文件、解析JS文件、执行JS文件等一系列操作,可以明显提升首屏加载速度和用户体验。

问题

但是,在实际项目中,我们发现依然存在着以下问题:

  1. 首次访问时,由于需要进行SSR,服务端耗费了大量的CPU资源。
  2. 客户端需要重新渲染整个页面,导致首屏渲染延迟。
  3. 对于同样的页面,由于服务端生成HTML代码可能存在微小差异,导致缓存失效率提高。

针对这些问题,我们进行了以下优化实践:

优化实践

1. 异步/分块请求

为了减轻服务端在首次渲染时的负担,我们可以将请求异步化或者分块化。例如,我们可以把页面上的某些部分(如评论区)单独作为一个组件,在客户端渲染完成后再通过Ajax等方式获取数据并填充。

示例代码:

------ ------ - --------- --------- - ---- --------
------ ----- ---- --------

-------- ------------- -
  ----- ---------- ------------ - -------------

  ------------ -- -
    --------------------------
      -------------- -- -
        ---------------------------
      ---
  -- ----

  ------ -
    ----
      --------------------- -- -
        --- ---------------------------------------
      ---
    -----
  --
-

------ ------- ------------

2. 首屏骨架屏

为了避免用户在等待页面渲染时的焦虑和不安,我们可以采用首屏骨架屏技术。简单来说,就是先使用占位符填充整个页面,等到异步/分块请求完成后再替换成真正的内容。

示例代码:

--------- -----
------
  ------
    ----- ----------------
    --------- -----------
    -------
      --------- -
        ----------------- --------
      -
    --------
  -------
  ------
    ---- ---------
      ---- -----------------------
      ---- -----------------------
      ---- -----------------------
      ---- --- ---
    ------
    ------- ----------------------------
  -------
-------

3. 缓存策略

为了避免服务端生成的HTML代码微小差异导致缓存失效,我们可以采用类似CDN缓存的方式,在URL后面添加hash值或者版本号,来保证每一次请求获取到的都是同一个HTML代码。

示例代码:

----- ---- - ----------- -- --------------

- ----------------------------------------------------------- --------
---------------------------------------------------------------------------------------