单页应用如何提高加载速度
通过代码分割、缓存、预加载等技术优化 SPA 加载性能
问题
单页应用(SPA)首次加载时往往需要下载大量 JavaScript 和资源文件,如何优化加载速度?
解答
代码分割与懒加载
将应用代码拆分成多个小块,按需加载,避免一次性加载所有代码。
// React 示例
import { lazy, Suspense } from 'react';
const Dashboard = lazy(() => import('./Dashboard'));
const Profile = lazy(() => import('./Profile'));
function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
<Routes>
<Route path="/dashboard" element={<Dashboard />} />
<Route path="/profile" element={<Profile />} />
</Routes>
</Suspense>
);
}
资源缓存
配置合理的缓存策略,让浏览器缓存静态资源。
// webpack 配置示例
module.exports = {
output: {
filename: '[name].[contenthash].js',
clean: true
}
};
# nginx 缓存配置
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
预加载关键资源
使用 preload 和 prefetch 提前加载关键资源。
<!-- 预加载关键 CSS 和字体 -->
<link rel="preload" href="/main.css" as="style">
<link rel="preload" href="/font.woff2" as="font" crossorigin>
<!-- 预获取可能需要的资源 -->
<link rel="prefetch" href="/dashboard.js">
图片优化
选择合适的图片格式并压缩,小图标使用字体图标或 SVG。
<!-- 使用 WebP 格式,提供降级方案 -->
<picture>
<source srcset="image.webp" type="image/webp">
<img src="image.jpg" alt="description">
</picture>
<!-- 响应式图片 -->
<img srcset="small.jpg 480w, medium.jpg 800w, large.jpg 1200w"
sizes="(max-width: 600px) 480px, 800px"
src="medium.jpg" alt="description">
启用压缩
在服务器端启用 Gzip 或 Brotli 压缩。
// Express 示例
const compression = require('compression');
app.use(compression());
使用 CDN
将静态资源部署到 CDN,加速全球访问。
// webpack 配置 CDN
module.exports = {
output: {
publicPath: 'https://cdn.example.com/assets/'
}
};
优化 API 请求
减少请求数量,使用缓存和批量请求。
// 使用 SWR 缓存请求
import useSWR from 'swr';
function Profile() {
const { data } = useSWR('/api/user', fetcher, {
revalidateOnFocus: false,
dedupingInterval: 60000
});
return <div>{data?.name}</div>;
}
// 批量请求
const [user, posts] = await Promise.all([
fetch('/api/user'),
fetch('/api/posts')
]);
服务器端渲染(SSR)
使用 SSR 生成首屏 HTML,减少客户端渲染时间。
// Next.js 示例
export async function getServerSideProps() {
const data = await fetchData();
return { props: { data } };
}
export default function Page({ data }) {
return <div>{data.title}</div>;
}
关键点
- 代码分割和路由懒加载可显著减少首次加载体积
- 合理配置缓存策略(contenthash + 长期缓存)提高二次访问速度
- 预加载关键资源和预获取可能访问的页面改善用户体验
- 图片优化(WebP、压缩、响应式)和启用 Gzip/Brotli 压缩减少传输大小
- SSR 适合首屏性能要求高的场景,但会增加服务器负担和架构复杂度
目录