FE Dump

์ด๋ฒˆ ๊ธ€์—์„œ๋Š” Next.js 14 ๋ฒ„์ „์—์„œ Pretendard ํฐํŠธ๋ฅผ ์ ์šฉํ•˜๋Š” ๋ฒ•๊ณผ, ๊ธฐ์กด์— cdn์—์„œ ํฐํŠธ๋ฅผ ์ ์šฉํ•˜๋Š” ๊ฒƒ์— ๋น„ํ•ด์„œ ์–ด๋–ค ์ตœ์ ํ™”๊ฐ€ ์ด๋ฃจ์–ด์ง€๋Š”์ง€ ๋‹ค๋ฃจ๊ฒ ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ Next.js 14์— ๋Œ€ํ•œ ์ž๋ฃŒ๋Š” ํ•œ๊ธ€ํ™”๋œ ๋ฌธ์„œ๊ฐ€ ๋งŽ์ง€ ์•Š์•„์„œ ๋„์›€์„ ๋ฐ›์œผ์‹ค ๋ถ„๋“ค์ด ๋งŽ์œผ์…จ์œผ๋ฉด ์ข‹๊ฒ ์Šต๋‹ˆ๋‹ค.

  1. Pretenard
  2. ์„ค์น˜
  3. tailwindcss์— css varaible๋กœ ๋“ฑ๋กํ•˜๊ณ  ์‚ฌ์šฉํ•˜๊ธฐ
    1. ์‚ฌ์šฉ
  4. Font Optimization
  5. References
  • ์‚ฌ์‹ค์ƒ ํ˜„์—… ํ‘œ์ค€์œผ๋กœ ์ž๋ฆฌ์žก์€ ํ•œ๊ธ€ ํฐํŠธ์ž…๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ ํšŒ์‚ฌ๋“ค์ด ํ”„๋กœ์ ํŠธ์— ์ ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์•„์ด์ฝ˜, ์ˆซ์ž์™€์˜ ๋ฐฐ์น˜๊ฐ€ ์ž์—ฐ์Šค๋Ÿฌ์šด ๊ฒƒ์ด ์žฅ์ ์ž…๋‹ˆ๋‹ค.
  • ํฐํŠธ ๊ตต๊ธฐ๊ฐ€ ๋‹ค์–‘ํ•˜์—ฌ ์„ฌ์„ธํ•œ ํฐํŠธ ์Šคํƒ€์ผ๋ง์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
  • ๋ฌด๋ฃŒ ์ƒ์—…์šฉ ํฐํŠธ๋กœ ๋ˆ„๊ตฌ๋‚˜ ๊ฐ€์ ธ๋‹ค ์“ธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  1. Prendtendard releast note๋กœ ๋“ค์–ด๊ฐ€์„œ ํŒŒ์ผ์„ ๋‹ค์šด๋กœ๋“œ ๋ฐ›์•„์ฃผ์„ธ์š”.
Release note assets
  1. ์••์ถ•์„ ํ’€๊ณ  .../Pretendard-1.3.9/web/variable/woff2/PretendardVariable.woff2 ํŒŒ์ผ์„ ํ”„๋กœ์ ํŠธ ๋””๋ ‰ํ† ๋ฆฌ์— ๋„ฃ์–ด์ฃผ์„ธ์š”. ์ œ ํ”„๋กœ์ ํŠธ์—๋Š” /static/fonts ๋””๋ ‰ํ† ๋ฆฌ์— ๋„ฃ์—ˆ์Šต๋‹ˆ๋‹ค.
Project directory
  1. global font๋กœ ์ ์šฉ์‹œํ‚ค๊ธฐ ์œ„ํ•ด์„œ app/layout.tsx์— className์„ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.

    import localFont from "next/font/local";
    
    const pretendard = localFont({
      src: "../static/fonts/PretendardVariable.woff2",
      display: "swap",
      weight: "45 920",
      variable: "--font-pretendard",
    });
    
    export default function RootLayout({
      children,
    }: Readonly<{
      children: React.ReactNode;
    }>) {
      return (
        <html lang="kr" className={`${pretendard.variable}`}>
          <body className={pretendard.className}>
            <Header />
            {children}
          </body>
        </html>
      );
    }
    

์ „์—ญ์ ์œผ๋กœ ํฐํŠธ๋ฅผ ์ ์šฉ์‹œํ‚ค๋Š” ๋Œ€์‹ ์— ๋ถ€๋ถ„์ ์œผ๋กœ ํฐํŠธ๋ฅผ ์ ์šฉํ•˜๊ณ  ์‹ถ์„ ๋•Œ๋Š” tailwind์˜ css variable์œผ๋กœ ๋“ฑ๋กํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  1. app/layout.tsx์—์„œ ํฐํŠธ์˜ css variable์„ document์— ๋„ฃ์–ด์ค๋‹ˆ๋‹ค.

    import localFont from "next/font/local";
    
    const pretendard = localFont({
      src: "../static/fonts/PretendardVariable.woff2",
      display: "swap",
      weight: "45 920",
      variable: "--font-pretendard",
    });
    
    export default function RootLayout({
      children,
    }: Readonly<{
      children: React.ReactNode;
    }>) {
      return (
        <html lang="kr" className={`${pretendard.variable}`}>
          <body className={pretendard.className}>
            <Header />
            {children}
          </body>
        </html>
      );
    }
    
  2. tailwind.cssconfig.js์—์„œ css variable์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

