[Next.js] SEO를 높이는 방법

jiny·2025년 11월 21일

기술 면접

목록 보기
74/78

🗣️ SEO란 무엇인가요? 그리고 SEO를 높이는 방법은 무엇인가요?

  • 의도: 지원자가 SEO(검색 엔진 최적화)의 개념과 이를 개선하는 방법을 이해하고 있는지 평가
    • SEO의 정의와 중요성을 설명한다.
    • SEO를 개선하는 방법(메타 태그, 정적 사이트 생성, 페이지 로딩 속도 등)을 설명한다.
    • SEO 최적화를 위한 도구와 기법을 설명한다.
  • 주어진 답안 (모범 답안)

    SEO(Search Engine Optimization)검색 엔진에서 웹사이트의 가시성과 순위를 높이는 작업을 의미합니다.
    검색 엔진이 웹사이트를 더 잘 인식하고 평가할 수 있도록 최적화하면, 자연 검색 결과에서 더 높은 순위를 차지할 수 있으며, 이를 통해 더 많은 사용자 유입을 기대할 수 있습니다.
    SEO를 높이기 위해서는 여러 가지 방법이 있습니다.

    첫째, 메타 태그 설정이 중요합니다.
    적절한 <title><meta description> 태그를 사용하면 검색 엔진이 페이지의 내용을 더 쉽게 이해하고, 검색 결과에서 사용자에게 더 매력적으로 보이게 할 수 있습니다.

    둘째, 정적 사이트 생성(SSG, Static Site Generation)을 활용하는 것이 효과적입니다.
    Next.js에서는 getStaticProps를 사용하여 미리 생성된 정적 페이지를 제공할 수 있으며, 이는 검색 엔진이 페이지를 빠르게 크롤링하고 색인할 수 있도록 도와줍니다.

    셋째, 페이지 로딩 속도를 최적화하는 것도 중요한 요소입니다.
    이미지 최적화, 코드 분할, 캐싱, CDN(Content Delivery Network) 활용 등을 통해 로딩 속도를 빠르게 하면, 사용자 경험이 개선될 뿐만 아니라 검색 엔진 순위에도 긍정적인 영향을 줍니다.

    넷째, 키워드 최적화를 신경 써야 합니다.
    사용자 검색 의도에 맞는 키워드를 적절히 배치하면 검색 엔진이 해당 페이지를 더 정확하게 인식할 수 있습니다.

    SEO를 분석하고 최적화하기 위해서는 다양한 도구를 활용할 수 있습니다.
    Google Search Console을 사용하면 웹사이트의 검색 성능을 모니터링하고, 색인 상태를 확인할 수 있습니다.
    Lighthouse를 이용하면 페이지 속도, 접근성, SEO 점수를 평가하여 개선할 수 있는 요소를 찾을 수 있습니다.
    Yoast SEO와 같은 도구는 메타 태그 및 키워드 최적화를 도와줍니다.

    결론적으로, Next.js의 정적 사이트 생성 기능과 빠른 로딩 속도를 활용하고, 메타 태그와 키워드 최적화를 병행하면 SEO를 효과적으로 향상시킬 수 있습니다.


📝 개념 정리

🌟 SEO(Search Engine Optimization)란?

  • 개념
    • 검색 엔진(구글, 네이버 등)에서 내 페이지가 잘 보이도록 만드는 전략
    • 검색 결과에서의 순위를 올려서 더 많은 자연 유입(organic traffic)을 얻는 것
  • 검색 엔진 입장에서는 대략 이런 순서로 페이지를 처리한다.
    1. 크롤링(Crawling): 봇(크롤러)이 링크를 타고 사이트를 돌아다니며 HTML을 가져간다.
    2. 인덱싱(Indexing): HTML 내용(텍스트, 메타 태그, 구조화 데이터 등)을 분석해서 이 페이지는 무슨 내용인지를 검색 인덱스에 기록한다.
    3. 랭킹(Ranking): 특정 키워드로 검색할 때, 어떤 페이지를 상위에 노출할지 점수를 매겨 순위를 정한다.
  • 이때 우리가 손댈 수 있는 부분이 On-Page/Technical SEO이다.
    • On-Page SEO: 제목(title), 설명(description), 본문 텍스트, heading 구조(h1, h2, ...)
    • Technical SEO
      • HTML이 처음 로딩될 때 얼마나 내용이 잘 노출되는지(SSR/SSG 여부)
      • 성능(Core Web Vitals)
      • 모바일 대응
      • URL 구조, sitemap, robots.txt 등

    💡 Next.js SEO는 이 On-page + Technical 부분을 쉽게 제어할 수 있게 도와주는 도구/패턴들의 모음이라고 보면 편하다.


