前端性能优化实践
在现代 Web 开发中,性能优化是一个永恒的话题。本文将分享一些在实际项目中应用的前端性能优化技巧和经验。
代码分割 (Code Splitting)
使用动态导入来实现代码分割,减少初始包大小:
TypeScript
// 路由级别的代码分割
import { lazy, Suspense } from 'react'
const Home = lazy(() => import('./pages/Home'))
const About = lazy(() => import('./pages/About'))
function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
</Suspense>
)
}图片优化
响应式图片
HTML
<picture>
<source media="(min-width: 800px)" srcset="large.webp" type="image/webp">
<source media="(min-width: 400px)" srcset="medium.webp" type="image/webp">
<img src="small.jpg" alt="描述" loading="lazy">
</picture>懒加载
TypeScript
import { useEffect, useRef, useState } from 'react'
const LazyImage = ({ src, alt }: { src: string; alt: string }) => {
const [isLoaded, setIsLoaded] = useState(false)
const [isInView, setIsInView] = useState(false)
const imgRef = useRef<HTMLImageElement>(null)
useEffect(() => {
const observer = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting) {
setIsInView(true)
observer.disconnect()
}
},
{ threshold: 0.1 }
)
if (imgRef.current) {
observer.observe(imgRef.current)
}
return () => observer.disconnect()
}, [])
return (
<img
ref={imgRef}
src={isInView ? src : undefined}
alt={alt}
onLoad={() => setIsLoaded(true)}
style={{ opacity: isLoaded ? 1 : 0 }}
/>
)
}缓存策略
Service Worker
JavaScript
// sw.js
const CACHE_NAME = 'my-app-v1'
const urlsToCache = [
'/',
'/static/css/main.css',
'/static/js/main.js'
]
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open(CACHE_NAME)
.then((cache) => cache.addAll(urlsToCache))
)
})
self.addEventListener('fetch', (event) => {
event.respondWith(
caches.match(event.request)
.then((response) => {
return response || fetch(event.request)
})
)
})性能监控
使用 Web Vitals 监控核心性能指标:
TypeScript
import { getCLS, getFID, getFCP, getLCP, getTTFB } from 'web-vitals'
function sendToAnalytics(metric: any) {
// 发送到分析服务
console.log(metric)
}
getCLS(sendToAnalytics)
getFID(sendToAnalytics)
getFCP(sendToAnalytics)
getLCP(sendToAnalytics)
getTTFB(sendToAnalytics)总结
性能优化是一个持续的过程,需要根据具体项目情况选择合适的优化策略。记住:
- 先测量,再优化
- 关注用户体验指标
- 持续监控和改进
希望这些实践经验对你有所帮助!