import type { Config } from "tailwindcss";

const config: Config = {
  content: [
    "./pages/**/*.{js,ts,jsx,tsx,mdx}",
    "./components/**/*.{js,ts,jsx,tsx,mdx}",
    "./app/**/*.{js,ts,jsx,tsx,mdx}",
    "./src/**/*.{js,ts,jsx,tsx,mdx}",
    "./stories/**/*.{js,ts,jsx,tsx,mdx}",
  ],
  theme: {
    extend: {
      fontFamily: {
        pretendard: ["var(--font-pretendard)"],
      },
    },
  },
  plugins: [],
};
export default config;

className์— font-pretendard๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ํฐํŠธ๋ฅผ ์ ์šฉ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

<div className="font-pretendard shrink-0 font-black">ํ”„๋ฆฌํ…๋‹ค๋“œ</div>

์ด ์ฏค์—์„œ ์˜๋ฌธ์ด ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.

.css file์—์„œ font-face attribute๋กœ cdn ํ†ตํ•ด ํฐํŠธ๋ฅผ ๋‹ค์šด๋กœ๋“œ ๋ฐ›์ง€ ์•Š๊ณ  ๊ตณ์ด ์ด๋ ‡๊ฒŒ ๊ตฌํ˜„ํ•ด์•ผ ํ•˜๋Š” ์ด์œ ๊ฐ€ ๋ฌด์—‡์ผ๊นŒ?

Next.js ํŠœํ† ๋ฆฌ์–ผ ๋น„๋””์˜ค์— ๋”ฐ๋ฅด๋ฉด ์ด์— ๋Œ€ํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋‹ต๋ณ€ํ•ด์ค๋‹ˆ๋‹ค.

  • cdn์œผ๋กœ๋ถ€ํ„ฐ ๋‹ค์šด๋กœ๋“œ ๋ฐ›๊ฒŒ ๋˜๋Š” ๊ฒฝ์šฐ์—๋Š” ํด๋ผ์ด์–ธํŠธ์—์„œ custom ํฐํŠธ๋ฅผ ๋‹ค์šด๋กœ๋“œ ๋ฐ›๊ธฐ ์ „๊นŒ์ง€๋Š” ์šด์˜์ฒด์ œ์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ fallback font(Arial ๋“ฑ)๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. custom ํฐํŠธ ๋กœ๋“œ ์ „/๋กœ๋“œ ํ›„์— ํฐํŠธ ์‚ฌ์ด์ฆˆ ํฌ๊ธฐ ์ฐจ์ด๋กœ ์ธํ•ด cumulative layout shift๊ฐ€ ๋ฐœ์ƒํ•˜์—ฌ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ํฌ๊ฒŒ ๋–จ์–ด๋œจ๋ฆฌ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

  • Next.js์˜ next/font๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” font๋ฅผ ๋นŒ๋“œ ํƒ€์ž„ ๋•Œ ํ•œ๋ฒˆ๋งŒ ๋‹ค์šด๋กœ๋“œ ๋ฐ›๊ณ , fallback font๊ฐ€ ์‚ฌ์šฉ๋˜๋Š” ๋™์•ˆ css size-adjust ํ”„๋กœํผํ‹ฐ๋ฅผ ์ ์šฉ์‹œ์ผœ์„œ ๊ธ€์ž ํฌ๊ธฐ๋ฅผ ๋™์ผํ•˜๊ฒŒํ•˜์—ฌ layout shift๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์„ ๋ง‰์•„์ค๋‹ˆ๋‹ค.

์ง์ ‘ ๊ฐœ๋ฐœ์ž ๋„๊ตฌ๋ฅผ ์ผœ๊ณ  ํ™•์ธํ•ด๋ดค์Šต๋‹ˆ๋‹ค. ๋„คํŠธ์›Œํฌ์— throttling์„ ๊ฑธ์–ด์„œ ์ผ๋‹จ custom font๊ฐ€ ๋กœ๋“œ๋˜๊ธฐ ์ „์˜ UI์™€ ๋กœ๋“œ๋œ ํ›„์˜ UI๋ฅผ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค.

  • ๋กœ๋“œ ์ „: ์‹œ์Šคํ…œ ํฐํŠธ๊ฐ€ ์ ์šฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

    Text with fallback font
  • ๋กœ๋“œ ํ›„: Pretendard ํฐํŠธ๊ฐ€ ์ ์šฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

    Text with Loaded font
  • ํŽ˜์ด์ง€์— ์ ‘์†ํ–ˆ์„ ๋•Œ ์ฒ˜์Œ ๋ฐ›์•„์˜ค๋Š” global css file์„ ํ™•์ธํ•ด๋ณด๋‹ˆ, ์ปค์Šคํ…€ ํฐํŠธ๊ฐ€ ๋กœ๋“œ๋˜๋Š” ๋™์•ˆ fallback font์— size-adjust๋ฅผ ์„ค์ •ํ•˜์—ฌ layout shift๋ฅผ ๋ง‰๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

font in devtools
font in devtools2