在同构的React web应用程序中,选择服务器渲染的最佳方式是什么

What is the best way to selectively server-render in an isomorphic React web app?

本文关键字:服务器 方式 是什么 选择 最佳 React 同构 web 应用程序      更新时间:2023-11-19

我希望有大量内容的网页具有最佳性能。特别感兴趣的是,在移动设备上,我希望用户尽快看到折叠上方的内容,然后让应用程序尽快引导。

我有一个变量isBrowser,它在浏览器环境中是true,但在服务器环境中却是false。考虑以下渲染函数:

render() {
  return (
    <div>
      <ContentAboveTheFold />
      { isBrowser && <ContentBelowTheFold /> }
    </div>
  )
}

注意,通过这种方式构造render(),服务器需要渲染的标记更少,通过有线传输的数据更少,浏览器在第一次通过时需要渲染的标签更少

这很好,但在控制台React警告

React尝试在容器中使用重用标记,但校验和无效。这通常意味着您使用的是服务器渲染,而服务器上生成的标记不是客户端所期望的。React注入了新的标记来补偿哪些有效,但您已经失去了服务器渲染的许多好处。相反,要弄清楚为什么生成的标记在客户端或服务器上不同。

在服务器上,React使用作为属性嵌入顶级元素(例如data-react-checksum="941190765")的校验和来呈现标记。然后在客户端上,react在第一次渲染后计算校验和,如果它与服务器的校验和不同,它会完全丢弃服务器生成的标记,并用客户端生成的标记替换它。

作为一种变通方法,我发现在我的顶级组件的componentDidMount生命周期方法中,我可以在下一个动画帧上安排以下操作:

componentDidMount() {
  requestAnimationFrame(() => {
    appIsMounted = true;
    this.forceUpdate();
  });
}

然后我可以这样写我的渲染方法,react不会生成任何关于校验和的警告:

render() {
  return (
    <div>
      <ContentAboveTheFold />
      { appIsMounted && <ContentBelowTheFold /> }
    </div>
  )
}

这样做有明显的性能优势吗?在任何一种情况下,折叠上方的内容都会很快出现,对吧?额外的复杂性是否合理?

是的,用requestAnimationFrame/setTimeout更新是正确的方法

不过,我会把它放在状态中,而不是使用变量和forceUpdate。

相关文章: