react-snap 学习笔记
react-snap
react-snap是第三方库,可将您网站上的页面预先呈现为静态HTML文件. 这样可以缩短应用程序中 “首次绘画” 的时间.
这是在模拟3G连接和移动设备上加载和不加载预渲染的相同应用程序的比较:
官方资料
react-snap不是唯一可以为您的React应用程序预渲染静态HTML内容的库. react-snapshot是另一种选择.
为什么使用它?
大型单页应用程序的主要性能问题是,用户需要等待组成网站的JavaScript包完成下载,然后才能看到任何实际内容. 捆绑包越大,用户必须等待的时间就越长.
为了解决这个问题,许多开发人员采取了在服务器上呈现应用程序的方法,而不仅仅是在浏览器中启动它. 每次页面/路由转换时,完整的HTML都会在服务器上生成并发送到浏览器,这虽然减少了"首次绘制"的时间,但代价是"到达第一个字节的时间变慢了".
预渲染是一种独立的技术,它不比服务器渲染复杂,但也提供了一种缩短应用程序中"首次绘画"时间的方法. 无头浏览器或没有用户界面的浏览器用于在构建期间生成每条路线的静态HTML文件. 然后可以将这些文件与应用程序所需的JavaScript捆绑包一起提供.
react-snap
react-snap使用Puppeteer在应用程序中创建不同路径的预渲染HTML文件.
首先,将其安装为开发依赖项:
npm install --save-dev react-snap
然后在您的package.json添加一个postbuild脚本:
"scripts": {
//...
"postbuild": "react-snap"
}
This would automatically run the react-snap command everytime a new build of the applications made (npm build).
npm支持主脚本和任意脚本的前命令和后命令,它们始终分别直接在原始脚本之前或之后直接运行. 您可以在npm文档中了解更多信息 .
您需要做的最后一件事是更改应用程序的启动方式. 将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请求的URL,然后单击Chrome DevTools中的" 预览"标签来查看HTML有效负载的外观.
react-snap可以用于React以外的其他框架! 这包括Vue和Preact. 更多相关说明可以在react-snap README中找到 .
Flash of unstyled content
尽管静态HTML现在几乎可以立即呈现,但是默认情况下仍保持未样式化,这可能会导致显示"样式样式内容闪烁"(FOUC)的问题. 如果您使用CSS-in-JS库来生成选择器,则这一点尤其明显,因为JavaScript包必须在应用任何样式之前完成执行.
为了避免这种情况,可以将关键的 CSS或呈现初始页面所需的最少CSS量直接内联到HTML文档的
中. react-snap使用另一个第三方库minimalcss提取用于不同路由的任何关键CSS. 您可以通过在package.json文件中指定以下内容来启用此功能:"reactSnap": {
"inlineCss": true
}
现在,看看Chrome DevTools中的响应预览,将显示带有内联关键CSS的样式页面.
警告: inlineCSS选项仍处于试验阶段. 值得仔细检查以确保为您的路线正确应用样式.
Conclusion
如果您不是应用程序中的服务器端呈现路线,请使用react-snap
将静态HTML预呈现给用户.
- 将其安装为开发依赖项,并仅从默认设置开始.
- 如果实验性inlineCss选项适用于您的网站,请使用它来内嵌关键CSS.
- 如果要在任何路线中的组件级别上使用代码拆分,请注意不要将加载状态预先呈现给用户. react-snap自述文件对此进行了详细介绍.