🌟 Next.js와 SEO의 관계

Next.js가 SEO에 강한 이유는 렌더링 전략을 유연하게 선택할 수 있기 때문이다.
Next.js SEO 문서에서는 렌더링 전략을 비교하면서 특히 Static Site Generation(SSG)를 SEO에 가장 유리한 방식으로 소개한다.

  • SSG (Static Site Generation)
    • 빌드 타임에 HTML을 미리 만들어 두고 정적 파일처럼 서빙한다.
    • 크롤러가 접근했을 때 이미 모든 HTML이 들어 있으므로, 크롤링/인덱싱에 최적화되어 있다.
    • 성능도 빠르기 때문에 Core Web Vitals 측면에서 유리하다. → 순위(Ranking)에 플러스 요소
  • SSR (Server Side Rendering)
    • 요청 시마다 서버에서 HTML을 만들어서 반환한다.
    • 크롤러 입장에서는 SSG와 비슷하게 완성된 HTML을 받기 때문에 SEO 측면에서 좋다.
    • 다만 요청마다 렌더링하니 서버 비용/응답 속도 관리가 관건이다.
  • ISR (Incremental Static Regeneration)
    • 기본은 SSG이지만, 일정 주기마다 백그라운드에서 페이지를 재생성한다.
    • 변동이 잦은 콘텐츠(블로그, 뉴스 등)에 좋고, 새로 생성된 HTML도 그대로 SEO에 사용된다.
  • CSR (Client Side Rendering, 순수 SPA에 가까운 패턴)
    • 처음에는 비어 있는 <div id="root"></div> 같은 HTML을 보내고, JS가 실행된 후에야 내용이 채워진다.
    • 예전에는 일부 크롤러가 JS 렌더링을 제대로 못해서 SEO에 불리했지만, 요즘 구글은 웬만하면 렌더링이 가능하다.
    • 그래도 초기 HTML에 콘텐츠가 있는 SSG/SSR보다 유리하다고 보기는 어렵다.

💡 정리하면,

  • 검색 유입이 중요한 페이지(랜딩, 블로그, 제품 상세 등) → SSG/ISR/SSR 우선 고려
  • 로그인 후 대시보드처럼 SEO 필요 없는 페이지CSR 위주로 가도 무방

🌟 Metadata API

Next.js App Router(app/)에서는 기존 next/head 대신 Metadata API로 SEO 관련 메타 태그를 관리한다.
메타데이터를 추가하는 방법은 크게 두 가지이다.

  1. 정적 metadata 객체 export

    // app/(root)/layout.tsx
    import type { Metadata } from "next";
    
    export const metadata: Metadata = {
      title: {
        default: "Phraiz",
        template: "%s | Phraiz",
      },
      description: "AI로 문장을 다듬고 인용을 자동으로 생성해주는 서비스",
    };
    • 이 파일이 담당하는 layout 이하 모든 페이지의 기본 메타 정보가 된다.
    • title.template 덕분에 하위 페이지에서 title: "로그인"만 써도 실제 <title>"로그인 | Phraiz" 형태로 자동 생성된다.
  1. 동적 generateMetadata 함수 export

    // app/post/[slug]/page.tsx
    import type { Metadata } from "next";
    import { getPost } from "@/apis/post";
    
    type Props = { params: { slug: string } };
    
    export async function generateMetadata({ params }: Props): Promise<Metadata> {
      const post = await getPost(params.slug);
      
      return {
        title: post.title,
        description: post.summary,
        openGraph: {
          title: post.title,
          description: post.summary,
          url: `https://example.com/post/${params.slug}`,
          images: [{ url: post.ogImageUrl }],
        },
      };
    }
    
    export default async function PostPage({ params }: Props) {
      const post = await getPost(params.slug);
      ...
    }
    • URL 파라미터나 fetch 결과에 따라 SEO 태그를 동적으로 구성할 때 사용한다.
    • 라우트 파라미터(params.slug)와 서버 데이터(getPost)를 기반으로 각각의 글에 맞는 SEO 정보를 설정한다.
    • App Router는 메타 데이터를 먼저 계산한 다음 해당 페이지를 스트리밍하기 때문에, 크롤러가 봤을 때도 헤드 정보가 적절히 설정된 상태가 된다.

