載入圖片的方法 base64 跟 require載入圖片 哪一個比較快
載入圖片:base64 vs require / import
TL;DR**小圖標(<5KB)**用 base64 inline、內容圖用一般 <img src> + 現代格式(WebP / AVIF)+ lazy loading。別把整個 product image 變 base64,反而拖慢首屏。
兩種方式的本質差別
| 方式 | 機制 | 進入 bundle? | HTTP 請求 |
|---|---|---|---|
| base64 inline | 圖片編碼成字串放進 JS / CSS | ✅ 是 | ❌ 不需要 |
| require / import | 圖片打包成獨立檔,給 URL | ❌ 否(獨立檔) | ✅ 需要 |
<img src="/path"> | 純 URL 引用 | ❌ 否 | ✅ 需要 |
各自的代價
base64 的隱形成本
Base64 編碼會讓檔案膨脹約 33%:
1KB二進制圖 → 約1.37KBbase64 字串- 字串進 JS bundle → 所有用到該頁面的人都要下載這個字串,即使他們不會看到圖
- 無法被瀏覽器 cache 成獨立資源(綁定在 JS bundle cache 裡)
- 解碼也要 CPU 成本(雖然很小)
require / 一般 <img> 的成本
- 每張圖 = 1 個 HTTP 請求(HTTP/2 後不太貴)
- TLS handshake 跟 TCP 慢啟動(現代 CDN 不太是問題)
- 小圖請求成本相對固定:1KB 的圖跟 100B 的圖,網路時間差不多
何時用哪個
base64 適合
- <5KB 的小圖標(SVG icon、loading spinner)
- CSS 背景小裝飾(避免 FOUC)
- Email 內嵌圖(離線可看)
一般載入適合
- 內容圖、產品圖、Hero 圖(走 CDN + cache)
- 超過 10KB 的圖(膨脹率讓 bundle 變大太多)
- 重複使用的 logo(獨立檔可被多頁共用 cache)
現代做法:都不是最佳解
2023 年寫的這篇 base64 vs require 的對比,在 2026 年的視角 已經有更好答案:
Next.js / Vite 的內建優化
// Next.js Image — 自動 WebP/AVIF、自動 lazy、自動 srcset
import Image from 'next/image';
<Image src="/hero.jpg" alt="hero" width={800} height={600} priority />
原生 <img> 進階用法
<picture>
<source srcset="hero.avif" type="image/avif">
<source srcset="hero.webp" type="image/webp">
<img src="hero.jpg" alt="hero" loading="lazy" decoding="async">
</picture>
loading="lazy" + decoding="async" + AVIF/WebP 格式,效能比 base64/require 都好。
Webpack / Vite 的 asset/inline threshold
打包工具其實已經幫你決定了:
// Webpack 5 — 自動依大小決定 inline or 獨立檔
module.exports = {
module: {
rules: [{
test: /\.(png|jpg|gif)$/,
type: 'asset',
parser: { dataUrlCondition: { maxSize: 8 * 1024 } }, // < 8KB 自動 base64
}],
},
};
預設 8KB 以下自動 inline 成 base64,以上獨立檔。Vite 預設 assetsInlineLimit: 4096(4KB)。所以實務上你只要設好 threshold,工具自己處理。