🧠 新的 React 和旧的缓存 Rapscallion electro-react-ssr-caching 安装使用 React 服务器端渲染优化库 React 组件缓存 React 预渲染组件

2025-06-10

🧠 新的 React 和旧的缓存

恶棍

电极反应-ssr-缓存NPM 版本 构建状态 依赖状态

安装

用法

React 服务器端渲染优化库

React 组件缓存

React 预渲染组件

React 🚀 快,还是 🐌 慢?这个问题的答案非常简单,无需思考。

  • React 很快,仅此而已。React 的速度取决于它所能达到的极致:不会显示太多数据,也不会以每秒 60 帧的速度进行动画。总有更快的对手(比如 Svelte?),但 React 的速度几乎足以应对任何情况。
  • React 很慢。再说一遍。让它变慢没什么大不了的——内联 1000 个 SVG 并用 React 全部渲染,或者在服务器端同时渲染 100 个页面。

简而言之 - React 作为客户端库是 👍 的,但作为服务端渲染 - 哦,🔥它会消耗你的 CPU 和 AWS 账单。不是因为它慢,而是因为万事皆有局限。

这是显而易见的 - 您无法比较所有 CPU 都为一个客户(在浏览器中)工作的情况,以及您必须同时为十几个客户端渲染相同内容的情况。

缓解这个问题的方法也显而易见——它以生成而闻名,而对于 React 本身来说,它的核心思想是处理不必要的更新——记忆化。或者,用老式的 SSR 来解释——就是缓存
缓存小块,缓存大块,缓存页面、数据和中间结果。尽可能多地缓存,让一个客户的渲染结果加快另一个客户的渲染速度。

缓存是一种众所周知的模式,它总是能节省时间!几十年来!对每个人来说都是如此!除了 React。

React 天

那么,React 中缓存是怎么回事?你还记得它的 API 吗?不,你不记得了。根本没有。

您仍然可以缓存renderToString结果 - 没什么大不了的,或者mxstbr去年为 Spectrum 所做的那样进行缓存。renderToNodeStream

但是我们需要缓存吗?

是的——React 15 确实很慢,而 React 16 即使速度快了很多,也仍然需要一些时间来渲染结果。
任何事情都需要时间。一切都有要求和限制。

React 中的缓存

只要问题存在,就会有许多开发人员利用缓存背景(来自以前使用不同框架或语言的经验)来解决它——新的模式和库就会出现。

恶棍

React-DOM 的替代方案。我们的英雄。节省了数百万 CPU 周期。能够在组件级别处理数据加载,并缓存结果。

完美运行。直到 React 16 才生效。之后就失效了。

GitHub 徽标 FormidableLabs / rapscallion

用于 SSR 的异步 React VirtualDOM 渲染器。

恶棍

CircleCI 加入聊天:https://gitter.im/FormidableLabs/rapscallion

概述

Rapscallion 是一个用于服务器的 React VirtualDOM 渲染器。其显著特点如下:

  • 渲染是异步且非阻塞的
  • Rapscallion比大约快 30%renderToString
  • 它提供了一个流式接口,以便您可以立即开始向客户端发送内容
  • 它提供了一个模板功能,这样你就可以将组件的 HTML 包装在样板中,而无需放弃流媒体的好处。
  • 它提供了组件缓存API 来进一步加快您的渲染速度。

目录

安装

使用 npm:

$ npm install --save rapscallion
Enter fullscreen mode Exit fullscreen mode

在 Node.js 中:

const {
  render,
  template
} = require("rapscallion");

// ...
Enter fullscreen mode Exit fullscreen mode

API

render

render(VirtualDomNode) -> Renderer

此函数返回一个 Renderer,一个用于渲染 VirtualDOM 元素的接口。其方法列举如下。


Renderer#toPromise

另一个很棒的组件级缓存工具。另一个侵入 React 并试图改变其工作方式的工具。然而,它不支持 React 16

