前端代码分割与懒加载:让你的应用飞起来

前端代码分割与懒加载:让你的应用飞起来

毒舌时刻

代码分割和懒加载?听起来就像是前端工程师为了掩饰自己代码写得太烂而发明的借口。你写的代码那么大,加载时间那么长,不分割能行吗?

你以为随便分割一下代码就能解决性能问题?别做梦了!如果分割策略不合理,反而会导致更多的网络请求,让应用变得更慢。

为什么你需要这个

  1. 减少初始加载时间:通过代码分割,只加载当前页面所需的代码,减少初始加载时间,提高用户体验。
  2. 优化资源利用:只加载用户需要的代码,避免加载不必要的资源,优化内存和带宽使用。
  3. 提高首屏渲染速度:快速加载首屏所需的代码,让用户尽快看到页面内容。
  4. 支持大型应用:对于大型应用,代码分割可以避免打包后的文件过大,导致加载时间过长。

反面教材

// 这是一个典型的不使用代码分割的应用 import React from 'react'; import ReactDOM from 'react-dom'; import Home from './pages/Home'; import About from './pages/About'; import Contact from './pages/Contact'; import Dashboard from './pages/Dashboard'; import Settings from './pages/Settings'; import UserProfile from './pages/UserProfile'; import AdminPanel from './pages/AdminPanel'; import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; function App() { return ( <Router> <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} /> <Route path="/contact" element={<Contact />} /> <Route path="/dashboard" element={<Dashboard />} /> <Route path="/settings" element={<Settings />} /> <Route path="/user-profile" element={<UserProfile />} /> <Route path="/admin" element={<AdminPanel />} /> </Routes> </Router> ); } ReactDOM.render(<App />, document.getElementById('root')); 

问题

  • 所有页面的代码都打包在一个文件中,导致初始加载时间过长
  • 即使用户只访问首页,也会加载所有页面的代码
  • 大型应用的打包文件会变得非常大,影响加载速度
  • 无法实现按需加载,浪费带宽和内存

正确的做法

React中的代码分割与懒加载

// 使用React.lazy和Suspense实现懒加载 import React, { lazy, Suspense } from 'react'; import ReactDOM from 'react-dom'; import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; // 懒加载页面组件 const Home = lazy(() => import('./pages/Home')); const About = lazy(() => import('./pages/About')); const Contact = lazy(() => import('./pages/Contact')); const Dashboard = lazy(() => import('./pages/Dashboard')); const Settings = lazy(() => import('./pages/Settings')); const UserProfile = lazy(() => import('./pages/UserProfile')); const AdminPanel = lazy(() => import('./pages/AdminPanel')); // 加载中组件 const Loading = () => <div>Loading...</div>; function App() { return ( <Router> <Suspense fallback={<Loading />}> <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} /> <Route path="/contact" element={<Contact />} /> <Route path="/dashboard" element={<Dashboard />} /> <Route path="/settings" element={<Settings />} /> <Route path="/user-profile" element={<UserProfile />} /> <Route path="/admin" element={<AdminPanel />} /> </Routes> </Suspense> </Router> ); } ReactDOM.render(<App />, document.getElementById('root')); 

Webpack中的代码分割

// webpack.config.js module.exports = { entry: { main: './src/index.js', }, output: { filename: '[name].[contenthash].js', chunkFilename: '[name].[contenthash].chunk.js', }, optimization: { splitChunks: { chunks: 'all', cacheGroups: { vendor: { test: /[\\/]node_modules[\\/]/, name: 'vendors', chunks: 'all', }, }, }, }, }; 

基于路由的代码分割

