我正在開發一個包含許多不同頁面的 React 應用程式。隨著我的頁數增加,我的包大小也增加了,所以我試圖將我們的路由拆分成它們自己的包,這些包可以在頁面完成渲染后加載。
我的第一次嘗試是使用React.lazy(),但這導致了糟糕的用戶體驗。當用戶進入一個新頁面時,頁面頁腳(我們的應用程式外殼的一部分)會搶到螢屏頂部,只是被延遲加載的內容推回。
我正在尋找的是這些組件的異步加載,但不是延遲加載。換句話說,在主要內容之后但在需要它們之前加載它們。理想情況下,我能夠做到:
import Page1 from "./Page1"; // Landing page that needs to pop up immediately
const Page2 = import("./Page2");
function AppShell () {
return (
<Switch>
<Route path="/"><Page1/></Route>
<Route path="/page2"><Page2/></Route>
</Switch>
)
}
但是 React 不喜歡未解決的 Promise 作為組件定義。有沒有辦法做到這一點?或者有沒有更標準的方法來處理這個閃爍的問題?
uj5u.com熱心網友回復:
您可以使用 React suspense 回退到占據整個視口的加載指示器。這將防止在您的應用程式加載延遲加載的組件時發生閃爍。
例如:
const LazyPage = (Component) => (props) => (
<React.Suspense fallback={<FullPageSpinner />}>
<Component {...props} />
</React.Suspense>
)
const LazyLoadedPage = LazyPage(React.lazy(() => import('/path/to/component/'));
然后,您可以在樹中呼叫 LazyLoadedPage,就好像它是一個普通組件一樣。
uj5u.com熱心網友回復:
昨天我想到了一種新的方式來表達我的問題,果然,有答案!我將分享我最終做了什么,然后解釋我是如何得到答案的。
它最終像包裝一樣簡單React.lazy():
const lazyWithPrefetch = (factory) => {
factory();
return lazy(factory);
};
此函式將包裝動態匯入的函式作為引數,例如() => import("./Page1.js"). 然后在回傳呼叫之前呼叫該函式,觸發網路請求React.lazy()。因為動態匯入是異步的,所以這不會阻止任何事情。
我從React.lazy 和 prefetching components中得到了靈感。Yash Joshi 的回答包括這個代碼塊:
function lazyWithPreload(factory) {
const Component = React.lazy(factory);
Component.preload = factory;
return Component;
}
const ComponentToPreload = lazyWithPreload(() => import("./Component"));
/* usage in Component */
ComponentToPreload.preload(); // this will trigger network request to load the component
將預取轉換為方法會很有幫助,讓您可以將其系結到 DOM 事件,例如單擊或懸停。
在我的用例中,我不需要那種粒度,每個組件有兩個函式呼叫(一個用于分配它,一個用于預取它)感覺很混亂。
此外,這是對包含大量匯入的現有專案的重構,因此我希望將更改保持在最低限度,以避免整個上午都進行復制和粘貼。這就是我最終將預取放在包裝函式中的方式。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/411876.html
標籤:
