圖片
圖片對你的應用程式效能有很大的影響。為了獲得最佳結果,你應該透過執行以下操作來優化它們:
- 產生最佳格式,例如
.avif
和.webp
- 為不同的螢幕建立不同的尺寸
- 確保資產可以有效地快取
手動執行此操作很繁瑣。你可以根據你的需求和偏好使用各種技術。
Vite 的內建處理
Vite 會自動處理導入的資產以提高效能。這包括透過 CSS url()
函數引用的資產。雜湊值將被添加到檔案名稱中,以便它們可以被快取,並且小於 assetsInlineLimit
的資產將會被內聯。Vite 的資產處理最常用於圖片,但對於影片、音訊等也很有用。
<script>
import logo from '$lib/assets/logo.png';
</script>
<img alt="The project logo" src={logo} />
@sveltejs/enhanced-img
@sveltejs/enhanced-img
是在 Vite 內建資產處理之上提供的外掛程式。它提供即插即用的圖片處理,可提供較小的檔案格式,例如 avif
或 webp
,自動設定圖片的固有 width
和 height
以避免版面配置偏移,為各種裝置建立多種尺寸的圖片,並刪除 EXIF 資料以保護隱私。它將在任何基於 Vite 的專案中運作,包括但不限於 SvelteKit 專案。
作為一個建置外掛程式,
@sveltejs/enhanced-img
只能優化建置過程中位於你電腦上的檔案。如果你有位於其他位置的圖片(例如從你的資料庫、CMS 或後端提供的路徑),請閱讀關於從 CDN 動態載入圖片的內容。警告:
@sveltejs/enhanced-img
套件是實驗性的。它使用 pre-1.0 版本控制,並且可能會在每個次要版本發佈時引入重大變更。
設定
安裝
npm install --save-dev @sveltejs/enhanced-img
調整 vite.config.js
import { function sveltekit(): Promise<Plugin<any>[]>
Returns the SvelteKit Vite plugins.
sveltekit } from '@sveltejs/kit/vite';
import { function enhancedImages(): Promise<Plugin[]>
enhancedImages } from '@sveltejs/enhanced-img';
import { function defineConfig(config: UserConfig): UserConfig (+3 overloads)
Type helper to make it easier to use vite.config.ts
accepts a direct
{@link
UserConfig
}
object, or a function that returns it.
The function receives a
{@link
ConfigEnv
}
object.
defineConfig } from 'vite';
export default function defineConfig(config: UserConfig): UserConfig (+3 overloads)
Type helper to make it easier to use vite.config.ts
accepts a direct
{@link
UserConfig
}
object, or a function that returns it.
The function receives a
{@link
ConfigEnv
}
object.
defineConfig({
UserConfig.plugins?: PluginOption[] | undefined
Array of vite plugins to use.
plugins: [
function enhancedImages(): Promise<Plugin[]>
enhancedImages(),
function sveltekit(): Promise<Plugin<any>[]>
Returns the SvelteKit Vite plugins.
sveltekit()
]
});
由於轉換圖片的計算開銷,第一次建置將會花費更長的時間。但是,建置輸出將快取在 ./node_modules/.cache/imagetools
中,以便後續建置能夠快速進行。
基本用法
在你的 .svelte
元件中使用 <enhanced:img>
而不是 <img>
,並使用 Vite 資產匯入路徑引用圖片檔案
<enhanced:img src="./path/to/your/image.jpg" alt="An alt text" />
在建置時,你的 <enhanced:img>
標籤將被一個由 <picture>
包裹的 <img>
取代,提供多種圖片類型和尺寸。僅在不損失品質的情況下縮小圖片是可能的,這表示你應該提供你所需要的最高解析度圖片 - 將為可能請求圖片的各種裝置類型產生較小的版本。
你應該為 HiDPI 螢幕(又稱 Retina 螢幕)提供 2 倍解析度的圖片。<enhanced:img>
將自動處理為較小的裝置提供較小的版本。
如果你希望向你的 <enhanced:img>
新增樣式,你應該新增一個 class
並以此為目標。
動態選擇圖片
你也可以手動匯入圖片資產並將其傳遞給 <enhanced:img>
。當你擁有一組靜態圖片並且想要動態選擇其中一張或迭代它們時,這很有用。在這種情況下,你需要更新 import
陳述式和 <img>
元素,如下所示,以指示你想要處理它們。
<script>
import MyImage from './path/to/your/image.jpg?enhanced';
</script>
<enhanced:img src={MyImage} alt="some alt text" />
你也可以使用 Vite 的 import.meta.glob
。請注意,你必須透過自訂查詢指定 enhanced
。
<script>
const imageModules = import.meta.glob(
'/path/to/assets/*.{avif,gif,heif,jpeg,jpg,png,tiff,webp,svg}',
{
eager: true,
query: {
enhanced: true
}
}
)
</script>
{#each Object.entries(imageModules) as [_path, module]}
<enhanced:img src={module.default} alt="some alt text" />
{/each}
固有尺寸
width
和 height
是可選的,因為它們可以從來源圖片中推斷出來,並且會在預處理 <enhanced:img>
標籤時自動新增。使用這些屬性,瀏覽器可以保留正確的空間量,防止版面配置偏移。如果你想使用不同的 width
和 height
,你可以使用 CSS 設定圖片的樣式。由於預處理器為你新增了 width
和 height
,如果你希望自動計算其中一個尺寸,則需要指定它
<style>
.hero-image img {
width: var(--size);
height: auto;
}
</style>
srcset 和 sizes
如果你有一個大型圖片,例如佔據設計寬度的英雄圖片,你應該指定 sizes
,以便在較小的裝置上請求較小的版本。例如,如果你有一個 1280 像素的圖片,你可能想要指定類似的內容
<enhanced:img src="./image.png" sizes="min(1280px, 100vw)"/>
如果指定了 sizes
,則 <enhanced:img>
將為較小的裝置產生小型圖片並填入 srcset
屬性。
自動產生的最小圖片寬度將為 540 像素。如果你想要更小的圖片或想要指定自訂寬度,你可以使用 w
查詢參數來執行此操作
<enhanced:img
src="./image.png?w=1280;640;400"
sizes="(min-width:1920px) 1280px, (min-width:1080px) 640px, (min-width:768px) 400px"
/>
如果未提供 sizes
,則會產生 HiDPI/Retina 圖片和標準解析度圖片。你提供的圖片應該是你希望顯示的解析度的 2 倍,以便瀏覽器可以在具有高裝置像素比率的裝置上顯示該圖片。
每個圖片的轉換
預設情況下,增強的圖片將轉換為更有效率的格式。但是,你可能希望應用其他轉換,例如模糊、品質、展平或旋轉操作。你可以透過附加查詢字串來執行每個圖片的轉換
<enhanced:img src="./path/to/your/image.jpg?blur=15" alt="An alt text" />
從 CDN 動態載入圖片
在某些情況下,圖片可能在建置時無法存取 - 例如,它們可能存在於內容管理系統或其他地方。
使用內容傳遞網路 (CDN) 可以讓你動態優化這些圖片,並在尺寸方面提供更大的彈性,但它可能涉及一些設定開銷和使用成本。根據快取策略,瀏覽器可能無法使用資產的快取副本,直到收到來自 CDN 的 304 回應。建立 HTML 以針對 CDN 允許使用 <img>
標籤,因為 CDN 可以根據 User-Agent
標頭提供適當的格式,而建置時的優化必須產生具有多個來源的 <picture>
標籤。最後,某些 CDN 可能會延遲產生圖片,這可能會對流量低且圖片經常變更的網站產生負面的效能影響。
通常可以無需任何程式庫即可使用 CDN。但是,有許多支援 Svelte 的程式庫可以簡化操作。@unpic/svelte
是一個與 CDN 無關的程式庫,支援大量的供應商。你也可能會發現像Cloudinary 這樣特定的 CDN 具有 Svelte 支援。最後,某些支援 Svelte 的內容管理系統 (CMS)(例如 Contentful、Storyblok 和 Contentstack)具有圖片處理的內建支援。
最佳實踐
- 對於每種圖片類型,請使用上述討論的適當解決方案。你可以在一個專案中混合搭配所有三種解決方案。例如,你可能會使用 Vite 的內建處理來為
<meta>
標籤提供圖片,使用@sveltejs/enhanced-img
在你的首頁上顯示圖片,並使用動態方法顯示使用者提交的內容。 - 考慮透過 CDN 提供所有圖片,無論你使用哪種圖片優化類型。CDN 透過在全球範圍內分發靜態資產的副本來減少延遲。
- 你的原始圖片應該具有良好的品質/解析度,並且應該具有其將顯示寬度的 2 倍,以便為 HiDPI 裝置提供服務。圖片處理可以縮小圖片尺寸,以便在提供較小螢幕時節省頻寬,但為了放大圖片而發明像素將會浪費頻寬。
- 對於比行動裝置寬度(約 400 像素)大得多的圖片,例如佔據頁面設計寬度的英雄圖片,請指定
sizes
,以便可以在較小的裝置上提供較小的圖片。 - 對於重要的圖片,例如最大內容繪製 (LCP) 圖片,設定
fetchpriority="high" loading="eager"
以優先盡早載入。 - 給圖片一個容器或樣式,使其受到約束,並且不會在頁面載入時跳動,從而影響你的累計版面配置偏移 (CLS)。
width
和height
協助瀏覽器在圖片仍在載入時保留空間,因此@sveltejs/enhanced-img
將為你新增width
和height
。 - 請務必提供良好的
alt
文字。如果你沒有執行此操作,Svelte 編譯器會發出警告。 - 請勿在
sizes
中使用em
或rem
,並變更這些度量的預設大小。在sizes
或@media
查詢中使用時,em
和rem
都定義為表示使用者的預設font-size
。對於像sizes="(min-width: 768px) min(100vw, 108rem), 64rem"
這樣的sizes
宣告,如果 CSS 變更,控制圖片在頁面上佈局的實際em
或rem
可能會不同。例如,不要執行類似html { font-size: 62.5%; }
的操作,因為瀏覽器預載入器保留的空間現在會比建立後 CSS 物件模型的實際空間大。