React ESI是用于Vanilla React和Next.js应用程序的超级强大的高速缓存库,可以使高度动态应用程序与静态站点一样快。
它通过将服务器端渲染页面的片段存储在Edge Cache服务器中,提供了一种直接的方法来提高应用程序的性能。
这意味着,在第一个渲染之后,您的页面片段将由您最终用户附近的服务器以几毫秒的方式提供!
这是提高网站的性能和SEO并大大降低托管成本和这些应用程序能耗的非常有效的方法。帮助地球,使用React Esi!
因为它是在边缘侧的顶部构建的,包括(ESI)W3C规范,因此ESI本身支持大多数著名的云高速缓存提供商,包括Cloudflare工人,Akamai和Farty。当然,React ESI还支持您可以在自己的基础架构中免费使用的开源清漆缓存服务器(配置示例)。
另外,React ESI允许每个React组件的不同时间(TTL)指定,并使用安全(签名)URL使用相应的HTML异步生成相应的HTML。缓存服务器在缓存中获取并存储所有所需的片段(与每个React组件相对应的HTML),构建最终页面并将其发送到浏览器。 React ESI还允许组件(重新)渲染客户端,而无需任何特定的配置。
清漆书中的模式
在此演示文稿中深入探讨ESI
使用NPM:
$ npm install react-esi
或使用纱线:
$ yarn add react-esi
或使用PNPM:
$ pnpm add react-esi
React ESI提供了一个方便的高阶组件,将:
React ESI自动称为名为getInitialProps()的static async方法,以填充组件的初始道具。服务器端,此方法可以访问HTTP请求和响应,例如,设置Cache-Control标头或一些缓存标签。
这些由getInitialProps()返回的道具也将被注入服务器端生成的HTML( <script> tag)中。客户端该组件将重复使用来自服务器的道具(该方法将不会第二次称为)。如果该方法尚未称为服务器端,则在第一次安装组件时将其称为客户端。
// pages/App.jsx
import withESI from "react-esi/lib/withESI" ;
import MyFragment from "../components/MyFragment" ;
const MyFragmentESI = withESI ( MyFragment , "MyFragment" ) ;
// The second parameter is an unique ID identifying this fragment.
// If you use different instances of the same component, use a different ID per instance.
export const App = ( ) => (
< div >
< h1 > React ESI demo app </ h1 >
< MyFragmentESI greeting = "Hello!" />
</ div >
) ; // components/MyFragment.jsx
import React from "react" ;
export default class MyFragment extends React . Component {
render ( ) {
return (
< section >
< h1 > A fragment that can have its own TTL </ h1 >
< div > { this . props . greeting /* access to the props as usual */ } </ div >
< div > { this . props . dataFromAnAPI } </ div >
</ section >
) ;
}
static async getInitialProps ( { props , res } ) {
return new Promise ( ( resolve ) => {
if ( res ) {
// Set a TTL for this fragment
res . set ( "Cache-Control" , "s-maxage=60, max-age=30" ) ;
}
// Simulate a delay (call to a remote service such as a web API)
setTimeout (
( ) =>
resolve ( {
... props , // Props coming from index.js, passed through the internal URL
dataFromAnAPI : "Hello there" ,
} ) ,
2000
) ;
} ) ;
}
}必须使用JSON.stringify()可以序列化初始道具。当心Map , Set和Symbol !
注意:为方便起见, getInitialProps()具有与下一个签名相同的签名。但是,这是一个完全独立且独立的实现(您不需要Next.js即可使用它)。
为了服务片段,React ESI提供了与Express兼容的现成控制器,请查看完整示例。
另外,这是使用next.js服务器的完整示例:
可以使用环境变量配置ESI:
REACT_ESI_SECRET :用于签署片段URL的秘密键(默认为随机字符串,强烈建议将其设置以防止服务器重新启动时或使用多个服务器时)REACT_ESI_PATH :用于生成片段的内部路径不应公开暴露(默认: /_fragment ) <esi:include>元素要将属性传递给<esi:include>元素,将具有以下结构的支柱传递给HOC:
{
esi : {
attrs : {
alt : "Alternative text" ,
onerror : "continue"
}
}
} 默认情况下,包括清漆在内的大多数高速缓存代理,如果请求包含cookie,则切勿提供缓存的响应。如果您使用localhost或类似的本地域进行测试,请清除此来源的所有预先存在的cookie 。如果期望cookie(例如:Google Analytics(分析)或广告cookie),则必须配置正确的高速缓存代理才能忽略它们。这是清漆的一些示例。
为了允许客户端应用程序重复使用所获取或计算的服务器端的道具,React ESI注入<script>标签包含ESI片段中的标签。通过缓存服务器组装页面后,这些脚本标签最终与合法HTML混合在一起。在渲染阶段之前,这些标签会自动从DOM中删除。
ESI对高级缓存策略的表现非常出色,包括:
试试看!
我们喜欢Vue和Nuxt和React和Nuct,因此我们目前正在为此平台移植ESI。如果您想提供帮助,请与我们联系!
由KévinDunglas创建。由les-tilleuls.coop赞助。