// 使用React Router和React.lazy实现基于路由的代码分割 import React, { lazy, Suspense } from 'react'; import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom'; // 懒加载路由组件 const Home = lazy(() => import('./pages/Home')); const About = lazy(() => import('./pages/About')); const Contact = lazy(() => import('./pages/Contact')); const Dashboard = lazy(() => import('./pages/Dashboard')); const Settings = lazy(() => import('./pages/Settings')); const UserProfile = lazy(() => import('./pages/UserProfile')); const AdminPanel = lazy(() => import('./pages/AdminPanel')); // 加载中组件 const Loading = () => ( <div className="loading"> <div className="loading-spinner"></div> <p>Loading...</p> </div> ); // 错误边界组件 class ErrorBoundary extends React.Component { constructor(props) { super(props); this.state = { hasError: false }; } static getDerivedStateFromError(error) { return { hasError: true }; } componentDidCatch(error, errorInfo) { console.error('Error:', error); console.error('Error Info:', errorInfo); } render() { if (this.state.hasError) { return <div>Something went wrong. Please try again later.</div>; } return this.props.children; } } function App() { return ( <Router> <ErrorBoundary> <Suspense fallback={<Loading />}> <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} /> <Route path="/contact" element={<Contact />} /> <Route path="/dashboard" element={<Dashboard />} /> <Route path="/settings" element={<Settings />} /> <Route path="/user-profile" element={<UserProfile />} /> <Route path="/admin" element={<AdminPanel />} /> <Route path="*" element={<Navigate to="/" replace />} /> </Routes> </Suspense> </ErrorBoundary> </Router> ); } export default App; 

基于条件的代码分割

// 基于条件懒加载组件 import React, { lazy, Suspense, useState } from 'react'; // 懒加载重型组件 const HeavyComponent = lazy(() => import('./HeavyComponent')); function App() { const [showHeavyComponent, setShowHeavyComponent] = useState(false); return ( <div> <h1>Home Page</h1> <button onClick={() => setShowHeavyComponent(true)}> Load Heavy Component </button> {showHeavyComponent && ( <Suspense fallback={<div>Loading heavy component...</div>}> <HeavyComponent /> </Suspense> )} </div> ); } export default App; 

毒舌点评

代码分割和懒加载确实能提高应用的性能,但我见过太多开发者滥用这个特性,导致应用变得更加复杂。

想象一下,当你为了分割代码而分割代码,把原本简单的应用拆分成无数个小模块,结果导致网络请求变得更多,加载时间反而增加了。这不是得不偿失吗?

还有那些过度使用懒加载的开发者,连一些轻量级的组件也懒加载,结果导致用户点击按钮后还要等待组件加载,影响用户体验。

所以,在使用代码分割和懒加载时,一定要把握好度。不要为了分割而分割,要根据实际情况来决定哪些代码需要分割,哪些不需要。

当然,对于大型应用来说,代码分割和懒加载是必不可少的。但对于小型应用,过度的代码分割反而会增加开发成本和维护难度。

最后,记住一句话:代码分割和懒加载的目的是为了提高应用的性能和用户体验,而不是为了炫技。如果你的代码分割策略导致应用变得更慢,那你就失败了。

Read more

【AI大模型前沿】昆仑万维开源Skywork-R1V3:38B多模态推理模型,高考数学142分刷新开源SOTA

【AI大模型前沿】昆仑万维开源Skywork-R1V3:38B多模态推理模型,高考数学142分刷新开源SOTA

系列篇章💥 No.文章1【AI大模型前沿】深度剖析瑞智病理大模型 RuiPath:如何革新癌症病理诊断技术2【AI大模型前沿】清华大学 CLAMP-3:多模态技术引领音乐检索新潮流3【AI大模型前沿】浙大携手阿里推出HealthGPT:医学视觉语言大模型助力智能医疗新突破4【AI大模型前沿】阿里 QwQ-32B:320 亿参数推理大模型,性能比肩 DeepSeek-R1,免费开源5【AI大模型前沿】TRELLIS:微软、清华、中科大联合推出的高质量3D生成模型6【AI大模型前沿】Migician:清华、北大、华科联手打造的多图像定位大模型,一键解决安防监控与自动驾驶难题7【AI大模型前沿】DeepSeek-V3-0324:AI 模型的全面升级与技术突破8【AI大模型前沿】BioMedGPT-R1:清华联合水木分子打造的多模态生物医药大模型,开启智能研发新纪元9【AI大模型前沿】DiffRhythm:西北工业大学打造的10秒铸就完整歌曲的AI歌曲生成模型10【AI大模型前沿】R1-Omni:阿里开源全模态情感识别与强化学习的创新结合11【AI大模型前沿】Qwen2.5-Omni:

