← Blog
최적화

HTML <link> 태그 — rel 값 하나로 갈리는 CSS · 프리로드 · SEO

📚 한 줄 요약 <link> 태그는 HTML 문서와 외부 리소스를 연결하는 메타 태그로, rel 속성값에 따라 CSS 연결·파비콘·성능 최적화·SEO 등 완전히 다른 기능을 수행한다.


왜 알아야 했나

  • 지도를 렌더링할 때 지도 페이지가 처음에 아님에도 지도 SDK를 미리 백그라운드에서 다운로드받되 처음 페이지가 나타나는 것은 바로 나타날수 있도록 (SDK로 인해 지연이 발생하지 않도록) 하고 싶고 지도 페이지를 들어가면 지도 SDK를 fetch 하는 과정 없이 바로 나타나도록 하고싶었음.

핵심 개념

  • <link>는 빈 태그(self-closing)이며 주로 <head> 안에 위치

  • 가장 중요한 속성은 rel(relationship) — 이 값에 따라 기능이 완전히 달라짐

  • 주요 카테고리: 스타일/아이콘 / 성능 힌트 / SEO / PWA / 네비게이션 / 보안

  • 기본 문법:

    <link rel="관계" href="경로" [추가속성]>
    

rel 값별 분류표

카테고리rel 값목적
스타일stylesheetCSS 파일 연결 (렌더 블로킹)
아이콘icon, apple-touch-icon파비콘, 홈 화면 아이콘
성능preload현재 페이지 필수 리소스 즉시 로드
성능prefetch다음 페이지 리소스 미리 로드
성능preconnect외부 도메인 연결 미리 수립
성능dns-prefetchDNS 조회만 미리
성능modulepreloadES 모듈 preload
SEOcanonical정식 URL 지정 (중복 방지)
SEOalternate다국어, RSS, 모바일 버전
PWAmanifestPWA 매니페스트 연결
네비prev, next페이지네이션 관계

예시 / 코드

1. 스타일시트 연결

<link rel="stylesheet" href="styles.css">
<link rel="stylesheet" href="print.css" media="print">
<link rel="stylesheet" href="mobile.css" media="(max-width: 768px)">

2. 파비콘 / 아이콘

<!-- 일반 파비콘 -->
<link rel="icon" href="/favicon.ico">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32.png">
<link rel="icon" type="image/svg+xml" href="/favicon.svg">

<!-- iOS 홈 화면 아이콘 -->
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">

<!-- 다크모드 대응 -->
<link rel="icon" href="/favicon-dark.svg" media="(prefers-color-scheme: dark)">

3. 성능 최적화 (가장 중요!)

<!-- preload: 현재 페이지에서 곧 쓸 리소스 즉시 로드 -->
<link rel="preload" href="hero.jpg" as="image">
<link rel="preload" href="main.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="critical.js" as="script">

<!-- prefetch: 다음 페이지 리소스 유휴 시간에 미리 로드 -->
<link rel="prefetch" href="/next-page.html">

<!-- preconnect: 외부 도메인과 DNS·TCP·TLS 연결 미리 수립 -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>

<!-- dns-prefetch: DNS 조회만 미리 (preconnect보다 가벼움) -->
<link rel="dns-prefetch" href="https://cdn.example.com">

<!-- ES 모듈 preload -->
<link rel="modulepreload" href="/modules/app.js">

4. SEO

<!-- canonical: 정식 URL 지정 -->
<link rel="canonical" href="https://example.com/article/123">

<!-- 다국어 alternate -->
<link rel="alternate" hreflang="en" href="https://example.com/en/">
<link rel="alternate" hreflang="ko" href="https://example.com/ko/">
<link rel="alternate" hreflang="x-default" href="https://example.com/">

<!-- RSS 피드 -->
<link rel="alternate" type="application/rss+xml" title="Blog RSS" href="/feed.xml">

5. PWA 매니페스트

<link rel="manifest" href="/manifest.json">

6. 보안 (SRI)

<link rel="stylesheet"
      href="https://cdn.example.com/lib.css"
      integrity="sha384-abc123..."
      crossorigin="anonymous">

7. 권장 작성 순서 (<head> 내부)

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">

  <!-- 1. 외부 도메인 연결 미리 -->
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>

  <!-- 2. 중요 리소스 preload -->
  <link rel="preload" href="/fonts/main.woff2" as="font" type="font/woff2" crossorigin>

  <!-- 3. 스타일시트 -->
  <link rel="stylesheet" href="/styles.css">

  <!-- 4. 부가 메타 -->
  <link rel="icon" href="/favicon.svg">
  <link rel="canonical" href="https://example.com/page">
  <link rel="manifest" href="/manifest.json">

  <!-- 5. 우선순위 낮은 prefetch -->
  <link rel="prefetch" href="/next-page-resources.js">
</head>

헷갈렸던 점

  • preload vs prefetch: preload는 _현재 페이지_에서 곧 쓸 리소스, prefetch는 _다음 페이지_용. 이름이 비슷해서 헷갈리기 쉬움
  • preconnect vs dns-prefetch: preconnect는 DNS + TCP + TLS까지 모두 미리 수립, dns-prefetch는 DNS만. preconnect가 더 무겁지만 효과는 큼
  • preload에 as 속성이 필수라는 점 — 빼먹으면 브라우저가 두 번 다운로드해서 오히려 역효과
  • crossorigin 속성 — 폰트 preload나 외부 도메인 preconnect 시 누락하면 동작하지 않음
  • <link><head> 안에만 쓰는 줄 알았는데, HTML5부터 body 안에서도 가능 (단, 권장은 아님)

실무 적용

  • 웹 성능 최적화 (Core Web Vitals 개선)
    • LCP 개선 → 히어로 이미지 preload
    • 폰트 깜빡임(FOUT) 방지 → 웹폰트 preload + preconnect
    • 외부 CDN 사용 시 preconnect로 초기 지연 단축
  • SEO 작업
    • 중복 URL 문제 발생 시 canonical 지정
    • 다국어 사이트 → hreflang이 들어간 alternate 세팅
  • PWA 구현manifest 연결로 설치 가능한 웹앱 제공
  • 블로그/뉴스 사이트 → RSS 피드를 alternate로 노출

관련 작업: [[Core Web Vitals 최적화]] [[웹폰트 로딩 전략]] [[PWA 구축]] [[SEO 메타태그 정리]]


더 공부할 것

  • <link rel="preload">as 속성 전체 종류와 동작 차이
  • HTTP/2 Server Push와 preload의 관계 (그리고 왜 Server Push가 deprecated 됐는지)
  • fetchpriority 속성 (preload와 함께 우선순위 제어)
  • <link rel="prerender"> (페이지 전체 미리 렌더링, 현재는 Speculation Rules API로 대체)
  • Resource Hints 명세와 Priority Hints 명세 차이
  • 브라우저별 preload 지원 범위 및 캐싱 동작

🔗 참고