使用回应贴靠预渲染路线

未使用服务器端渲染,但仍想提升 React 网站的性能?尝试预呈现!

react-snap 是一个第三方 库,用于将您网站上的网页预呈现为静态 HTML 文件。这可以 提高 首次绘制 次数。

以下对比了同一应用采用预呈现和不采用预呈现的情况 在模拟 3G 连接和移动设备上加载:

<ph type="x-smartling-placeholder">
</ph> 并排加载比较。使用预呈现功能的版本的加载速度提高了 4.2 秒。

为什么搜索渠道报告非常实用?

大型单页应用的主要性能问题是, 用户需要等待构成该网站的 JavaScript 软件包运行完毕 然后才能看到任何真实内容。套装越大, 用户将需要等待更长时间

为了解决这个问题,许多开发者采用 而不是只在浏览器中启动应用对于每个 网页/路线转换时,会在服务器上生成完整的 HTML,并将其发送到 这样可以缩短首次绘制时间,但代价是 Time to First Byte。

预渲染是一项单独的技术,不如服务器复杂 同时又能缩短 应用。使用无头浏览器或没有界面的浏览器 在构建时生成每条路线的静态 HTML 文件。这些文件 然后可与 应用。

回应截取

react-snap使用 Puppeteer 执行以下操作: 在应用中创建不同路由的预渲染 HTML 文件。接收者 首先,将其作为开发依赖项进行安装:

npm install --save-dev react-snap

然后在 package.json 中添加 postbuild 脚本:

"scripts": {
  //...
  "postbuild": "react-snap"
}

每次创建新的 build 时,此操作都会自动运行 react-snap 命令 所做的应用 (npm build)。

您需要执行的最后一项操作是更改应用的启动方式。 将 src/index.js 文件更改为以下内容:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';

ReactDOM.render(<App />, document.getElementById('root'));
const rootElement = document.getElementById("root");

if (rootElement.hasChildNodes()) {
  ReactDOM.hydrate(<App />, rootElement);
} else {
  ReactDOM.render(<App />, rootElement);
}

并非仅使用 ReactDOM.render 来渲染 React 根元素 直接传递到 DOM 中,检查是否已经存在任何子节点 以确定 HTML 内容是否已预呈现(或呈现在 服务器)。在这种情况下,系统会改用 ReactDOM.hydrate 来附加事件 监听器,而不是创建新的 HTML。

现在,构建应用将生成静态 HTML 文件作为 抓取的每个路由。您可以看看 HTML 有效负载是什么样子的 具体方法是点击 HTML 请求的网址,然后点击 Previews 标签页。

前后对比分析。屏幕截图显示内容已渲染。

闪烁无样式的内容

虽然静态 HTML 现在几乎可以立即呈现,但它仍然存在 默认未设置样式 内容”(FOUC)。如果您使用 CSS-in-JS 用于生成选择器的库,因为完成 JavaScript 软件包 才能应用任何样式。

为防止出现这种情况,关键 CSS,也就是 直接内嵌到 <head> HTML 文档。react-snap 会使用 minimalcss,提取任何 不同路由的关键 CSS您可以通过指定 在 package.json 文件中添加以下代码:

"reactSnap": {
  "inlineCss": true
}

现在,在 Chrome 开发者工具中查看响应预览,系统将显示内嵌了关键 CSS 的已设置样式的页面。

前后对比分析。屏幕截图显示内容已渲染,并且因内嵌了关键 CSS 而设置了样式。

总结

如果您的应用中没有服务器端渲染路由,请使用 react-snap,用于向用户预呈现静态 HTML。

  1. 将其作为开发依赖项进行安装,并仅从默认值开始 设置。
  2. 使用实验性 inlineCss 选项内嵌关键 CSS(如果可行的话) 。
  3. 如果您要在任何路由内的组件级别使用代码拆分, 注意不要向用户预呈现加载状态。通过 react-snap 自述文件 我们将对此进行详细介绍