透過超過 100 個訣竅來學習 Nuxt!
發佈·  

Nuxt Icon v1 介紹

探索 Nuxt Icon v1 - 為您的 Nuxt 專案量身打造的現代、多功能且可客製化的圖示解決方案。

圖示對於現代網路介面至關重要。它們簡化了導航、釐清了功能並增強了視覺吸引力。然而,有效實施圖示會遇到一些挑戰,例如可擴展性、動態載入和伺服器端渲染 (SSR) 的相容性。

為了應對這些挑戰,我們開發了 Nuxt Icon v1 — 專為 Nuxt 專案量身打造的多功能現代解決方案。透過建立在既有的圖示渲染技術並引入創新的方法,Nuxt Icon 彌合了效能、可用性和彈性之間的差距。

在這篇文章中,我們將探討圖示渲染的挑戰、圖示解決方案的演變,以及 Nuxt Icon 如何結合這些方法的優點,為開發人員提供無縫的體驗。


為什麼圖示具有挑戰性?

乍看之下,圖示似乎很簡單 — 它們本質上只是微小的圖像元素,可以增強使用者介面,提供視覺提示並提高可用性。

Icons Showcases

然而,從工程的角度來看,它們帶來了一些挑戰。理想的圖示應該是

  • 可著色的:能夠適應主題和配色方案。
  • 可縮放的:能夠以各種大小和解析度清晰地渲染。
  • 可管理的:圖示集可能包含數百甚至數千個圖示。
  • 高效打包的:盡量減少網路請求。
  • 最佳載入的:會影響應用程式效能和使用者體驗。
  • 動態的:支援動態載入使用者產生或執行階段定義的圖示。

Engineering Challenges with Icons

要滿足所有這些需求,需要一個精心設計的解決方案,以平衡各項權衡。讓我們探討圖示解決方案的演變以及它們如何應對這些挑戰。


圖示解決方案的歷程

多年來,開發人員嘗試了各種技術來有效地渲染圖示。讓我們探討這些解決方案的演變以及它們面臨的挑戰。

1. <img> 標籤:早期

最直接的解決方案:使用 <img> 標籤。這是網路早期常用的方法。

您可以託管您的圖像資源,並使用 <img> 標籤連結到該圖像,並指定其寬度和高度。它很簡單,不需要任何設定或執行階段依賴項,並且可以在瀏覽器中原生使用。

Solution 1

然而,這方法有一些缺點。圖像可能會出現像素化、缺乏色彩控制,並且無法很好地縮放。每個圖示都是單獨的圖像檔案,會導致許多網路請求,這可能會很慢,尤其是在 HTTP 1.1 時代。在下載圖像之前,您可能會看到閃爍的不可見圖示,這可能會損害使用者體驗。最後,寫起來非常冗長,因為您需要指定圖像的完整路徑並管理相對路徑。這說明了為什麼這種方法在現代網站上很少使用。


2. 網頁字型:圖示字型

作為圖示演變的下一步,網頁字型成為一種流行的解決方案。字型本身是向量化的且可著色的,使其自然適用於圖示。

圖示集提供者通常會將其圖示編譯成一個特殊的字型檔案,並為每個圖示分配一個唯一的 Unicode 字元。這還附帶一個 CSS 檔案,將這些 Unicode 值映射到特定的圖示類別。

這種方法的優點很明顯:它易於使用、可著色、可縮放,並且只需要單次請求即可載入所有圖示。

Solution 2

然而,也有一些缺點。預先載入大型字型檔案可能會很慢,而且自訂圖示集具有挑戰性。此外,您可能會在字型載入之前體驗到閃爍的不可見圖示,因為沒有可用的回退字型。


3. 行內 SVG:基於元件的圖示

隨著現代前端框架的出現,重複使用 HTML 元素變得更加容易。這導致了直接將 SVG 標籤內嵌為元件的想法。

為了支援這種方法,許多圖示集都提供了為每個框架量身定制的包裝程式包。例如,MDI 圖示使用共享元件並將圖示資料作為 props 傳遞,而 Tabler 圖示則為每個圖示提供專用元件。

由於這些是 SVG,因此它們本質上是可著色的、可縮放的,並且保留了 SVG 的所有功能。通常,圖示會被捆綁到應用程式中,從而消除了額外的網路請求,並確保它們對 SSR 友好並且在首次渲染時可見。

Solution 3

但是,這種方法也有其缺點。它會產生大量的 SVG DOM 元素,當使用許多圖示時,這會影響效能。它還會增加捆綁包的大小,並且需要針對每個圖示集和框架組合提供特定的整合支援,從而導致一定程度的供應商鎖定。這使得切換到不同的圖示集或框架變得具有挑戰性。

