最近再写一个后台管理系统,品是我们一般设计后台管理的话一个页面就一张大表,这个是惯例,就按惯例的话懒加载我们一般在路由管理那儿处理就可。类似于这样:
import React, { Children, lazy, Suspense } from 'react';
const Home = lazy(() => import('../views/Home'));
const Login = lazy(() => import('../views/Login'));
const NotFound = lazy(() => import('../views/NotFound'));
// 懒加载的模式 需要添加一个loading的模式
// 懒加载的模式的组件的写法,需要套一层Loading的提示加载组件
const HomePage = lazy(() => import('../views/home/index'));
const withLoadingCompoent = (comp: JSX.Element) => (
<React.Suspense fallback={<div>Loading...</div>}>{comp}</React.Suspense>
);
const routes = [
{
path: '/',
element: <Navigate to="/home/page" />,
},
{
path: '/login',
element: <Login />,
},
{
path: '/home',
element: <Home />,
breadcrumb: '首页',
children: [
{
path: 'page',
breadcrumb: 'page',
element: withLoadingCompoent(<HomePage />),
},
],
},
.........路由太多省略
这样路由跳转就不会太卡顿了,后来页面出现卡顿了,我怪罪于react的性能不好(因为我在一个页面里面做了五六七八张表格,即使没有数据,光渲染也会卡奔溃的。)后来越想越不对劲,不应该这么卡。
打开调试窗口debuge调试半天,后来发现页面跳转是没问题,问题就出现在渲染上了,果然一看吓一跳,他一次渲染的页面的高度就达到了56千的像素,怪不得会卡,发现问题:页面一次渲染太多内容了。但我确实应该有这么多数据啊?这使我想起瀑布流的这个案例,与这个有相同点。找到问题解决问题就简单很多了,代码如下:
// 视口懒加载组件
import React, { Suspense } from 'react';
import { useInView } from 'react-intersection-observer';
const LazyLoad = ({ children }: { children: React.ReactNode }) => {
const { ref, inView } = useInView({
triggerOnce: true, // 只触发一次
threshold: 0.9, // 视口渲染阈值
});
return (
<div ref={ref}>
{inView ? (
<Suspense>
{children}
</Suspense>
) : (
<div style={{ minHeight: '200px' }} /> // 占位符
)}
</div>
);
};
export default LazyLoad;
这里我使用了一个插件”react-intersection-observer“,直接安装像我一样使用就行。他会自动监听组件在没在视口内然后决定渲染。
使用的话像我这样
<LazyLoad>
<MyTable title="全国景点排行" data={data1} columns={columns1} showSelect={false}></MyTable>
</LazyLoad>
引入这个组件,用它包裹住需要处理的页面组件。好了bug解决!事实上这样解决还是不够雅观,因为我有太多的页面组件了,每个组件都这样被相同的工具给包裹起来很不自在,如果你觉得有更好更雅观的解决方案请和我一起讨论