GitHub 徽标 电极-io /电极-反应-ssr-缓存

通过分析和组件缓存优化 React SSR

电极反应-ssr-缓存NPM 版本 构建状态 依赖状态

支持分析 React 服务器端渲染时间和组件缓存,以帮助您加快 SSR 速度。

安装

npm i electrode-react-ssr-caching

用法

请注意,由于此模块修补了 React 的源代码以注入缓存逻辑,因此必须在 React 模块之前加载它。

例如:

import SSRCaching from "electrode-react-ssr-caching";
import React from 'react';
import ReactDOM from 'react-dom/server';
Enter fullscreen mode Exit fullscreen mode

分析

您可以使用此模块检查每个组件渲染所花费的时间。

import SSRCaching from "electrode-react-ssr-caching";
import { renderToString } from "react-dom/server";
import MyComponent from "mycomponent";
// First you should render your component in a loop to prime the JS engine (i.e: V8 for NodeJS)
for( let i = 0; i < 10; i ++ ) {
    renderToString(<MyComponent />);
}

SSRCaching.clearProfileData();
SSRCaching.enableProfiling();
const html
Enter fullscreen mode Exit fullscreen mode

React-SSR 优化

沃尔玛实验室开发的用于记忆模板化的神奇系统。在 React 14-15 迁移期间曾出现故障,并且未获得 React 16支持。

GitHub 徽标 walmartlabs / react-ssr-optimization

使用组件记忆和模板化进行 React.js 服务器端渲染优化

React 服务器端渲染优化库

这个 React 服务器端优化库是一个可配置的 ReactJS 扩展,用于在服务器上记忆 React 组件标记。它还支持组件模板化,以便进一步缓存渲染标记和更多动态数据。该服务器端模块使用钩子拦截 React 的 instantiateReactComponent 模块require(),避免 React 的 fork。

构建状态 版本 执照

我们为何建造它

React 是一个一流的 UI 组件框架,它使我们能够构建可跨页面和应用共享和复用的高级组件。React 的虚拟 DOM 提供了卓越的开发体验,使我们无需管理细微的 DOM 更改。最重要的是,React 为我们提供了一个出色的开箱即用的同构/通用 JavaScript 解决方案。ReactrenderToString(..)可以将页面的 HTML 标记完整地渲染为服务器端的字符串。这对于初始页面加载性能(尤其是对于带宽较低的移动用户)以及搜索引擎索引和排名尤为重要……

React-组件缓存

TLDR:实际上是一个有效的!

GitHub 徽标 rookLab / react-component-caching

React 16 中的组件缓存可实现更快的服务器端渲染

React 组件缓存

概述

React Component Caching 是一个组件级缓存库,用于使用 React 16 实现更快的服务器端渲染。

  • 使用 React 的四种服务器端渲染方法中的任意一种。渲染是异步的
  • 使用简单或模板策略缓存组件。
  • 从三种缓存实现(LRU、Redis 或 Memcached)中进行选择。

安装

使用 npm:

$ npm install react-component-caching
Enter fullscreen mode Exit fullscreen mode

用法

在 Node 渲染服务器中:

实例化一个缓存并将其作为第二个参数传递给任意渲染方法(renderToStringrenderToStaticMarkuprenderToNodeStreamrenderToStaticNodeStream)。无论在哪里使用ReactDOM.renderToString,都请使用ReactCC.renderToString

注意:所有这些方法都是异步的,并返回一个 Promise。要使用它们,await请在渲染之前

