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

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

毒舌时刻

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

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

为什么你需要这个

  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

C++ 方向 Web 自动化测试实战:以博客系统为例,从用例到报告全流程解析

C++ 方向 Web 自动化测试实战:以博客系统为例,从用例到报告全流程解析

🔥草莓熊Lotso:个人主页 ❄️个人专栏: 《C++知识分享》《Linux 入门到实践:零基础也能懂》 ✨生活是默默的坚持,毅力是永久的享受! 🎬 博主简介: 文章目录 * 前言: * 一. 自动化测试前置:明确测试范围与测试用例设计 * 二. 自动化测试脚本开发:Python+Selenium 实现 * 2.1 通用工具类:common/Utils.py * 2.2. 登录模块测试:cases/BlogLogin.py * 2.3. 博客列表与详情页测试:cases/BlogList.py & BlogDetail.py * 2.3.1. 列表页测试(BlogList.py) * 2.3.

一文读懂AI大模型训练全流程,从准备到落地清晰拆解!

一文读懂AI大模型训练全流程,从准备到落地清晰拆解!

AI大模型的诞生并非一蹴而就,而是需要经过一套严谨、系统的流程设计与执行。其核心训练环节可概括为五大阶段:数据与模型准备、核心参数训练、性能验证测试、针对性调优迭代、实际场景落地。每个阶段环环相扣,共同决定了大模型的最终效果与实用价值。 1. 准备阶段:为模型搭建“地基” 准备阶段是大模型训练的基础,如同盖房子前的“打地基”与“备材料”,直接影响后续训练的效率与模型质量。此阶段的核心目标是获取高质量数据、设计适配任务的模型架构,为训练环节做好充分铺垫。 数据收集:构建“知识宝库” 大模型的“认知能力”源于海量数据,因此数据收集需兼顾规模、多样性与合规性。 * 数据来源广泛,涵盖公开互联网文本(如百科、论坛、新闻)、经过授权的图书资源、行业垂直数据集(如医疗文献、金融报告)、社交媒体对话等,部分场景还会引入多语言数据以提升模型通用性。 * 数据量通常以“TB”甚至“PB”为单位,例如主流大模型的训练数据量常突破万亿 tokens,

9.4k stars!手中就有一整个 AI 团队:agency-agents 深度解析手中就有一整个 AI 团队:agency-agents 深度解析!

9.4k stars!手中就有一整个 AI 团队:agency-agents 深度解析手中就有一整个 AI 团队:agency-agents 深度解析!

手中就有一整个 AI 团队:agency-agents 深度解析 当别人还在反复调试同一个"万能提示词",有人已经在用一支分工明确的 AI 精英团队在干活了。 一、你是不是也有这些痛点? 用 Claude Code 写代码,前一秒在解 Bug,后一秒又要帮你想营销文案,再后一秒还得审查 UI 设计——同一个 AI 上下文频繁切换,结果每件事都做得平平无奇。 通用 AI 的问题在于:它什么都能做,但什么都不够专。 你有没有想过,如果 AI 也能像真实公司一样——前端有前端工程师、设计有 UI 设计师、增长有增长黑客——每个岗位的人用自己深耕多年的方式来工作,结果会有多大不同? agency-agents 就是为了解决这个问题而生的。 二、agency-agents 是什么? agency-agents

10分钟,教你用OpenClaw+Chrome插件生成一份AI每日简报

大家好,我是岳哥。 最近在自己电脑上安装了OpenClaw(原名Clawdbot),越用越上瘾,中午吃饭的时候都还在用手机飞书给它下命令。 花了点时间让它帮我做了一个AI每日简报,可以看下效果。 这个是基于X和Brave Search搜索全网信息源生成的,我个人认为效果还是挺不错的,直接在飞书上就可以看到了。 下面给大家分享一下要如何实现这个功能。 安装OpenClaw和飞书插件 这个前面有详细介绍,包括飞书插件安装失败的解决办法,都有给大家分享,跟着教程操作都可以安装成功的。 具体链接如下: Clawdbot/Moltbot安装教程,接入飞书本地搭建你的AI助理平台 教你如何解决OpenClaw安装飞书插件失败的问题 安装Chrome插件 这个是OpenClaw开发的一个Chrome插件,可以根据你的要求使用Chrome打开你要搜索的信息关键词的相关网页。 这个插件分为三个部分: * 浏览器控制服务(网关或节点):代理/工具调用的API(通过网关) * 本地中继服务器(环回CDP):控制服务器与扩展之间的桥接(默认设置)http://127.0.0.