前端效能優化是現代網頁開發不可忽視的重要環節。根據 Google 的研究,頁面載入時間每增加 1 秒,轉換率就會下降 7%。
本文將分享實務中證實有效的優化策略與技術實作,涵蓋從基礎到進階的完整方法。
效能評估:建立正確的測量基準
在開始優化之前,必須先建立準確的測量方式。主觀感受往往不可靠,需要依賴客觀數據來指導優化方向。
核心效能指標 (Core Web Vitals)
Google 定義的三個關鍵指標:
- LCP (Largest Contentful Paint):最大內容載入時間,理想值 < 2.5 秒
- FID (First Input Delay):首次輸入延遲,理想值 < 100 毫秒
- CLS (Cumulative Layout Shift):累計版面偏移,理想值 < 0.1
效能監控工具選擇
開發環境工具:
-
Chrome DevTools
- Performance 面板:分析運行時效能
- Network 面板:監控資源載入
- Lighthouse:綜合效能評分
-
Webpack Bundle Analyzer
npm install --save-dev webpack-bundle-analyzer npx webpack-bundle-analyzer build/static/js/*.js
-
Web Vitals 監控
import { getCLS, getFID, getFCP, getLCP, getTTFB } from 'web-vitals'; function sendToAnalytics(metric) { console.log(metric.name, metric.value); } getCLS(sendToAnalytics); getFID(sendToAnalytics); getLCP(sendToAnalytics);
生產環境監控:
- PageSpeed Insights:分析真實用戶數據
- Chrome UX Report:大規模用戶體驗統計
- 自定義 RUM (Real User Monitoring):持續監控線上效能
圖片資源優化策略
為什麼圖片優化如此重要
圖片通常佔據網頁總大小的 60-70%,是影響載入速度的關鍵因素。合理的圖片優化能顯著提升頁面效能。
現代圖片格式選擇
格式優先級策略:
<picture>
<source srcset="hero-image.avif" type="image/avif" />
<source srcset="hero-image.webp" type="image/webp" />
<img
src="hero-image.jpg"
alt="首頁橫幅"
loading="lazy"
width="1200"
height="600"
/>
</picture>
格式效能比較:
- AVIF: 最新格式,壓縮率比 JPEG 高 50%,但瀏覽器支援度約 80%
- WebP: 壓縮率比 JPEG 高 25-30%,現代瀏覽器普遍支援
- JPEG/PNG: 通用格式,作為 fallback
響應式圖片實作
<img
srcset="image-400.jpg 400w,
image-800.jpg 800w,
image-1200.jpg 1200w"
sizes="(max-width: 400px) 400px,
(max-width: 800px) 800px,
1200px"
src="image-800.jpg"
alt="響應式圖片"
loading="lazy"
/>
根據使用者裝置載入適當尺寸的圖片,避免浪費頻寬載入過大的圖檔。
JavaScript 效能優化
Bundle Size 控制策略
大型 JavaScript bundle 是效能瓶頸的主要來源。以下是有效的優化策略:
模組化載入:
// 避免載入整個函式庫
import _ from 'lodash'; // ❌ 載入整個 lodash (70KB)
import { debounce } from 'lodash-es'; // ✅ 只載入需要的函數
// 使用原生 API 替代
const unique = _.uniq(array); // ❌ 使用 lodash
const unique = [...new Set(array)]; // ✅ 原生去重
// 日期處理優化
import moment from 'moment'; // ❌ moment.js (67KB)
import { format } from 'date-fns'; // ✅ date-fns 模組化 (2KB per function)
動態載入 (Code Splitting)
// 路由層級分割
const HomePage = lazy(() => import('./pages/HomePage'));
const ProductPage = lazy(() => import('./pages/ProductPage'));
// 功能層級分割
const handleChartView = async () => {
const { Chart } = await import('./components/Chart');
// 只在需要時載入圖表功能
};
根據用戶需求動態載入程式碼,減少初始 bundle 大小。
React 效能優化
避免不必要的重新渲染:
// 問題:每次渲染都創建新函數
const App = () => {
const [data, setData] = useState([]);
return (
<List
items={data}
onItemClick={(id) => handleClick(id)} // ❌ 每次都是新函數
/>
);
};
// 解決:使用 useCallback
const App = () => {
const [data, setData] = useState([]);
const handleItemClick = useCallback((id) => {
handleClick(id);
}, []);
return (
<List
items={data}
onItemClick={handleItemClick} // ✅ 穩定的函數引用
/>
);
};
使用 React.memo、useCallback、useMemo 等優化工具,避免不必要的組件重新渲染。
CSS 動畫效能最佳化
高效能動畫原則
CSS 動畫效能取決於觸發的瀏覽器渲染階段。理想的動畫只觸發 Composite 階段:
/* 低效能:觸發 Layout + Paint + Composite */
.slow-animation {
transition: width 0.3s ease;
}
.slow-animation:hover {
width: 200px; /* 改變 width 觸發 layout */
}
/* 高效能:只觸發 Composite */
.fast-animation {
transition: transform 0.3s ease;
will-change: transform;
}
.fast-animation:hover {
transform: scaleX(1.5); /* transform 只觸發 composite */
}
動畫屬性選擇指南
效能友善的 CSS 屬性: transform、opacity、filter、backdrop-filter
避免動畫的屬性: width、height、top、left、margin、padding、border
選擇正確的動畫屬性是提升效能的關鍵。Transform 和 opacity 變化只需要 GPU 合成,不會觸發重排或重繪。
進階動畫技巧
使用 will-change
提示瀏覽器:
.animated-element {
will-change: transform, opacity;
/* 動畫結束後記得移除 */
}
.animated-element.animation-complete {
will-change: auto;
}
適當使用 will-change
可以讓瀏覽器預先優化元素,但過度使用反而會消耗記憶體。
進階優化技術
虛擬滾動實作
對於大量數據的列表,虛擬滾動是必要的優化手段:
const VirtualList = ({ items, itemHeight = 50 }) => {
const [scrollTop, setScrollTop] = useState(0);
const containerHeight = 600;
const startIndex = Math.floor(scrollTop / itemHeight);
const endIndex = Math.min(
startIndex + Math.ceil(containerHeight / itemHeight) + 1,
items.length
);
const visibleItems = items.slice(startIndex, endIndex);
return (
<div
style={{ height: containerHeight, overflow: 'auto' }}
onScroll={(e) => setScrollTop(e.target.scrollTop)}
>
<div style={{ height: items.length * itemHeight, position: 'relative' }}>
{visibleItems.map((item, index) => (
<div
key={startIndex + index}
style={{
position: 'absolute',
top: (startIndex + index) * itemHeight,
height: itemHeight,
width: '100%'
}}
>
{item.content}
</div>
))}
</div>
</div>
);
};
虛擬滾動只渲染可見區域的元素,大幅減少 DOM 節點數量。
資源預載入策略
<!-- 關鍵資源預載入 -->
<link rel="preload" href="/fonts/main.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/css/critical.css" as="style">
<!-- 可能用到的資源預取 -->
<link rel="prefetch" href="/js/secondary-features.js">
<link rel="dns-prefetch" href="//api.example.com">
<!-- 下一頁預載入 -->
<link rel="prerender" href="/next-page">
合理的預載入可以提升用戶體驗,但要避免預載入過多資源影響關鍵資源的載入。
Service Worker 快取策略
// 在 service-worker.js 中實作智能快取
const CACHE_NAME = 'app-v1';
const STATIC_ASSETS = [
'/',
'/css/main.css',
'/js/app.js',
'/fonts/main.woff2'
];
// 安裝時預快取關鍵資源
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open(CACHE_NAME)
.then(cache => cache.addAll(STATIC_ASSETS))
);
});
// 網路優先策略,適用於動態內容
self.addEventListener('fetch', (event) => {
if (event.request.url.includes('/api/')) {
event.respondWith(
fetch(event.request)
.then(response => {
const responseClone = response.clone();
caches.open(CACHE_NAME)
.then(cache => cache.put(event.request, responseClone));
return response;
})
.catch(() => caches.match(event.request))
);
}
});
Service Worker 提供離線體驗和智能快取,是現代 PWA 的核心技術。
實用優化技巧
CSS content-visibility 屬性
.article-list-item {
content-visibility: auto;
contain-intrinsic-size: 0 300px;
}
此屬性可讓瀏覽器跳過不在視窗內的元素渲染,對長列表效能提升顯著。
防抖動滾動事件
let ticking = false;
function updateScrollPosition() {
// 處理滾動邏輯
ticking = false;
}
window.addEventListener('scroll', () => {
if (!ticking) {
requestAnimationFrame(updateScrollPosition);
ticking = true;
}
});
使用 requestAnimationFrame 避免滾動事件過度觸發,提升滾動效能。
效能優化策略總結
優化優先級框架
效能優化應該遵循明確的優先級順序:
🎯 優化順序建議
- 1. 關鍵渲染路徑優化
首屏載入速度、關鍵 CSS 和 JavaScript - 2. 資源載入優化
圖片壓縮、字體優化、bundle size 控制 - 3. 運行時效能
動畫流暢度、記憶體使用、CPU 佔用 - 4. 用戶體驗細節
載入狀態、錯誤處理、離線支援
效能監控檢查清單
開發階段:
- 每次 build 檢查 bundle size 變化
- 使用 Lighthouse 評估核心指標
- 在低速網路環境下測試
上線後:
- 設定 Core Web Vitals 監控
- 定期分析 RUM 數據
- 追蹤關鍵業務指標與效能的關聯
常見效能陷阱
- 過度優化:在不需要的地方浪費時間
- 忽略測量:憑感覺而非數據做決策
- 單點優化:只關注某個指標而忽略整體
- 技術債務:短期解決方案累積成長期問題
核心原則: 測量先行、用戶為本、持續改進。效能優化是一個持續的過程,而不是一次性的任務。
實用工具與資源
效能分析工具
- • Chrome DevTools - 內建分析功能
- • WebPageTest - 載入瀑布圖分析
- • GTmetrix - 綜合效能評估
- • Pingdom - 全球多點監控
優化工具
- • ImageOptim - 圖片無損壓縮
- • Critical - 提取關鍵 CSS
- • Workbox - Service Worker 快取
- • webpack-bundle-analyzer - Bundle 分析
前端效能優化需要持續關注和改進。從基礎的資源優化到進階的架構設計,每個環節都影響著用戶體驗。重要的是建立正確的測量習慣,並根據實際數據指導優化方向。