儘管有這些權衡,但這種方法今天被廣泛採用,因為對於大多數專案來說,切換圖示集或框架並不是頻繁的必要條件。


4. Iconify 執行階段:動態 API 存取

Iconify 透過聚合 100 多個集合中的 200,000 多個圖示,徹底改變了圖示的使用方式。它的執行階段解決方案透過 API 動態提取圖示,無需預先捆綁即可動態存取任何圖示。

這非常適合從使用者提供的內容或其他您在建置時不知道的動態內容中渲染圖示。而且它非常容易設定,因為您甚至可以在沒有任何建置工具的情況下將其用作 CDN。

Solution 4

雖然這種方法提供了很大的彈性,但也帶來了一些權衡。它引入了執行階段依賴項,這意味著圖示只有在 JavaScript 載入並提取圖示資料後才會呈現。這種方法還對伺服器端渲染 (SSR) 和快取層(例如在漸進式網頁應用程式 (PWA) 中使用的那些)構成挑戰。


5. 隨需元件圖示

透過 Iconify 的統一介面和 Vite 的隨需方法,我們開發了 unplugin-icons。這個工具允許您隨需匯入任何圖示作為元件。

作為 unplugin,它支援所有流行的建置工具,包括 Vite、webpack 和 rspack。我們為 Vue、React、Svelte 和 Solid 等流行的框架提供編譯器。透過 Iconify,您可以在任何框架中使用任何圖示,從而最大程度地減少供應商鎖定。

Solution 5

雖然此技術與先前的元件圖示解決方案具有相同的優缺點,但與建置工具的整合使我們能夠提供完整的 Iconify 集合,同時僅運送您實際使用的圖示。但是,執行階段問題(例如 DOM 元素管理)仍然存在。


6. 純 CSS 圖示

作為開發 UnoCSS 的副作用,我們發現了完全將圖示嵌入 CSS 中的潛力,這導致了 純 CSS 圖示的創新解決方案。

這種方法涉及將 SVG 圖示內嵌為資料 URL,並提供單個類別來顯示圖示。經過一些調整,這些圖示變得可著色、可縮放,甚至能夠顯示 SVG 動畫。

瀏覽器可以快取 CSS 規則,每個圖示僅需要 一個 DOM 元素 來渲染。這種方法將圖示與單個 CSS 檔案一起運送,無需額外請求。由於它是純 CSS,圖示會與 UI 的其餘部分一起顯示,不需要任何執行階段,並且可以自然地與 SSR 配合使用 — 您的伺服器不需要在伺服器端進行任何額外的工作。

Solution 6

唯一的缺點是 SVG 內部元素缺乏完全的自訂,以及需要在建置時捆綁圖示,這不是動態的。


在 Nuxt 中整合的挑戰

雖然我會說 純 CSS 圖示隨需元件圖示對於大多數靜態使用來說已經足夠了,但作為一個功能齊全的框架,Nuxt 在有效整合圖示方面有更多要求

  • SSR/CSR:Nuxt 在伺服器端渲染 (SSR) 和用戶端渲染 (CSR) 模式下工作。我們非常關心最終使用者體驗,並且希望確保圖示可以立即渲染而不會閃爍。
  • 動態圖示:在像 Nuxt Content 這樣的整合中,內容可以在執行階段提供或來自外部來源,而我們在建置時並不知道。我們希望確保我們有能力很好地與這些情況整合。
  • 效能:我們希望確保圖示可以有效捆綁,並且圖示的載入已針對最佳效能進行最佳化。
  • 自訂圖示:雖然 Iconify 提供了廣泛的圖示可供選擇,但我們也知道專案擁有自己的圖示集或想要使用 Iconify 中不可用的付費圖示是很常見的。支援自訂圖示對於我們的使用者至關重要。

Nuxt Integration Challenges and Solutions

考慮到這些要求,讓我們重新審視我們之前討論的解決方案,看看它們如何堆疊起來。

對於動態圖示,Iconify 執行階段是一個可行的選擇。它允許動態提取圖示,使其適合在建置時未知的內容。但是,它也有其缺點。對執行階段依賴項的依賴意味著它無法與 SSR 無縫整合,並且它不支援自訂圖示,因為請求會定向到 Iconify 的伺服器,而這些伺服器無法存取我們的本機圖示設定。

相反,純 CSS 圖示提供了卓越的效能和 SSR 相容性。它們可確保圖示立即渲染而不會閃爍,並且可以有效捆綁。但是,當涉及到動態圖示時,它們會縮短,因為它們需要在建置時捆綁並且缺乏適應執行階段內容變更的彈性。