🌟 SEO에서 중요한 메타 태그들

  1. title, description
    검색 결과에서 가장 먼저 보이는 부분이다.
    export const metadata: Metadata = {
      title: "AI 문장 변환 - Phraiz",
      description: "AI로 문장을 더 자연스럽고 명확하게 바꿔보세요. 학습, 리포트, 업무 메일까지 모두 지원합니다.",
    };
    • title: 페이지 내용핵심 키워드를 포함해 간결하게
    • description: 1~2문장으로, 사용자가 "이 페이지에 들어가면 무슨 일을 할 수 있는지"를 설명
  1. openGraph, twitter: 소셜 미리보기
    openGraph와 twitter 설정으로 OG 이미지, 제목, 설명을 포함해 SNS 공유 시 보이는 카드 정보를 구성할 수 있다.
    export const metadata: Metadata = {
      title: "AI 문장 변환 - Phraiz",
      openGraph: {
        title: "AI 문장 변환 - Phraiz",
        description: "AI로 문장을 더 자연스럽게 바꿔보세요.",
        url: "https://www.phraiz.com/paraphrase",
        type: "website",
        images: [
          {
            url: "https://www.phraiz.com/og/paraphrase.png",
            width: 1200,
            height: 630,
            alt: "Phraiz AI 문장 변환 페이지 미리보기",
          },
        ],
      },
      twitter: {
        card: "summary_large_image",
        title: "AI 문장 변환 - Phraiz",
        description: "AI로 문장을 더 자연스럽게 바꿔보세요.",
        images: ["https://www.phraiz.com/og/paraphrase.png"],
      },
    };
    • openGraph: 페이스북, 카카오톡, 슬랙 등 OG 프로토콜 쓰는 서비스들이 주로 읽는 메타 정보
    • twitter: 트위터(현 X) 전용 카드 정보
    • 카카오톡, 슬랙, 트위터 등에서 링크를 붙여 넣었을 때 이 설정들이 적용된다.
    • 서비스 브랜딩, 클릭 유도(CTR)에 크게 영향을 미친다.

      🤔 twitter만 따로 있는 이유

      1. 프로토콜이 아예 다르기 때문
        • Open Graph(OG)
          • 원래 페이스북이 만든 프로토콜
          • 태그 형태: og:title, og:description, og:image
          • 지금은 페이스북, 링크드인, 카카오톡, 핀터레스트 등에서 널리 씀
        • Twitter Card
          • 트위터(X)가 따로 만든 메타데이터 규격
          • 태그 형태: twitter:card, twitter:title, twitter:description, twitter:image
          • Open Graph랑 비슷하지만, card 타입(summary, summarylarge_image 등 같은 트위터 전용 속성이 따로 있음

      ➡️ 즉, "링크 미리보기"라는 목적은 같지만, 태그 이름/필드 구성이 다른 두 개의 표준이 있는 것이다.
      ➡️ 그래서 Next.js도
      openGraphog:* 메타태그 세트
      twittertwitter:* 메타태그 세트
      이렇게 프로토콜 단위로 분리해서 필드를 둔 것이다.

      1. 그냥 openGraph만 쓰면 안될까?
        • 트위터 카드 태그가 없으면, 트위터가 Open Graph 태그로 어느 정도 fallback 해준다.
        • 하지만, 공식 가이드/SEO 글들에서는 가능하면 Open Graph + Twitter Card 둘 다 명시하라고 권장한다.
        • 그 이유는 다음과 같다.
          1. 트위터 전용 옵션을 써야 하는 경우
            • card: "summary_large_image", site, creator 같은 건 OG에 없는 개념이라 openGraph만으로는 표현이 안 된다.
          2. 트위터에서만 다른 카드 모양/텍스트를 쓰고 싶을 때
            • 다른 SNS(카카오톡, 페이스북 등)는 OG용 이미지
            • 트위터는 비율/크롭이 잘 보이는 다른 이미지 → twitter.images에 따로 설정
            • 이런 커스터마이징을 하기 좋게 Next가 필드를 분리해 둔 것이다.
  1. robots: 검색 허용/차단
    민감한 페이지나 어드민, 임시 페이지는 크롤링을 차단할 수 있다.
    export const metadata: Metadata = {
      robots: {
        index: false, // 검색 결과에 노출 금지
        follow: false, // 링크도 따라가지 않음
      },
    };
  1. icons: 파비콘/애플 터치 아이콘 설정

    • icons 필드는 브라우저 탭에 보이는 파비콘, 모바일 홈 화면 아이콘(apple-touch-icon), shortcut icon 등을 한 번에 설정하는 곳이다.

      // app/layout.tsx
      import type { Metadata } from "next";
      
      export const metadata: Metadata = {
        icons: {
          // 일반 파비콘 (브라우저 탭 아이콘)
          icon: "/icons/favicon-32x32.png",
          // shortcut icon (일부 브라우저에서 사용)
          shortcut: "/icons/favicon.ico",
          // iOS 홈 화면 추가용 아이콘
          apple: "/icons/apple-touch-icon.png",
          // 그 외 커스텀 rel
          other: [
            {
              rel: "mask-icon", // Safari pinned tab 등
              url: "/icons/safari-pinned-tab.svg",
              color: "#5bbad5",
            },
          ],
        },
      };

      대략 이런 HTML이 자동으로 나온다.

      <link rel="icon" href="/icons/favicon-32x32.png" />
      <link rel="shortcut icon" href="/icons/favicon.ico" />
      <link rel="apple-touch-icon" href="/icons/apple-touch-icon.png" />
       <link rel="mask-icon" href="/icons/safari-pinned-tab.svg" color="#5bbad5" />
    • 혹은 파일 컨벤션만 두어도 Next.js가 자동으로 <head><link rel="icon" ...>을 만들어 준다.
      • 기본 파비콘: app/favicon.ico
      • 일반 아이콘: app/icon.png, app/icon.jpg, app/icon.svg
      • 애플 터치 아이콘: app/apple-icon.png
  1. alternates: 여러 종류의 대체 URL 정의

    • 태그 종류
      • canonical: 이 페이지의 대표 URL (<link rel="canonical">)
      • languages: 각 언어/지역별 hreflang 링크 (<link rel="alternate" hreflang="...">)
      • media: 특정 미디어 쿼리용 대체 페이지 (모바일 전용 등)
      • types: RSS 같은 다른 타입의 리소스용 (type="application/rss+xml")
    • 예제 1: 기본 canonical만 쓰는 예제

      import type { Metadata } from "next";
      
      export const metadata: Metadata = {
        alternates: {
          canonical: "https://example.com/paraphrase",
        },
      };

      HTML 예시는 대략 다음과 같다.

      <link rel="canonical" href="https://example.com/paraphrase" />
      • canonical동일/유사 콘텐츠가 여러 URL에 있을 때 "대표는 이 URL이다"라고 검색 엔진에 알려주는 역할이다.
    • 예제 2: canonical + hreflang(languages)
      Next.js에서는 hreflang을 직접 쓰는 게 아니라 alternates.languages로 정의하면, 내부적으로 <link rel="alternate" hreflang="...">를 만들어 준다.

      // app/layout.tsx
      import type { Metadata } from "next";
      
      export const metadata: Metadata = {
        metadataBase: new URL("https://example.com"),
        alternates: {
          canonical: "/", // https://example.com
          languages: {
            "en-US": "/en-US",
            "de-DE": "/de-DE",
            "ko-KR": "/ko",
          },
        },
      };

      HTML 예시는 대략 다음과 같다.

      <link rel="canonical" href="https://example.com" />
      <link rel="alternate" hreflang="en-US" href="https://example.com/en-US" />
      <link rel="alternate" hreflang="de-DE" href="https://example.com/de-DE" />
      <link rel="alternate" hreflang="ko-KR" href="https://example.com/ko" />
      • 여기서 hreflang"이 URL은 어떤 언어/지역용 버전인지"를 검색엔진에 알려주는 태그이다.
      • 다국어 사이트에서 각 언어 페이지에 이런 링크를 넣어두면, 구글이 사용자 언어/지역에 맞게 적절한 버전을 보여주기 훨씬 쉬워진다.
    • 예제 3: media, types까지 같이 쓰는 예제

      export const metadata: Metadata = {
        alternates: {
          canonical: "https://nextjs.org",
          languages: {
            "en-US": "https://nextjs.org/en-US",
            "de-DE": "https://nextjs.org/de-DE",
          },
          media: {
            "only screen and (max-width: 600px)": "https://nextjs.org/mobile",
          },
          types: {
            "application/rss+xml": "https://nextjs.org/rss",
          },
        },
      };

      HTML 예시는 대략 다음과 같다.

      <link rel="canonical" href="https://nextjs.org" />
      <!-- hreflang -->
      <link rel="alternate" hreflang="en-US" href="https://nextjs.org/en-US" />
      <link rel="alternate" hreflang="de-DE" href="https://nextjs.org/de-DE" />
      <!-- media (모바일 전용 대체 페이지) -->
      <link
        rel="alternate"
        media="only screen and (max-width: 600px)"
        href="https://nextjs.org/mobile"
      />
      <!-- types (RSS 피드) -->
      <link
        rel="alternate"
        type="application/rss+xml"
        href="https://nextjs.org/rss"
      />

🌟 크롤러 길잡이: robots.txt, sitemap.xml

  1. robots.txt

    • 역할: "어떤 경로는 크롤링해도 되고, 어떤 경로는 하지 마라"를 알려주는 표준 파일

    • App Router에서 두 가지 방식으로 정의할 수 있다.

      1. 정적 파일: app/robots.txt 파일을 직접 만들어두면 해당 내용이 그대로 서빙된다.

      2. 동적 생성: app/robots.ts에서 함수로 정의하면 TypeScript 기반으로 동적으로 robots를 생성할 수 있다.

        // app/robots.ts
        import type { MetadataRoute } from "next";
        
        export default function robots(): MetadataRoute.Robots {
          const baseUrl = process.env.NEXT_PUBLIC_SITE_URL!;
          
          return {
            rules: {
              userAgent: "*",
              allow: "/",
              disallow: ["/admin", "/dashboard"],
            },
            sitemap: `${baseUrl}/sitemap.xml`
          };
        }

        Next.js가 만들어 내는 robots.txt는 대략 다음과 같다.

        User-agent: *
        Allow: /
        
        Disallow: /admin
        Disallow: /dashboard
        
        Sitemap: https://example.com/sitemap.xml
        • 의미: 모든 크롤러에게 사이트 전체는 열어 주되, /admin, /dashboard는 막고, sitemap 위치는 BASE_URL/sitemap.xml이다.
  1. sitemap.xml

    • 역할: "우리 사이트에는 이런 URL들이 있고, 최근 변경일/우선순위는 이렇다"를 검색 엔진에 알려주는 파일

    • App Router에서 두 가지 방식으로 정의할 수 있다.

      1. 정적 파일: app/sitemap.xml 고정 파일

      2. 동적 파일: app/sitemap.ts에서 함수로 정의하면 DB에서 글 목록을 가져와 sitemap을 자동 생성해준다.

        // app/sitemap.ts
        import type { MetadataRoute } from "next";
        import { getAllPosts } from "@/apis/post";
        
        export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
          const posts = await getAllPosts();
          const baseUrl = process.env.NEXT_PUBLIC_SITE_URL!;
          
          const postEntries = posts.map((post) => ({
            url: `${baseUrl}/post/${post.slug}`,
            lastModified: post.updatedAt,
          }));
          
          return [
            { url: baseUrl, lastModified: new Date() },
            ...postEntries,
          ];
        }

        Next.js가 만들어 내는 sitemap.xml은 대략 다음과 같다.

        <urlset ...>
           <url>
             <loc>https://example.com</loc>
             <lastmod>2025-11-21</lastmod>
           </url>
           <url>
             <loc>https://example.com/post/nextjs-seo-guide</loc>
             <lastmod>2025-01-01</lastmod>
           </url>
           ...
        </urlset>

