跳至內容

3

優化字體和圖片

在上一章中,您學習了如何設定 Next.js 應用程式的樣式。讓我們繼續製作您的首頁,加入自訂字體和首頁圖片。

本章節內容...

以下是我們將涵蓋的主題

如何使用 next/font 加入自訂字體。

如何使用 next/image 加入圖片。

Next.js 如何優化字體和圖片。

為何要優化字體?

字體在網站設計中扮演著重要的角色,但如果專案中的自訂字體檔案需要被擷取和載入,則可能會影響效能。

累積版面配置偏移是 Google 用來評估網站效能和使用者體驗的指標。對於字體而言,版面配置偏移的發生是因為瀏覽器最初會以後備或系統字體顯示文字,然後在自訂字體載入後再替換掉。這種替換可能會導致文字大小、間距或版面配置發生變化,進而使其周圍的元素也發生偏移。

Mock UI showing initial load of a page, followed by a layout shift as the custom font loads.

當您使用 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> 元素。除了像之前一樣指定子集之外,您還需要指定字體的**粗細**。

準備好後,展開下方的程式碼片段以查看解答。

提示

  • 如果您不確定要傳遞哪些粗細選項給字體,請檢查程式碼編輯器中的 TypeScript 錯誤。
  • 造訪 Google Fonts 網站並搜尋 Lusitana 以查看可用的選項。
  • 請參閱新增多個字體的說明文件,以及完整選項列表

最後,<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="Screenshots of the dashboard project showing desktop version"
/>

然而,這表示您必須手動:

  • 確保您的圖片在不同螢幕尺寸上都能響應式調整。
  • 為不同裝置指定圖片大小。
  • 防止圖片載入時版面跳動。
  • 延遲載入使用者視埠外的圖片。

圖片最佳化是網頁開發中的一大主題,本身可以被視為一門專業。您可以使用 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">
      {/* Add Hero Images Here */}
      <Image
        src="/hero-desktop.png"
        width={1000}
        height={760}
        className="hidden md:block"
        alt="Screenshots of the dashboard project showing desktop version"
      />
    </div>
    //...
  );
}

在這裡,您將 width 設定為 1000 像素,將 height 設定為 760 像素。設定圖片的 widthheight 以避免版面配置偏移是一個好習慣,這些應該與原始圖片的長寬比**完全相同**。

您還會注意到 hidden 類別會從行動裝置螢幕的 DOM 中移除圖片,而 md:block 則會在桌面版螢幕上顯示圖片。

這是您的首頁現在的樣子

Styled home page with a custom font and hero image

練習:新增行動版首頁圖片

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

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

準備好後,展開下方的程式碼片段以查看解答。

太好了!您的首頁現在有自訂字體和首頁圖片。

關於這些主題還有很多可以學習,包括優化遠端圖片和使用本地字體檔案。如果您想深入了解字體和圖片,請參閱

您已完成此章節3

您已學習如何使用 Next.js 優化字體和圖片。

下一步

4:建立佈局和頁面

讓我們使用巢狀佈局和頁面來建立您的儀表板路由!