優化字體與圖片

在上一章中,您學習了如何為 Next.js 應用程式添加樣式。現在我們將繼續完善首頁,加入自訂字體與主視覺圖片。

為何需要優化字體?

字體在網站設計中扮演重要角色,但使用自訂字體可能會影響效能,因為需要獲取並載入字體檔案。

累積版面位移 (CLS) 是 Google 用來評估網站效能與使用者體驗的指標。當瀏覽器最初以備用或系統字體渲染文字,隨後載入自訂字體時進行替換,就會發生版面位移。這種替換可能導致文字大小、間距或版面發生變化,進而影響周圍元素。

模擬頁面初次載入的 UI,展示自訂字體載入時的版面位移情況

當您使用 next/font 模組時,Next.js 會自動優化應用程式中的字體。它會在建置時下載字體檔案並與其他靜態資源一同托管。這意味著使用者訪問您的應用程式時,無需額外的網路請求來獲取字體,從而提升效能。

添加主要字體

讓我們為應用程式添加一個 Google 字體來了解其運作方式。

/app/ui 資料夾中,新建一個名為 fonts.ts 的檔案。此檔案將用於存放整個應用程式中使用的字體。

next/font/google 模組導入 Inter 字體——這將是您的主要字體。然後,指定要載入的子集,此處選擇 'latin'

/app/ui/fonts.ts
import { Inter } from 'next/font/google';
 
export const inter = Inter({ subsets: ['latin'] });

最後,將字體添加到 /app/layout.tsx 中的 <body> 元素:

/app/layout.tsx
import '@/app/ui/global.css';
import { inter } from '@/app/ui/fonts';
 
export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body className={`${inter.className} antialiased`}>{children}</body>
    </html>
  );
}

Inter 添加到 <body> 元素後,字體將應用於整個應用程式。此處還添加了 Tailwind 的 antialiased 類別來平滑字體。雖然此類別非必要,但能提升視覺效果。

在瀏覽器中開啟開發者工具並選擇 body 元素,您應該會在樣式中看到 InterInter_Fallback 已應用。

練習:添加次要字體

您也可以為應用程式的特定元素添加字體。

現在輪到您了!在 fonts.ts 檔案中,導入名為 Lusitana 的次要字體,並將其傳遞給 /app/page.tsx 檔案中的 <p> 元素。除了像之前一樣指定子集外,還需指定不同的字體粗細,例如 400(正常)和 700(粗體)。

完成後,展開以下程式碼片段查看解決方案。

提示:

最後,<AcmeLogo /> 元件也使用了 Lusitana。之前被註解掉以避免錯誤,現在您可以取消註解:

/app/page.tsx
// ...
 
export default function Page() {
  return (
    <main className="flex min-h-screen flex-col p-6">
      <div className="flex h-20 shrink-0 items-end rounded-lg bg-blue-500 p-4 md:h-52">
        <AcmeLogo />
        {/* ... */}
      </div>
    </main>
  );
}

太棒了,您已為應用程式添加了兩種自訂字體!接下來,讓我們為首頁添加主視覺圖片。

為何需要優化圖片?

Next.js 可以透過頂層的 /public 資料夾提供靜態資源,例如圖片。/public 中的檔案可以在應用程式中引用。

使用常規 HTML 時,您會這樣添加圖片:

<img
  src="/hero.png"
  alt="展示儀表板專案桌面版的截圖"
/>

但這意味著您需要手動:

  • 確保圖片在不同螢幕尺寸下具有響應性。
  • 為不同裝置指定圖片尺寸。
  • 防止圖片載入時的版面位移。
  • 延遲載入使用者視窗外的圖片。

圖片優化是網頁開發中的一大主題,甚至可以視為一門專業。與手動實現這些優化不同,您可以使用 next/image 元件自動優化圖片。

<Image> 元件

<Image> 元件是 HTML <img> 標籤的擴展,具有自動圖片優化功能,例如:

  • 自動防止圖片載入時的版面位移。
  • 調整圖片尺寸以避免向較小視窗的裝置傳送過大圖片。
  • 預設延遲載入圖片(圖片進入視窗時才載入)。
  • 在瀏覽器支援時提供現代格式的圖片,如 WebPAVIF

添加桌面版主視覺圖片

讓我們使用 <Image> 元件。查看 /public 資料夾,您會發現有兩張圖片:hero-desktop.pnghero-mobile.png。這兩張圖片完全不同,將根據使用者裝置是桌面還是行動裝置來顯示。

/app/page.tsx 檔案中,從 next/image 導入元件,然後在註解下方添加圖片:

/app/page.tsx
import AcmeLogo from '@/app/ui/acme-logo';
import { ArrowRightIcon } from '@heroicons/react/24/outline';
import Link from 'next/link';
import { lusitana } from '@/app/ui/fonts';
import Image from 'next/image';
 
export default function Page() {
  return (
    // ...
    <div className="flex items-center justify-center p-6 md:w-3/5 md:px-28 md:py-12">
      {/* 在此添加主視覺圖片 */}
      <Image
        src="/hero-desktop.png"
        width={1000}
        height={760}
        className="hidden md:block"
        alt="展示儀表板專案桌面版的截圖"
      />
    </div>
    //...
  );
}

此處,您將 width 設為 1000height 設為 760 像素。最佳實踐是設定圖片的 widthheight 以避免版面位移,這些值應與原始圖片的寬高比完全相同。這些值並非圖片渲染的尺寸,而是用於理解寬高比的實際圖片檔案尺寸。

您還會注意到 hidden 類別用於在行動裝置上隱藏圖片,而 md:block 類別用於在桌面裝置上顯示圖片。

現在您的首頁應該如下所示:

具有自訂字體和主視覺圖片的首頁樣式

練習:添加行動版主視覺圖片

現在輪到您了!在剛剛添加的圖片下方,為 hero-mobile.png 添加另一個 <Image> 元件。

  • 圖片的 width 應為 560height 應為 620 像素。
  • 它應在行動裝置上顯示,在桌面上隱藏——您可以使用開發者工具檢查桌面和行動圖片是否正確切換。

完成後,展開以下程式碼片段查看解決方案。

太棒了!您的首頁現在擁有自訂字體和主視覺圖片。

推薦閱讀

關於這些主題還有更多內容值得學習,包括優化遠端圖片和使用本地字體檔案。如果您想深入了解字體與圖片,請參考:

On this page