平衡這些權衡確實具有挑戰性。那麼,為什麼不利用這兩種方法的優勢呢?透過了解這些權衡,我們可以更好地了解 Nuxt Icon v1 提供的平衡解決方案。


Nuxt Icon v1 介紹:兩個世界的平衡

憑藉 Nuxt 模組系統的靈活性,Nuxt Icon 結合了兩個世界的優點:CSS 圖示的即時渲染和 Iconify 圖示的動態提取。這種雙重方法提供了一個多功能、現代且可自訂的圖示解決方案,可以無縫適應您專案的需求。

雙重渲染模式

為了應對渲染方法中的權衡,Nuxt Icon 引入了一個多功能的 <Icon> 元件,該元件同時支援 CSS 和 SVG 模式,這兩種模式都對 SSR 友好。根據您的自訂需求,您可以在每個圖示的這些模式之間切換。

在 CSS 模式下,圖示在 SSR 期間包含在 CSS 中,確保它們可以立即渲染而不會產生任何執行階段成本。在 SVG 模式下,圖示在 SSR 期間以 HTML 內嵌,提供相同的即時渲染優勢。這兩種方法都確保圖示在初始螢幕上顯示時不會有任何延遲,從而提供無縫的使用者體驗。

Dual rendering mode


圖示捆綁

動態圖示帶來了獨特的挑戰,尤其是在有效載入它們時。為了應對這一點,我們利用 Iconify 的 API,這使我們能夠透過網路請求按需提供任何圖示。但是,僅依賴此 API 可能會導致延遲,尤其是當伺服器在地理位置上與您的使用者相距甚遠時。

為了緩解這個問題,我們引入了圖示捆綁的概念。我們可以將常用的圖示直接捆綁到 Client Bundle 中。這樣可以確保這些圖示能立即渲染,而無需額外的網路請求。然而,由於可能會增加捆綁包的大小,因此捆綁所有可能的圖示是不可行的。

鑒於 Nuxt 是一個全端框架,我們可以透過引入 Server Bundle 來取得平衡。在伺服器端,捆綁包的大小問題較小,允許我們包含更廣泛的圖示集。在 SSR 期間,可以快速取得這些圖示並根據需要將其傳送到客戶端。此設定可確保常用圖示的高效能,同時仍保有從 Iconify 服務任何圖示作為後備的彈性。

透過結合客戶端捆綁靜態圖示和伺服器端捆綁動態圖示,我們可以在效能和彈性之間實現最佳平衡。

Icon Bundles in Nuxt Icons


資料流

以下是一個資料流程圖,說明 Nuxt Icon 如何請求圖示資料

  1. 您使用 <Icon> 元件並提供圖示的 name
  2. Nuxt Icon 會先檢查圖示是否在 Client Bundle 或 SSR payload 中(在 SSR 時已知的圖示將會出現在 payload 中)。如果是,則會立即渲染圖示。
  3. 如果圖示在客戶端不可用,Nuxt Icon 將會從您的 Nuxt 應用程式一起提供的伺服器 API 取得圖示資料。在伺服器端點內部,它會查詢 Server Bundle,以查看圖示是否可用。
  4. 在此期間,會有多個快取系統參與。伺服器端點快取、HTTP 快取和客戶端快取,以確保快速有效地取得圖示。由於圖示資料不會經常變更,我們使用硬快取策略來確保最佳效能。
  5. 當客戶端和伺服器都不知道圖示(動態圖示)時,伺服器端點將會回退到 Iconify API 來取得圖示資料。由於伺服器端點已快取,因此無論有多少客戶端請求,Iconify API 都只會針對每個唯一圖示呼叫一次,以節省雙方的資源。

Nuxt Icon Requesting Data flow

這種分層方法可確保有效率地傳遞圖示,平衡速度和彈性,同時盡可能地動態化,並平衡每種解決方案之間的權衡取捨。


立即試用 Nuxt Icon

Nuxt Icon v1 代表了圖示渲染多年創新的集大成。無論您是在建構動態應用程式、靜態網站還是介於兩者之間的任何內容,Nuxt Icon 都能適應您的需求。

透過執行以下命令,可以輕鬆地將 Nuxt Icon 新增至您的專案

npx nuxi module add icon

然後,在您的 Vue 元件中匯入 <Icon> 元件,並按照 Iconify 的慣例提供圖示的 name

<template>
  <Icon name="ph:arrow-down-duotone" />
</template>

透過 文件探索更多內容,試用其功能,並讓我們知道您的想法。我們很期待看到 Nuxt Icon 如何改變您的專案!

祝您 Nuxting 愉快 ✨