🌟 URL 구조 & 라우팅이 SEO에 미치는 영향

Next.js의 파일 기반 라우팅은 SEO 친화적인 URL을 만들기 좋게 설계되어 있다.

1. 의미 있는 슬러그 사용

  • 숫자 ID보다 슬러그가 좋은 이유
    • 숫자 ID (예: /post/123)
      • 사람 입장: 이 URL만 보고 무슨 글인지 추측 불가
      • 검색엔진 입장: URL에서 얻을 수 있는 단서가 거의 없음
    • 슬러그: (예: /post/nextjs-seo-guide)
      • 사람 입장: Next.js SEO 가이드 글이라는 걸 인식함 → 클릭 확률(CTR)이 올라감
      • 검색엔진 입장: URL 안에 nextjs, seo, guide라는 키워드가 직접 들어 있음페이지 주제를 판단할 때 추가 신호로 사용
        ➡️ SEO에서 URL은 컨텐츠의 주제를 요약하는 짧은 키워드 묶음 정도로 보면 된다.
  • 슬러그 만들 때 기본 원칙
    • 짧고 명확하게: nextjs-seo-guide-for-beginners 정도까지는 괜찮다.
    • 단어는 하이픈(-)으로 구분: /ai-summary-best-practices
    • 불필요한 숫자/파라미터 제거: /post?id=123&lang=ko 대신 /blog/nextjs-seo