const ReactCC = require("react-component-caching");
const cache = new ReactCC.ComponentCache();
app.get('/example', async (req,res) => {
    const renderString = await ReactCC.
Enter fullscreen mode Exit fullscreen mode

React 16 使用组件缓存实现更快的服务器端渲染

Sasha Aickin在 2016 年的一次关于加速服务器端渲染方法的演讲中介绍并演示了组件缓存。此后不久,沃尔玛实验室创建了一个组件缓存库,该库具有用于计时渲染的分析功能。这个想法在去年的React Amsterdam上引起了关注,并在 Github 上的讨论中浮出水面。Formidable 的 React 服务器渲染器Rapscallion中也加入了组件缓存 API 。
随着去年 9 月 React 16 的发布,许多此类工作都需要重新启动。React 提高了其服务器端渲染方法的速度,现在提供两种流式传输方法。我们很好奇是否可以通过这些新的和改进的方法利用组件缓存的强大功能。因此,我们构建了React Component Caching,让开发人员能够做到这一点。


但是,你知道,这个库内部相当复杂,在下一个 React 版本中肯定会崩溃——100%。而且面向用户的 API 也相当复杂……但它确实能用,能和 memcache 或其他缓存库协同工作,并且一直是我们的救星……直到今天。

React-Prerendered-Component

那么,让我来介绍一下 React 中组件级缓存的另一种方法,这种方法永远不会被破坏。从设计上来说永远不会。

import {CachedLocation, NotCacheable} from 'react-prerendred-component';

const MyCachedComponent = () => (
  <CachedLocation cacheKey="MyCachedComponent">
    any code you want
  </CachedLocation>
);

// component like this shall not be cached.
const SomeNonPureImportantComponent = () => (
 <NotCacheable>hey {global.userName}</NotCacheable>
);
Enter fullscreen mode Exit fullscreen mode

简单吗?容易吗?它是如何运作的?

工作原理

  1. CachedLocation将用以下方式包装您的组件<x-cached-store>{children}<x-cached-store>
  2. 的结果renderToString将被分析是否存在此类标记,并且标记的内容将被移入缓存。renderToStream同样的操作是通过 进行的transform streams
  3. 如果key在存储中存在,那么CachedLocation就会渲染<x-cached-restore-key />,并且相同的后置过滤器会用存储的值替换该文本。

这在 HTML/流转换级别上起作用,并且不依赖于任何 React 内部结构

客户端也一样CachedLocation它只会用 包装你的数据,div然后使用 来存储/恢复数据dangerouslySetInnerHTML。例如,你可能会缓存那些我在一开始提到的大型 SVG 文件。

<CachedLocation cacheKey="svg-fileName">
  // react component first time, just a string second.
  <MySVRGComponent />
</CachedLocation>

renderToString(...);

// - first render, cache is empty, making a full render
// <x-cached-store-1><svg..../></x-cached-store-1>
// - cache stored, extra tags removed
// <svg .../> 

renderToString(...);

// - second render, cache exists - restore entity
// <x-cached-restore-1/>
// - we know what to restore
// <svg ...
Enter fullscreen mode Exit fullscreen mode

虽然CachedLocation在渲染过程中添加了额外的标签,但它们稍后会被移除。这是一个透明的过程!

它是完全基于纯 HTML 的解决方案,在React 完成工作后即可发挥作用。

XSS 我的朋友?

所以 - 让我们再回想一下 -CachedLocation将在结果 HTML 中放入一些tag,而一些虚拟的(它是)RegEx 将完成剩下的工作。

如果你亲爱的客户也这么做了怎么办?如果tagJSON、脚本以及反之亦然,也会出现同样的情况怎么办?当然,那就糟了:P

所以,在实际应用中,这个库不会使用如此明显的标签名称,而是会使用nanoid在每次渲染时生成唯一的标签名称。这样,就不会出现 XSS 漏洞和误报,放心吧。

<x-cached-supersecretstring-11 /> // it's "safe"
Enter fullscreen mode Exit fullscreen mode

唯一的问题是,现在在不同线程中生成的缓存彼此不兼容,因此在分布式缓存的情况下,您必须super-secret-seed自己指定。

模板化

这是一个很长的术语,可能不太正确,代表较少变化的记忆。

例如,标题dev.to包含你的头像,但其他内容相同,你可以将其“模板化”到静态和缓存中<Header/>。如果你按用户缓存标题,会发生什么?嗯,缓存不是无限的。

图片来自Scaling React 服务器端渲染

<Button>unuqieText</Button>您可能不需要拥有 100500 个不同的变量<Button>#text#</Button>- 因此您将只记住复杂的 html 标记,并使用简单的方法添加一些“变量” replace

虽然使用字符串替换并不十分安全,但这个库为您提供了一些组件来注入占位符,它使用 Context API 来深入研究 props,并且只需要进行少量的代码样式更改即可使用。

const UserHeader = () => (
 <div>
   .....
   <Placeholder name="userName"/>
   ....
 </div>
)

renderToString(<CacheLocation variables={{userName:'Joe'}}><UserHeader/></CacheLocation>);

// <x-cached-store-1 userName="Joe">....{x-cached-placeholder-userName}...</x-cached-store-1>

renderToString(<CacheLocation variables={{userName:'Jack'}}><UserHeader/></CacheLocation>);

// <x-cached-restore-1 userName="Jack"/>
// ....{x-cached-placeholder-userName}...
// ....Jack...
Enter fullscreen mode Exit fullscreen mode

这是一个非常强大的策略,通过将全新的 React App 转换为旧式模板引擎,可以减少内存使用量并使您的应用程序性能飞速提升

这真是🚀非常🚀快🚀。

附言:这可以实现亚毫秒级的服务器端渲染 (SSR),react-component-caching这一点已经得到证实。
附言:但这还不适用客户端缓存。使用变量进行 CSR 缓存会禁用缓存。

该技术的另一个名称是缓存interpolation,如果您想真正了解片段缓存背后的一切,请阅读文章

缓存在哪里?

这种方法的另一个很酷的时刻是cache。一个简单的 React 16/Suspense 兼容缓存模型。

  • 同步get缓存
  • 同步set缓存。
  • 没有可用的缓存?——抛出一个承诺!

您不能使用react-cache,只要它使用不同的模型(没有set),但任何其他缓存,包括内存或共享内存的缓存 - 都很简单。

但不是memcache,只要不支持异步缓存。

预渲染组件为您提供了组件的功能memoization,并且templatization适用于服务器和客户端,并且将来不会中断,因为它就是这样构建的 - 永远不会让您失望。

尝试一下,
或者只是想想。

GitHub 徽标 theKashey / react-prerendered-component

🤔悬念时代之前的局部补水和缓存

React 预渲染组件



部分水合和组件级缓存







主意

简而言之:不要尝试运行JS 代码,并生成与预渲染树匹配的 React 树,而是使用预渲染的 HTML,直到 JS 代码准备好替换它。让它上线。

HTML 层面还能做什么?缓存、模板化,以及其他好东西🚀,只占 3kb*。

预渲染组件

在服务器上渲染某些内容,并在客户端将其用作 HTML

  • 服务器端渲染数据
    • 呼叫thisIsServer某处来设置环境。
    • React-prerendered-component will leave trails,用已知id 的 div 包裹每个块。
  • 客户端保湿
    • React-prerendered-component 将搜索已知的ID,然后read rendered HTML从页面返回。
  • 您的网站已准备就绪
    • React-prerendered-components 已准备就绪。它们正在渲染你从服务器发送的预先存在的 HTML。
  • 一旦任何组件准备更换 - 水合物
    • 但在此之前不行。这就是重点……

PS:顺便说一下,react-prerendered-component 是另一篇文章的英雄:

鏂囩珷鏉ユ簮锛�https://dev.to/thekashey/a-new-react-and-the-old-cache-15h5
PREV
开始使用 ES6 数组方法 .filter()、.map() 和 .reduce() JavaScript 数组资源管理器
NEXT
使用 --patch git add --patch 升级你的 git 游戏