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贊助。