Published on

React渲染模式 —— 客户端渲染

Authors
  • avatar
    Name
    Deng Hua
    Twitter

文章翻译至: Client-side Rendering

目录

Client-side Rendering

在客户端渲染 (CSR) 中,服务器仅渲染应用挂载的 根Root HTML节点。而在页面上显示内容所需的逻辑、数据获取、模板和路由在浏览器/客户端中执行的 JavaScript 代码都将在本地处理。

CSR 作为一种构建单页应用程序的方法变得流行起来。它有助于模糊网站和已安装应用程序之间的区别。

为了更好地理解其他模式提供的好处,让我们首先更深入地了解客户端渲染 (CSR),并找出它在哪些情况下效果很好,哪些是它的缺点。

基本结构

考虑这个使用 React 在页面上显示和更新当前时间的简单示例。

<div id="root"></div>
function tick() {
  const element = (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {new Date().toLocaleTimeString()}.</h2>
    </div>
  );
  ReactDOM.render(element, document.getElementById("root"));
}

setInterval(tick, 1000);

HTML 仅包含一个root <div> 标记。另一方面,内容显示和更新完全由 JavaScript 处理。渲染的 HTML 也是在本地更新。

这里的时间信息也可以被任何其他实时信息所取代,例如从 API 获取的汇率或股票价格,这些数据都无需刷新页面即可显示。

JavaScript 包和性能

随着显示图像、显示数据存储中的数据以及包括事件处理的页面复杂性增加,渲染页面所需的 JavaScript 代码的复杂性和大小也会增加。 CSR 导致大量 JavaScript bundle,从而增加了页面的 FCP 和 TTI。

如上图所示,随着bundle.js大小的增加,FCP和TTI的时间被向前推。这意味着用户将在 FP 和 FCP 之间的整个持续时间内看到空白屏幕。

优点和缺点

使用 React,大部分应用程序逻辑都在客户端执行,并通过 API 调用与服务器交互以获取或保存数据。

几乎所有的 UI 都是在客户端生成的。整个 Web 应用程序在发出第一个请求时开始加载。当用户通过单击链接进行导航时,不会向服务器生成用于渲染页面的新请求。该代码在客户端上运行以更改UI/数据。

CSR 使我们能够拥有一个单页应用程序,该应用程序支持无需刷新页面的导航,并提供出色的用户体验。由于为更改视图而处理的数据有限,页面之间的路由通常会更快,从而使 CSR 应用程序看起来响应更快。 CSR 还允许开发人员实现客户端和服务器代码之间的明确分离。

尽管它提供了出色的交互体验,但此 CSR 仍存在一些缺陷。

  1. SEO

大多数网络爬虫可以直接解析服务端渲染的网站。在客户端渲染的情况下,事情会变得稍微复杂,因为大的负载和网络请求的瀑布(例如 API 响应)流可能会导致有意义的内容渲染速度不够快,无法让爬虫对其进行索引。爬虫可能理解 JavaScript,但也有局限性。因此,需要一些解决方法来使客户端渲染的网站 SEO 友好。

  1. 性能

通过客户端渲染,交互期间的响应时间大大缩短,因为没有与服务器的往返。然而,浏览器第一次在客户端渲染内容时,必须等待 JavaScript 首先加载并开始处理。因此,用户在初始页面加载之前会遇到一些延迟。随着 JS 包的大小变大和/或客户端没有足够的处理能力,这可能会影响用户体验。

  1. 代码可维护性

某些代码元素可能会在不同语言的客户端和服务器 (API) 之间重复。在其他情况下,业务逻辑的干净分离可能是不可能的。这方面的示例可能包括货币和日期字段的验证和格式化逻辑。

  1. 数据获取

在客户端渲染中,数据获取通常是事件驱动的。该页面最初可以在没有任何数据的情况下加载。随后可以使用 API 调用在页面加载或按钮单击等事件发生时获取数据。根据数据的大小,这可能会增加应用程序的加载/交互时间。

这些考虑因素的重要性可能因应用程序而异。开发人员通常有兴趣寻找 SEO 友好的解决方案,可以更快地提供页面服务,而不影响交互时间。根据应用要求,分配给不同性能标准的优先级可能不同。有时,使用客户端渲染进行一些调整可能就足够了,而不是采用完全不同的模式。

由于 CSR 的性能与 JavaScript 包的大小成反比,因此我们能做的最好的事情就是构建 JavaScript 代码以获得最佳性能。以下是可能有帮助的指南列表。

  • JavaScript包临界大小

确保初始页面加载的 JavaScript 有一个合适的大小。压缩和压缩后小于 100-170KB 的初始包是一个很好的起点。然后可以根据需要的功能按需加载代码

  • 预加载

此技术可用于在页面生命周期的早期预加载页面所需的关键资源。关键资源可能包括 JavaScript,可以通过在 HTML 的 <head> 部分中包含以下指令来预加载 JavaScript。

<link rel="preload" as="script" href="critical.js" />

这通知浏览器在页面渲染机制启动之前开始加载 critical.js 文件。因此,脚本将更早可用,并且不会阻塞页面渲染机制,从而提高性能。

  • 延迟加载

通过延迟加载,您可以识别非关键资源并仅在需要时加载这些资源。使用此方法可以缩短初始页面加载时间,因为初始加载的资源大小会减少。例如,聊天小部件组件通常不会在页面加载时立即需要,并且可以延迟加载。

  • 代码拆分

为了避免大量 JavaScript 代码,您可以开始拆分代码包。 Webpack 等bundle支持代码分割,可用于创建可在运行时动态加载的多个bundle包。代码分割还使您能够延迟加载 JavaScript 资源。

  • 使用 Service Worker 进行应用程序 shell 缓存

此技术涉及缓存应用程序 shell,它是支持用户界面的最小 HTML、CSS 和 JavaScript。 Service Worker 可用于离线缓存应用程序 shell。这对于提供本机单页应用程序体验非常有用,其中剩余内容根据需要逐步加载。


通过这些技术,CSR 可以帮助提供更快的单页应用程序体验以及良好的 FCP 和 TTI。接下来,我们将了解服务器端渲染的另一端可用的功能。

End.