前言
Svelte,一個語法簡潔、入門容易,面向未來的前端框架。
從 Svelte 誕生之初,就備受開發者的喜愛,根據統計,從 2019 年到 2024 年,連續 6 年一直是開發者最感興趣的前端框架 No.1:
Svelte 以其獨特的編譯時優化機制著稱,具有輕量級、高性能、易上手等特性,非常適合構建輕量級 Web 項目。
為了幫助大家學習 Svelte,我同時搭建了 Svelte 最新的中文文檔站點。
如果需要進階學習,也可以入手我的小冊《Svelte 開發指南》,語法篇、實戰篇、原理篇三大篇章帶你系統掌握 Svelte!
歡迎圍觀我的“網頁版朋友圈”、加入“冴羽·成長陪伴社群”,踏上“前端大佬成長之路”。
圖片
圖片會對您的應用性能產生重大影響。為了獲得最佳效果,您應該通過以下方式優化它們:
- 生成最優格式如
.avif
和.webp
- 為不同的屏幕創建不同尺寸的圖片
- 確保資源可以被有效緩存
手動完成這些工作很繁瑣。根據您的需求和偏好,您可以使用多種技術。
Vite 的內置處理
Vite 會自動處理導入的資源以提升性能。這包括通過 CSS url()
函數引用的資源。文件名中會添加哈希值以便緩存,小于 assetsInlineLimit
的資源會被內聯。Vite 的資源處理最常用于圖片,但對視頻、音頻等也很有用。
<script>import logo from '$lib/assets/logo.png';
</script><img alt="項目標志" src={logo} />
@sveltejs/enhanced-img
@sveltejs/enhanced-img
是在 Vite 內置資源處理基礎上提供的插件。它提供即插即用的圖片處理功能,可以提供更小的文件格式如 avif
或 webp
,自動設置圖片的固有 width
和 height
以避免布局偏移,為各種設備創建多種尺寸的圖片,并出于隱私考慮去除 EXIF 數據。它可以在任何基于 Vite 的項目中使用,包括但不限于 SvelteKit 項目。
[!NOTE] 作為構建插件,
@sveltejs/enhanced-img
只能在構建過程中優化位于您機器上的文件。如果您的圖片位于其他位置(如從數據庫、CMS 或后端服務的路徑),請閱讀從 CDN 動態加載圖片。警告:
@sveltejs/enhanced-img
包是實驗性的。它使用 1.0 之前的版本號,每個小版本發布可能會引入破壞性變更。
設置
安裝:
npm install --save-dev @sveltejs/enhanced-img
調整 vite.config.js
:
import { sveltekit } from '@sveltejs/kit/vite';
+++import { enhancedImages } from '@sveltejs/enhanced-img';+++
import { defineConfig } from 'vite';export default defineConfig({plugins: [+++enhancedImages(),+++sveltekit()]
});
由于轉換圖片的計算開銷,第一次構建會花費更長時間。但是,構建輸出會被緩存在 ./node_modules/.cache/imagetools
中,因此后續的構建會很快。
基本用法
在你的 .svelte
組件中使用 <enhanced:img>
而不是<img>
,并通過 Vite 資源導入 路徑引用圖片文件:
<enhanced:img src="./path/to/your/image.jpg" alt="An alt text" />
在構建時,您的 <enhanced:img>
標簽將被 <img>
替換,并由 <picture>
包裝,提供多種圖片類型和尺寸。在不損失質量的情況下只能對圖片進行縮小,這意味著你應該提供所需的最高分辨率圖片——系統會為可能請求圖片的各種設備類型生成較小的版本。
你應該為 HiDPI 顯示器(又稱視網膜顯示器)提供 2x 分辨率的圖片。<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
,這樣在較小的設備上就會請求較小版本的圖像。例如,如果你有一個 1280px 的圖像,你可能想要指定類似這樣的內容:
<enhanced:img src="./image.png" sizes="min(1280px, 100vw)"/>
如果指定了 sizes
,<enhanced:img>
將為較小的設備生成小尺寸圖片,并填充 srcset
屬性。
自動生成的最小圖片寬度為 540px。如果你需要更小的圖片或想要指定自定義寬度,可以使用 w
查詢參數:
<enhanced:imgsrc="./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" />
查看 imagetools 倉庫以獲取完整的指令列表。.
從 CDN 動態加載圖片
在某些情況下,圖片在構建時可能無法訪問 —— 例如,它們可能存儲在內容管理系統或其他地方。
使用內容分發網絡(CDN)可以讓你動態優化這些圖片,并在尺寸方面提供更多靈活性,但可能需要一些設置開銷和使用成本。根據緩存策略,在從 CDN 收到 304 響應之前,瀏覽器可能無法使用資源的緩存副本。構建面向 CDN 的 HTML 允許使用 <img>
標簽,因為 CDN 可以根據 User-Agent
頭部提供適當的格式,而構建時優化必須生成帶有多個源的 <picture>
標簽。最后,某些 CDN 可能會延遲生成圖片,這可能會對低流量且圖片頻繁更改的網站的性能產生負面影響。
CDN 通常可以直接使用,無需任何庫。然而,有許多支持 Svelte 的庫可以讓使用變得更簡單。@unpic/svelte
是一個支持大量提供商的與 CDN 無關的庫。你可能還會發現一些特定的 CDN(如 Cloudinary)有 Svelte 支持。最后,一些支持 Svelte 的內容管理系統(CMS)(如 Contentful、Storyblok 和 Contentstack 都內置了圖像處理支持。
最佳實踐
- 對于每種圖片類型,使用上述討論過的適當解決方案。你可以在一個項目中混合使用這三種解決方案。例如,你可以使用 Vite 的內置處理來為
<meta>
標簽提供圖片,使用@sveltejs/enhanced-img
在主頁上顯示圖片,并使用動態方法顯示用戶提交的內容。 - 考慮通過 CDN 提供所有圖片服務,無論你使用何種圖片優化類型。CDN 通過在全球分發靜態資源副本來減少延遲。
- 原始圖片應具有良好的質量/分辨率,并且寬度應該是顯示寬度的 2 倍,以便支持 HiDPI 設備。圖片處理可以將圖片尺寸縮小以在服務較小屏幕時節省帶寬,但為了放大圖片而創造像素會浪費帶寬。
- 對于遠大于移動設備寬度(大約400px)的圖片,例如占據頁面設計寬度的主圖,指定
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
聲明,控制圖片在頁面上布局方式的實際em
或rem
如果被 CSS 更改可能會有所不同。例如,不要做類似html { font-size: 62.5%; }
這樣的事情,因為瀏覽器預加載器預留的空間現在會比創建后的 CSS 對象模型的實際空間更大。
Svelte 中文文檔
點擊查看中文文檔:SvelteKit 圖片
系統學習 Svelte,歡迎入手小冊《Svelte 開發指南》。語法篇、實戰篇、原理篇三大篇章帶你系統掌握 Svelte!
此外我還寫過 JavaScript 系列、TypeScript 系列、React 系列、Next.js 系列、冴羽答讀者問等 14 個系列文章, 全系列文章目錄:https://github.com/mqyqingfeng/Blog
歡迎圍觀我的“網頁版朋友圈”、加入“冴羽·成長陪伴社群”,踏上“前端大佬成長之路”。