🧠 新的 React 和旧的缓存
恶棍
电极反应-ssr-缓存
安装
用法
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 才 生效。之后就失效了。
用于 SSR 的异步 React VirtualDOM 渲染器。
恶棍
概述
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 。
支持分析 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 支持。
使用组件记忆和模板化进行 React.js 服务器端渲染优化
React 服务器端渲染优化库
这个 React 服务器端优化库是一个可配置的 ReactJS 扩展,用于在服务器上记忆 React 组件标记。它还支持组件模板化,以便进一步缓存渲染标记和更多动态数据。该服务器端模块使用钩子拦截 React 的 instantiateReactComponent 模块 require()
,避免 React 的 fork。
我们为何建造它
React 是一个一流的 UI 组件框架,它使我们能够构建可跨页面和应用共享和复用的高级组件。React 的虚拟 DOM 提供了卓越的开发体验,使我们无需管理细微的 DOM 更改。最重要的是,React 为我们提供了一个出色的开箱即用的同构/通用 JavaScript 解决方案。React renderToString(..)
可以将页面的 HTML 标记完整地渲染为服务器端的字符串。这对于初始页面加载性能(尤其是对于带宽较低的移动用户)以及搜索引擎索引和排名尤为重要……
React-组件缓存
TLDR:实际上是一个 有效 的!
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 渲染服务器中:
实例化一个缓存并将其作为第二个参数传递给任意渲染方法( renderToString
、 renderToStaticMarkup
、 renderToNodeStream
或 renderToStaticNodeStream
)。无论在哪里使用 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
简单吗?容易吗?它是如何运作的?
工作原理
CachedLocation
将用以下方式包装您的组件 <x-cached-store>{children}<x-cached-store>
的结果 renderToString
将被分析是否存在此类标记,并且标记的内容将被移入缓存。 renderToStream
同样的操作是通过 进行的 transform streams
。
如果 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 将完成剩下的工作。
如果你亲爱的客户也这么做了怎么办?如果 tag
JSON、脚本以及反之亦然,也会出现同样的情况怎么办?当然, 那就糟了 :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
适用于服务器和客户端,并且将来不会中断,因为它就是这样构建的 - 永远不会让您失望。
尝试一下, 或者只是想想。
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