React 项目性能提升:如何避免路由懒加载和图片懒加载导致的慢速问题

前言

在日常的 React 项目开发中,这些错误会让你的项目变慢。实际上如果你熟悉 Vue 项目的开发话,这些道理是相同的。这边文章分析的是路由懒加载和图片懒加载。

路由懒加载

  • 通过 React.lzay() 实现组件的动态加载
  • import() 拆包
  • 优化性能不需要一次加载全部的 js 文件

例子:

1
2
3
4
5
6
7
8
9
10
import { createBrowserRouter, RouterProvider } from "react-router-dom";

import Home from "./pages/Home";

const router = createBrowserRouter([
{
path: "/",
element: <Home />,
},
]);

变成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { createBrowserRouter, RouterProvider } from "react-router-dom";

const Home = React.lazy(() => import("./pages/Home"));

const router = createBrowserRouter([
{
path: "/",
element: (
<Suspense fallback={<>loading....</>}>
<Home />
</Suspense>
),
},
]);

在打包的时候也会根据懒加载而将文件进行分割。减小了首页 JS 文件的大小。

在组件中,对于子组件来说,也是通过lazy导入模块配合Suspense来使用

1
2
3
4
5
6
7
8
9
const Test = React.lazy(() => import("./_components/Test"));

export default function Wrapper() {
return (
<Suspense fallback={<>loading</>}>
<Test />
</Suspense>
);
}

这样不仅会在加载的时候不干扰其他的组件加载,同时还能显示骨架屏。

图片懒加载

为什么要做图片懒加载呢,因为图片资源很多的话,会一直在请求下载,会对网站造成卡顿。所以我们应该暂时不加载那些看不见的图片。

这里用的 JS 自带的IntersectionObserver函数,具体可以去MDN上看他的说明。

这里提供一个封装的 Image 懒加载的组件,以供参考

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
export default function LazyLoad(props: LazyLoadProps) {
const [inView, setInView] = useState(false);
const [ref, setRef] = useState(null);
const fallback = (entries, observer) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
setInView(true);
}
});
};

useEffect(() => {
let observer = new IntersectionObserver(fallback);

if (ref?.current) {
observer.observe(ref.current);
}

return () => {
// if(ref?.current){
// observer.unobserver(ref.current);
// }
observer.disconnect();
};
}, []);

return inView ? (
<img {...props} />
) : (
<img
{...props}
ref={ref}
style={{ width: "1000px", height: "1000px", backgroundColor: "red" }}
/>
);
}