고양의 성장일기

[HTML] <script> 태그의 적절한 위치를 찾아보자 본문

🖥️ Front-End/HTML

[HTML] <script> 태그의 적절한 위치를 찾아보자

고 양 2025. 9. 19. 20:05
반응형
<script> 태그의 적절한 위치를 찾아보자

<script> 태그는 웹페이지에 영혼을 불어넣어 줄 자바스크립트가 깃드는 매우 중요하고 성스러운 곳이죠.

태그 자체가 중요한 만큼 태그의 위치도 매우 중요한데, 이 태그의 위치에 따라 사용자들은 아무 이질감 없이 웹페이지를 볼 수도, 버벅거리고 고장 난 것 같은 웹페이지를 마주할 수도 있습니다.

 

이번 포스팅에서는 여러 경우에 따른 <script> 태그의 적절한 위치를 탐색해 보도록 하겠습니다.

<head>
    <script></script>
</head>

헤드 태그 내부엔 여러 가지 메타데이터나 CSS 등 HTML 전역 구조와 스타일에 영향을 미치는 요소가 포함됩니다.

같은 맥락으로 아래와 같은 경우 스크립트 태그는 헤드 태그 내부에 위치하게 됩니다.

 

1. 라이브러리를 로드하는 경우

<head>
  <!-- jQuery 라이브러리 로드 -->
  <script src="https://code.jquery.com/jquery-3.6.0.min.js" defer></script>

  <!-- Lodash 같은 유틸리티 라이브러리 -->
  <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js" defer></script>
</head>

2. 소셜미디어 API를 초기화 / 호출

<head>
  <!-- Facebook SDK -->
  <script async defer crossorigin="anonymous"
          src="https://connect.facebook.net/en_US/sdk.js"></script>

  <!-- Twitter 위젯 -->
  <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</head>

3. DOM을 초기화 또는 전역변수 / 함수 선언

<head>
  <script>
    // 전역 설정 변수
    window.APP_CONFIG = {
      apiBaseUrl: "https://api.example.com",
      version: "1.0.0"
    };

    // 페이지 전역에서 사용할 함수
    function formatDate(dateStr) {
      const date = new Date(dateStr);
      return date.toISOString().split("T")[0];
    }
  </script>
</head>

4. SEO 및 Google Analytics와 같은 추적 코드

<head>
  <!-- Google Analytics (GA4) -->
  <script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXX"></script>
  <script>
    window.dataLayer = window.dataLayer || [];
    function gtag(){ dataLayer.push(arguments); }
    gtag('js', new Date());
    gtag('config', 'G-XXXXXXX');
  </script>

  <!-- Google Tag Manager -->
  <script>
    (function(w,d,s,l,i){
      w[l]=w[l]||[];
      w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});
      var f=d.getElementsByTagName(s)[0],
          j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';
      j.async=true;
      j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl;
      f.parentNode.insertBefore(j,f);
    })(window,document,'script','dataLayer','GTM-XXXX');
  </script>
</head>

<body>
    <script></script>
</body>

바디 태그 내에 스크립트 태그가 포함되는 것은 일반적이지 않지만, 바디태그 내부에 스크립트가 위치해야 하는 경우가 있습니다.

광고나 소셜미디어 위젯과 같이 특정 DOM 안에서만 작용해야하는 경우 해당 요소 내부에 스크립트 태그가 배치됩니다.

 

왜 일반적이지 않은지 그 이유는 아래에서 설명하도록 하겠습니다.

<body></body>
<script></script>

가장 일반적이고 좋은 위치입니다.

페이지의 기본 구조를 먼저 파싱하므로 DOM 로딩이 최적화 될 수 있습니다.

HTML 파싱이 마무리되고 스크립트가 실행되므로 이벤트를 핸들링하는 함수나 DOM을 조작하는 함수가 안전하게 실행될 수 있습니다.

 

즉, DOM이나 사용자와 직접적으로 상호작용해야 하는 스크립트라면 바디 태그 이후에 로드되는 것이 안전하고 성능면에서 유리합니다.

태그의 위치는 왜 중요할까?

브라우저는 HTML을 위에서부터 아래로 읽어 내려오며 HTML 파싱을 수행하므로 대부분의 태그는 위치가 정말 중요합니다.

적절한 계층과 적절한 위치에 적절한 태그가 위치한다는 것은 흔히 말하는 '주차가 잘 된 얼굴'과 같은 것이죠.

(저는 DOM을 설명할 때 얼굴에 비유해서 설명하곤 하는데 보통 HTML은 이목구비, CSS는 메이크업, JS는 표정이라고 비유합니다.)

 

그럼 만약 <script> 태그가 부적절한 곳에 위치한다면 어떤 일이 벌어질까요?

  1. 스크립트 로드/실행 중 HTML 파싱이 중단될 수 있음
  2. DOM 관련 이벤트 리스너가 오작동 할 수 있음
  3. DOM이 파싱되지 않은 상태에서 DOM을 조작하는 스크립트가 실행되는 경우 예외가 발생할 수 있음

태그 위치에 따른 HTML 파싱 및 스크립트 실행 순서

대략적인 렌더링 순서를 파악했으니 조금 더 디테일한 렌더링 순서를 타임라인 형식으로 정리해보겠습니다.

 

1. <head> 내부

[브라우저 파싱 시작]
   ↓
<head> 읽음
   ↓
<script> 발견 → JS 파일 다운로드 및 실행 (DOM 파싱 중단됨)
   ↓
JS 실행 완료 후 다시 DOM 파싱 재개
   ↓
<body> 렌더링

2. <body> 내부

[브라우저 파싱 시작]
   ↓
<body> 일부 파싱됨
   ↓
<script> 발견 → 해당 시점에서 DOM 파싱 중단, JS 실행
   ↓
실행 끝나면 다시 DOM 파싱 계속
   ↓
<body> 나머지 렌더링

3. <body> 끝

[브라우저 파싱 시작]
   ↓
<head> 끝남
   ↓
<body> 콘텐츠 파싱 및 렌더링 (사용자는 화면을 볼 수 있음)
   ↓
</body> 바로 위에서 <script> 로드 및 실행
   ↓
DOMContentLoaded 이벤트 발생
위치/속성 렌더링 차단 실행 시점 실행 순서
<head> ✅ 차단 발견 즉시 실행 순서 보장
<body> 내부 ✅ 부분 차단 해당 위치에서 즉시 실행 순서 보장
<body> 끝 ❌ 비차단 DOM 거의 다 파싱된 후 실행 순서 보장

마치며

<script> 태그의 적절한 위치는 태그의 목적과 역할에 따라 달라집니다.

HTML 파싱과 스크립트 실행 순서를 이해하면, 웹페이지 성능과 사용자 경험 개선에 큰 도움이 되기 때문에 알아두면 좋을 것 같습니다.

 

감사합니다!

반응형