2. 폴더 구조 = 정보 구조

  • URL 계층 자체가 카테고리 구조가 된다.
    • 예시: /blog/nextjs/seo
      • 1단계: /blog → 블로그 영역
      • 2단계: /blog/nextjs → Next.js 관련 글 모음
      • 3단계: /blog/nextjs/seo → 그 안에서 SEO 관련 글
    • 이렇게 정보 구조(Information Architecture)가 URL에 그대로 드러난다.
  • 사용자 경험 측면에서도 좋다.
    • URL만 보고도 "지금 어디 서브섹션에 있는지" 감이 오는 구조이다.
    • 브라우저 주소창을 잘라서 /blog/nextjs만 열어 보면, 관련 글 리스트 페이지로 자연스럽게 이어질 수 있다.

3. 중복/파라미터 정리

같은 (혹은 거의 같은) 콘텐츠가 여러 URL로 접근 가능하면 검색엔진이 중복 콘텐츠로 볼 수 있다.
그래서 canonical로 대표 URL을 지정하거나, 파라미터 설계를 신중하게 해야 한다.

  • 어떤 식으로 중복이 생길까?
    • 예시 1: 페이지네이션
      • /blog?page=1
      • /blog?page=2
      • /blog?page=3
    • 예시 2: 정렬/필터
      • /blog?sort=latest
      • /blog?sort=popular
    • 예시 3: 트래킹 파라미터
      • /blog/nextjs-seo-guide?utm_source=facebook
      • /blog/nextjs-seo-guide?utm_source=newsletter&utm_medium=email
    • 사람 눈에는 다 비슷해 보이지만, 검색엔진 입장에서는 모두 다른 URL이다.
    • 페이지가 거의 동일한데 파라미터만 다른 경우, 중복으로 인식해서 평가가 나뉘거나, 원치 않는 URL이 노출될 수 있다.
  • canonical로 대표 페이지를 알려주기
    • 예시: 블로그 글 상세 페이지
      • 실제 접근 URL
        • /blog/nextjs-seo-guide?utm_source=facebook
        • /blog/nextjs-seo-guide?ref=home
      • 대표로 쓰고 싶은 URL: /blog/nextjs-seo-guide
        • 이럴 때 모든 버전에서 <link rel="canonical" href="https://site.com/blog/nextjs-seo-guide" />를 넣어두면,
          "파라미터가 뭘로 붙었든, 이 글의 진짜 대표 URL은 이것이다"라고 검색엔진에게 알려줄 수 있다.

🌟 성능(Core Web Vitals)과 Next.js SEO

요즘은 SEO = 콘텐츠 + 성능(Core Web Vitals)이라고 봐도 될 정도로, 성능이 중요한 랭킹 요소가 되었다.
Next.js SEO 관련 글에서도 SSR/SSG뿐 아니라 LCP, CLS, INP 등 성능 지표를 최적화하는 전략이 강조된다.

  • Next.js에서 도움 되는 것들
    1. next/image
      자동 이미지 최적화(리사이즈, WebP, lazy loading) ➡️ LCP 개선
    2. dynamic import, code splitting
      next/dynamic으로 무거운 컴포넌트를 지연 로딩 ➡️ 초기 JS 줄이기
    3. 데이터 캐싱, revalidate
      export const revalidate = 60같은 설정으로 ISR 사용 ➡️ 자주 바뀌지 않는 데이터는 캐시
    4. App Router SSR + Streaming
      필요한 부분만 서버에서 렌더링해 스트리밍 ➡️ 사용자와 크롤러 모두에게 더 빠른 첫 화면 제공
  • SEO 측면에서 특히 중요한 지표
    • LCP(Largest Contentful Paint): 큰 콘텐츠(히어로 이미지, 메인 헤더)가 얼마나 빨리 보이는지
    • CLS(Cumulative Layout Shift): 레이아웃이 얼마나 덜 움직이는지
    • INP(Interaction to Next Paint): 유저가 클릭/입력했을 때의 반응 속도

0개의 댓글