react s-s-r 与代码拆分而不是 React.Lazy 的优缺点

Posted

技术标签:

【中文标题】react s-s-r 与代码拆分而不是 React.Lazy 的优缺点【英文标题】:the pros and const of react s-s-r with code splitting and now React.Lazy 【发布时间】:2019-04-03 21:26:18 【问题描述】:

我对 s-s-r 和代码拆分以及仅在客户端完成代码拆分的优点有点困惑。

我的想法是,服务器首先呈现页面会带来更好的体验,而无需解析所有的 javascript,然后再呈现服务器。

我很困惑代码拆分如何适应 s-s-r 模型,是 s-s-r 呈现第一个命中,然后在客户端上完成代码拆分?

React.Lazy 强调说 react.client 都是在客户端完成的。它与服务器上的代码拆分有何不同。如果你去一个特定的路线,那么你是否会在第一次渲染时检索该块?

我知道 React.Lazy 都是在客户端完成的,他们确实这么说。如果在服务器上做会有什么不同。

s-s-r 对代码拆分有什么真正的好处吗?它不仅增加了复杂性吗?

【问题讨论】:

【参考方案1】:

tl;博士

根据您的用例,您可以只使用 s-s-r、只使用代码拆分或根据需要组合两者。

s-s-r的优点

    更好的 SEO,因为搜索机器人可以使用标记(并且不一定依赖于执行 javascript)进行索引。

    更快的初始渲染 因为标记是从服务器发送的,所以浏览器不必等待执行 javascript 来渲染它。 (尽管在 react 客户端水合之前,标记仍然缺乏交互性)。

    首先交付关键 CSS。初始页面渲染的关键 CSS 可以内嵌,更好的用户体验,因为加载的标记已经准备好样式。

    更简单的路由拆分。 s-s-r imo 可以更简单地推断路由拆分您的应用程序。例如,/about/home 可能有不同的页面,您可以对它们进行路由拆分以减小包大小(并在需要时在客户端预加载其他路由)。

组合代码拆分组件和 s-s-r

可能不需要服务器渲染整个页面。例如,假设您的主页(您希望服务器呈现)包含一个 Chat 组件,因此用户可以直接向您提问。

如果这个组件很大,你可能会决定不服务器渲染它,这样用户就可以首先获得页面中最重要的部分。这将通过在您的主页组件中拆分此组件的代码来减少您的初始页面加载。

当浏览器解析标记后,它会在主包之后加载您的Chat 组件。通过这种方式,您可以识别并控制您的捆绑包大小。

仅使用代码拆分

如果您对 s-s-r 的好处不感兴趣,这是构建应用程序 imo 的绝佳方式。

例如,如果您的应用程序是经过身份验证的用户的用户仪表板,那么完全不用担心 s-s-r 并只对应用程序进行代码拆分可能会更好。另请注意,由于必须生成标记,因此服务器渲染您的应用程序将花费更多时间在服务器上发送响应(而不是普通的 REST API)。

回答你的问题:

我很困惑代码拆分如何适应 s-s-r 模型,是 s-s-r 呈现第一个命中,然后在客户端上完成代码拆分?

是的,有点。在客户端负责加载必要的位之后,浏览器从服务器接收初始负载。现在,您可能决定在服务器端预加载组件并发送所有内容(请查看我在此答案末尾提到的react-loadable)。

它与服务器上的代码拆分有何不同。如果你去一个特定的路线,那么你是否会在第一次渲染时检索该块?

lazy 只是一个更简洁的 API,支持 Suspense 进行代码拆分。理想情况下,第一次加载路由时,您将服务器渲染初始标记,然后让客户端负责加载下一个位和路由。 Imo Next.js 做得很好。

如果在服务器上完成会有什么不同。

您可以预加载所有组件或仅预加载必要的位。请查看组合代码拆分组件和 s-s-r 部分。

s-s-r 对代码拆分有什么真正的好处吗?它不仅增加了复杂性吗?

在 imo 中,每件事都有自己的取舍。正如我在仅使用代码拆分部分中提到的,如果您的用例不需要 s-s-r 的优点,则仅使用代码拆分是完全可以的。

注意

目前lazy(在 React v16.6.1 中)不完全支持 s-s-r。您可能需要查看react-loadable 来处理您希望在服务器端预加载组件的情况。

【讨论】:

【参考方案2】:

服务器端渲染

对 SEO 重要页面有用

当页面被请求时,服务器处理请求并构建最终的 html 页面,然后将其传递给客户端。

这种方法有利于 SEO 问题页面,因为最终内容在第一个请求中可用,因此搜索引擎能够对其进行索引。

代码拆分

对于内容在不同时间加载的页面很有用

如果您的整个网站在不同的加载时间使用过多的资源,则代码拆分是性能优化的首选技术。您不是在第一次请求时加载所有资源,而是将加载延迟到需要资源为止。

两者同时实现

假设您有一个包含大量资源的网站,并且您希望在将请求的整个页面处理给客户端之前呈现整个页面,您可能希望实现这两种技术。

React.lazy()

React.lazy() 在React v16.6.0 中实现,作为使用Suspense 组件进行代码拆分的新方法。

注意

This feature is not yet available for server-side rendering.
Suspense support will be added in a later release.

总结一下

Suspense + React.lazy() 还不支持服务器端渲染。

服务器端渲染 + 代码拆分允许客户端获取请求的渲染页面,而无需额外的暂时不需要的资源。

【讨论】:

【参考方案3】:

你在这里问了很多问题。在我看来,代码拆分对于较大的应用程序很有用,在这些应用程序中,您构建的包对于单个负载来说太大了。虽然服务器端渲染对于较小的着陆页样式页面很有用,但可以减少浏览器中的计算时间。

【讨论】:

以上是关于react s-s-r 与代码拆分而不是 React.Lazy 的优缺点的主要内容,如果未能解决你的问题,请参考以下文章

Webpack 代码拆分影响 Web 性能

未定义窗口 - react-draft-wysiwyg 与下一个 js (s-s-r) 一起使用

s-s-r:反应应用程序中的动态导入如何在客户端加载组件时处理html未匹配

ReactJS - 超级表达式必须为空或函数,而不是未定义

webpack 代码拆分是不是适用于 react-native?

CORS 和 s-s-r 以及 express、react 和 Axios