英文:
Lazy Loading in React - improves first page load, but makes all other page loads less smooth because of subsequent loads
问题
在我们的React应用程序的App.js文件中,延迟加载不需要在初始页面加载时使用的组件绝对有助于加快我们第一页的加载速度。然而,这似乎也对网站的其他性能产生了负面影响,因为现在所有延迟加载的页面在用户首次访问各自的页面时仍然需要加载:
const ConfController = lazy(() => import('./containers/StatsPages/Conference/ConfController'));
<Suspense fallback={ourLoadingSpinner}>
<Routes>
<Route exact path='/' element={<HomePage />} />
<Route exact path='/stats/:competitionId/conferences/:conferenceId/:view' element={<ConfController />} />
...
</Routes>
</Suspense>
当用户首次访问ConfController
或其他两打延迟加载的组件之一时,它们会在短短的一瞬间显示ourLoadingSpinner
。我猜这就是延迟加载的权衡吧?初始页面加载速度与每次需要加载延迟加载页面时的这些短暂加载之间的权衡。我几乎觉得我宁愿网站多加载一秒,而不是在所有其他页面上都有这些短暂加载。
我设想有一个中间解决方案,页面不一定在首次访问网站时立即加载(以提高初始加载时间),但这些页面稍后几秒后会在后台加载(以避免每次不同页面首次访问时出现Suspense回退加载)。一些解决方案有益于初始页面加载时间,同时在用户实际访问大多数或所有组件之前加载它们,以避免Suspense回退加载。
英文:
In our React application's App.js file, lazy loading components that are not needed on the initial page load definitely helps with the speed of our first page load. However, it also seems to have a negative impact on the rest of the website's performance, because all of the lazy-loaded pages now still need to be loaded the first time a user visits each respective page:
const ConfController = lazy(() => import('./containers/StatsPages/Conference/ConfController'));
<Suspense fallback={ourLoadingSpinner}>
<Routes>
<Route exact path='/' element={<HomePage />} />
<Route exact path='/stats/:competitionId/conferences/:conferenceId/:view' element={<ConfController />} />
...
</Routes>
</Suspense>
The first time a user visits ConfController
, or any of the other 2-dozen components that are lazy-loaded, they get hit with a brief-but-not-frictionless ourLoadingSpinner
for a fraction of a second. I guess this is the lazy-loading trade-off? Initial page-load speed vs these other minor loads every time a lazy-loaded page finally needs to load. I almost feel like I'd rather the website take an extra second to load, rather than have all of these fraction-of-a-second loads on all other pages.
I'm envisioning a middle ground solution, where pages don't necessarily load immediately the first time the website is visited (to benefit the initial load time), however these pages do get loaded in the background a few seconds shortly later (to avoid the suspense loading fallback every time a different page is visited for the first time). Some solution that is beneficial for our initial page load time, while also loading the components before most or all of them are actually visited by the user, to avoid the Suspense fallback loading.
答案1
得分: 1
"这个解决方案似乎存在重复加载组件的问题,但下面的代码确实可以在导航到ConfController
页面时阻止ourLoadingSpinner
的运行。
const ConfController = lazy(() => import('./containers/StatsPages/Conference/ConfController'));
useEffect(() => {
import('./containers/StatsPages/Conference/ConfController').then(module => {
module.default.preload();
});
}, []);
看起来module.preload();
和module.default.preload();
都可以工作。有人能否找出这个解决方案的任何问题?它似乎为我们提供了快速初始加载时间和没有下游性能负面影响的最佳方案?它只在初始页面加载后/组件挂载后加载懒加载页面吗?
编辑: 在发布上述解决方案时,我们尚未意识到控制台出现了module.default.preload() is not a function
和module.preload()
不是函数的错误。下面使用@loadable/component
npm包的更新代码似乎工作得更好:
import loadable from '@loadable/component';
const ConfController = loadable(() => import('./containers/StatsPages/Conference/ConfController'));
function App() {
useEffect(() => {
ConfController.preload();
}, []);
...
}
"
英文:
It seems duplicative as this solution seems to load the component twice, but the below code does eliminate the ourLoadingSpinner
from running when we navigate to the ConfController
page.
const ConfController = lazy(() => import('./containers/StatsPages/Conference/ConfController'));
useEffect(() => {
import('./containers/StatsPages/Conference/ConfController').then(module => {
module.default.preload();
// module.preload();
});
}, []);
Seems to work with both module.preload();
and module.default.preload();
. Can anyone identify any issues with this solution? It seems like it gives us the best of both quick initial load times, as well as no downstream negative performance? Simply loads the lazy-loaded pages after the initial page-load / after the component has mounted?
Edit: at the time of posting the above solution, we had not realized that we were getting errors in the console for module.default.preload() is not a function
, and module.preload()
is not a function. The following updated code using the @loadable/component
npm package appears to be working better:
// const ConfController = lazy(() => import('./containers/StatsPages/Conference/ConfController'));
import loadable from '@loadable/component';
const ConfController = loadable(() => import('./containers/StatsPages/Conference/ConfController'));
function App() {
useEffect(() => {
ConfController.preload();
}, []);
...
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论