【程序员副业指南】KwaiKAT AI制作小红薯[特殊字符]卡片MCP

【程序员副业指南】KwaiKAT AI制作小红薯[特殊字符]卡片MCP

【程序员副业指南】KwaiKAT AI制作小红薯卡片MCP 【程序员副业指南】KwaiKAT AI制作小红薯📕卡片MCP 背景 每个程序员都熟悉计算机,是最适合写技术博客以及做分享的人。最近发现了一个Markdown转知识卡片,值得注意的是,可以利用这个快速制作小红薯📕卡片,但是有点小贵,对于我这样的白嫖党,那肯定是负担不起的,于是决定利用KAT-Coder-Pro V1复刻一个小红薯📕卡片MCP。 效果展示 本项目已开源:https://github.com/lfrbmw/Little-Red-Book-Card-MCP 有朋友问这个有什么用,最近来看效果,你的到一个可以直接发的小红📕卡片,示例如下,直接输出一张可发布小红书的笔记,还提供多个样式。 相关介绍 为什么选择 KAT-Coder-Pro V1? 🔥 高性能,高性价比 * SWE-Bench Verified 解决率达 73.4%,媲美全球顶尖闭源模型 * 256K 超长上下文,轻松处理项目级代码与复杂任务 * 支持

Pytorch和Tensorflow两大架构如何安装?想在自己的电脑上跑神经网络?如何找到部署自己电脑版本的神经网络工具?人工智能专业的学生集合!!

人工智能研究方向的科研小白,天崩开局?手把手教搭建神经网络训练工具准备 第一章 前言 1.1 研究背景 在当今科技迅猛发展的时代浪潮中,人工智能无疑已成为推动各领域变革与创新的核心驱动力。而神经网络,作为人工智能领域的基石与先锋,正以其独特的魅力与强大的效能,重塑着我们对世界的认知与交互方式。 近年来,生成式 AI 的爆发式增长成为科技领域最耀眼的现象之一。以Deep Seek为代表的大型语言模型,凭借其强大的自然语言处理能力,实现了与人类流畅、智能的对话交互,从文本创作、智能客服到知识问答,广泛应用于各个行业,为人们的工作与生活带来了前所未有的便利。图像生成领域,StableDiffusion 等模型能够根据简单的文本描述,创作出令人惊叹的高质量图像,激发了艺术创作的无限可能。这些生成式 AI 的卓越表现,背后离不开神经网络的有力支撑。神经网络通过对海量数据的深度挖掘与学习,掌握了语言、图像等信息的内在模式与规律,从而实现了精准的生成与创造。 1.2 研究意义 在当下,全国各大高校对计算机专业展现出了极高的热情,招生规模不断扩张,新的专业方向与课程设置也如雨后春笋般

用 AI 设计力打造专业 UI_UX:在 Trea、Qoder 等 AI IDE 中集成 ui-ux-pro-max-skill

用 AI 设计力打造专业 UI_UX:在 Trea、Qoder 等 AI IDE 中集成 ui-ux-pro-max-skill

在 AI 编程工具爆发的 2025–2026 年,开发者不再满足于“能跑就行”的界面——我们渴望一键生成媲美 Figma 原型的专业 UI。GitHub 上的开源项目 ui-ux-pro-max-skill 正是为此而生:它将 57 种设计风格、95 套行业配色、56 组字体搭配和 98 条 UX 准则打包成一个结构化知识库,让任何支持上下文引用的 AI 编码助手都能输出高质量前端代码。 本文将手把手教你如何在 Trea 和 Qoder 这类国产主流 AI IDE 中高效使用该项目——即使它们尚未被官方原生支持。 🌟 项目核心能力 ui-ux-pro-max-skill 不是一个普通插件,而是一个AI 可读的设计系统数据库,包含: * 57 种 UI 风格: