노트

preload·prefetch·preconnect

Resource Hints

프런트엔드#html#performance · 연결된 개념 8개

쉽게 말하면

리소스 힌트는 여행 전날 짐을 싸 두고 택시를 미리 불러 두듯, 브라우저에게 '이건 미리 받아 둬', '이 서버와는 미리 연결해 둬'라고 귀띔하는 방법이에요. 그러면 HTML을 다 읽기 전에 중요한 파일을 받기 시작해요.

비유가 깨지는 곳 무엇을 미리 할지 고르는 게 핵심이에요. prefetch는 다음 페이지용이라 지금 페이지의 히어로 이미지엔 preload를 써야 해요. preload나 preconnect를 남발하면 정작 중요한 리소스와 경쟁해요.

link 태그의 rel로 브라우저에게 "이건 미리 받아 둬", "이 서버와는 미리 연결해 둬"라고 알려 주는 기법. 브라우저가 HTML을 끝까지 읽기 전에 중요한 일을 앞당겨 시작하게 한다.

힌트하는 일대상우선순위
preload지금 페이지에 곧 필요한 파일을 즉시 받음폰트, 핵심 CSS, 히어로 이미지높음
prefetch다음 페이지에 필요할 수도 있는 파일을 한가할 때 받음다음 라우트 JS·데이터가장 낮음
preconnectDNS(Domain Name System) 조회 + TCP(Transmission Control Protocol) 연결 + TLS(Transport Layer Security) 협상까지 미리확실히 쓸 외부 도메인(CDN = Content Delivery Network, 폰트)-
dns-prefetchDNS 조회만 미리쓸 수도 있는 외부 도메인-
<link rel="preload" href="/fonts/main.woff2" as="font" type="font/woff2" crossorigin />
<link rel="preload" href="/hero.jpg" as="image" />
<link rel="preconnect" href="https://cdn.example.com" />
<link rel="prefetch" href="/about" />

dns-prefetch는 DNS 조회만, preconnect는 그 뒤 연결까지 준비한다는 차이다.

자주 하는 실수

  • 히어로 이미지에 prefetch를 걸고 LCP(Largest Contentful Paint) 개선을 기대한다. prefetch는 미래용이라 현재 페이지에는 거의 도움이 안 된다. 현재 페이지라면 preload다 → Core Web Vitals
  • preload를 남발한다. 모두 높은 우선순위로 받으니 정작 중요한 리소스와 경쟁한다. 진짜 핵심 몇 개만 건다
  • preconnect를 많이 건다. 연결은 비용이 있고 오래 안 쓰면 끊긴다. 확실히 쓸 몇 개 도메인만 건다
  • 폰트 preload에 crossorigin을 빠뜨린다. 폰트는 CORS(Cross-Origin Resource Sharing) 모드로 요청되므로 속성이 없으면 두 번 받는다

프레임워크에서

  • Next.js Link는 화면에 보이는 링크의 다음 라우트(JS 청크, RSC 페이로드(React Server Components Payload))를 자동으로 prefetch한다. prefetch={false}로 끌 수 있다
  • Next.js Image의 우선 로드 옵션(버전에 따라 priority 또는 preload)은 rel="preload" 링크를 만든다 → Next.js 16 변경점
  • 코드를 쪼개 놓아야 다음 라우트만 골라 prefetch할 수 있다 → 코드 스플리팅과 동적 임포트

출처: web.dev — Preload critical assets · MDN — rel=preconnect · MDN — rel=prefetch

연결된 개념

이 노트를 가리키는 문서

뜻이 가까운 노트

  • 부분 사전 렌더링(PPR)

    PPR(Partial Prerendering)은 한 라우트를 빌드 때 만든 정적 셸(Static Shell)과 요청 때 채우는 동적 구멍으로 나눠, 셸은 즉시 보내고 구멍은 스트리밍으로 채우는 렌더링 모델이다. Next.js 16에서 Cache Components(cacheComponents: true)를 켜면 기본 동작이다(2026 기준).

  • loading 경계와 레이아웃 끌어올리기

    Next.js App Router에서 loading.tsx는 같은 세그먼트의 page와 그 아래(하위 layout 포함)를 suspense로 감싸지만, **같은 세그먼트의 layout은 감싸지 않는다**. 그래서 데이터를 기다릴 필요가 없는 공통 UI(탭바, 필터 헤더)를 page에서 layout으로 끌어올리면 스켈레톤에 덮이지 않고 처음부터 실제 모습으로 보인다.

  • Pages Router에서 App Router로

    App Router는 Next.js 13에서 도입된 app/ 디렉터리 기반 라우터로, 서버 컴포넌트·중첩 레이아웃(Nested Layouts)·스트리밍을 기본으로 한다. pages/ 기반의 Pages Router에서 옮길 때 바뀌는 생각을 정리한다.

  • 버전 스큐와 정적 자산 오프로드

    버전 스큐(Version Skew)는 새 버전을 배포한 뒤에도 브라우저에 떠 있는 이전 빌드의 클라이언트가 새 서버와 통신하면서 생기는 불일치다. 대표 증상은 이전 HTML이 참조하던 JS 청크를 늦게 불러오려다 404가 나는 ChunkLoadError다.

  • next-intl과 서버 컴포넌트 친화 i18n

    next-intl은 Next.js App Router와 서버 컴포넌트를 전제로 설계된 국제화(Internationalization, i18n) 라이브러리다. 번역 메시지를 React Context가 아니라 요청 단위 설정 함수에서 읽어서, 번역만 쓰는 컴포넌트를 서버 컴포넌트로 남길 수 있다.

보기 옵션