본문 바로가기
Web Frontend

HTML파일에서 JS파일을 효과적으로 가져오는 법

by 코라채 2025. 1. 4.
728x90

Html 파일에서 효율적으로 js파일 가져오기

 

프론트엔드 개발자로서 성능 최적화는 중요한 과제입니다. HTML 문서에서 JavaScript 파일을 가져올 때, script 태그의 기본 동작과 함께 HTML5에 추가된 deferasync 속성을 활용하면 로딩 속도를 개선하고 성능을 최적화할 수 있습니다. 이번 포스팅에서는 각각의 개념과 올바른 사용 예시를 간단하게 알아봅시다.

🔖 HTML 코드는 위에서부터 아래로 파싱됩니다.

script 태그의 기본 동작

HTML로 파일을 작성할 때 script태그를 사용해 JS 파일을 불러올 수 있습니다. 브라우저가 HTML 파일을 위에서부터 아래로 순차적으로 파싱하면서 <script>태그를 만나면 HTML 문서의 파싱을 멈추고 JavaScript 파일을 다운로드하여 실행한 후 나머지 HTML을 계속 파싱합니다.

<script src="app.js"></script>

🔧 script 태그의 문제점 알기

script 태그를 head 태그에 위치하거나 body 태그 최상단에 넣을 경우 HTML이 다 파싱되기 전에 DOM요소를 제어하려는 script태그 내에 js 코드를 만나게 되면서 문제가 발생하게 됩니다. 또한 렌더링 과정에서 대규모 JavaScript파일이나 CSS파일과 같은 특정 리소스를 다운로드 될 때 해당 파일이 실행될 때까지 HTML 문서의 파싱이 멈추게 되면서 렌더링이 멈추는 현상이 발생하게 됩니다 ( = 렌더링 블로킹 문제 발생) 또한 스크립트 로드와 실행 중 HTML 파싱이 멈춘다게되면서 대규모 스크립트 파일이 로드되면 사용자 경험(UX)에 저하시킵니다.

<!DOCTYPE html>
<html lang="ko">
  <head>
    <script src="app.js"></script>
  </head>
  <body>
    <div id="content">이곳에 텍스트가 추가됩니다.</div>
  </body>
</html>
// app.js
document.getElementById('content').textContent = 'Hello, world!';

해당 코드의 문제점은 외부 JavaScript 파일(app.js)이 DOM 요소 #content를 조작하려 하지만, HTML이 아직 완전히 파싱되지 않아 DOM 요소를 찾을 수 없어 문제가 발생합니다. 해당 문제를 해결하는 방법은 크게 두 가지가 있는데, script 태그를 body코드 최 하단에 위치시키거나 DOMContentLoaded 이벤트를 활용하거나 defer, async 속성을 사용하는 방법이 있습니다.

✔️ script 로드 해결 방법

HTML5에 이전에는 body 태그 최 하단에 <script> 태그를 넣거나 load 이벤트를 사용해 DOM 준비 이후 스크립트를 실행하여 해결하였습니다. 하지만 HTML5 에서 defer, async 속성으로 비동기 script 로드가 가능해져 이러한 문제를 더 간단하게 해결할 수 있게 되었습니다. 이전 해결방식으로 순차적으로 알아보겠습니다.

1. body 태그 최 하단에 script 태그 넣기

<script> 태그를 body 태그 끝에 배치해 HTML 파싱이 끝난 후 스크립트 로드되도록 합니다.

<!DOCTYPE html>
<html lang="ko">
  <head>

  </head>
  <body>
    <div id="content">이곳에 텍스트가 추가됩니다.</div>
    <script src="app.js"></script>
  </body>
</html>

2. load 이벤트 리스너 등록하기

  • window.onload : HTML, CSS, 이미지 등 모든 리소스가 로드된 후 실행됩니다.
<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8">
    <title>window.onload 예제</title>
  </head>
  <body>
    <img src="https://via.placeholder.com/150" alt="이미지 예제" />
    <button id="btn">클릭하세요</button>
    <script>
      window.onload = function () {
        const btn = document.getElementById('btn');
        btn.addEventListener('click', function () {
          alert('Hello, window.onload!');
        });
      };
    </script>
  </body>
</html>
  • DOMContentLoaded : HTML 파싱이 완료된 후 외부 리소스(이미지, 스타일시트 등) 로딩은 기다리지 않아 즉시 스크립트를 실행할 수 있습니다.
<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8">
    <title>DOMContentLoaded 예제</title>
  </head>
  <body>
    <button id="btn">클릭하세요</button>
    <script>
      document.addEventListener('DOMContentLoaded', function () {
        const btn = document.getElementById('btn');
        btn.addEventListener('click', function () {
          alert('Hello, DOMContentLoaded!');
        });
      });
    </script>
  </body>
</html>

DOMContentLoaded과 window.onload의 차이

특징 DOMContentLoaded window.onload
실행 시점 DOM이 준비된 직후 모든 리소스 로드 완료 후
속도 더 빠름 느림
외부 리소스 의존성 여부 없음 있음
사용 사례 DOM 조작 작업 이미지나 스타일 로드 후 작업
  • DOM 준비만 필요하다면 DOMContentLoaded, 전체 리소스 로드 후 작업이 필요하다면 window.onload를 사용할 수 있습니다. 상황에 맞게 script파일을 분리하여 사용하도록 합니다.

🔖 HTML5의 script 로드 해결 방법

HTML5에서는 defer async 속성을 통해 비동기 script 로드로 해결할 수 있습니다.

✔️ defer 속성

defer는 스크립트를 비동기로 다운로드하면서도 HTML 파싱을 차단하지 않는 속성입니다.
HTML 파싱이 완료된 후, 스크립트가 정의된 순서대로 실행됩니다.

<script src="app.js" defer></script>

특징

  • 스크립트 파일 다운로드는 비동기로 이루어짐.
  • HTML 파싱 완료 후 실행되므로 DOM이 완전히 준비된 상태에서 스크립트 실행 가능.
  • 스크립트가 정의된 순서를 보장함.

사용 예시

  • DOM 의존성이 있는 스크립트(예: DOM 조작 코드).
  • 실행 순서가 중요한 여러 스크립트.

✔️ async 속성

async는 스크립트를 비동기로 다운로드하면서도, HTML 파싱과 별개로 다운로드가 완료되는 즉시 실행합니다.
이는 defer와 달리 스크립트 실행 순서가 보장되지 않습니다.

<script src="analytics.js" async></script>

특징

  • 스크립트 파일 다운로드는 비동기로 이루어짐.
  • 다운로드가 완료되면 즉시 실행되므로 HTML 파싱이 일시적으로 멈출 수 있음.
  • 실행 순서가 중요하지 않은 스크립트에 적합 ( 실행 순서가 보장되지 않아 독립적인 스크립트에 적합 )

사용 예시

  • 실행 순서가 중요하지 않은 광고 코드나 분석 도구 스크립트에 적합.

✔️ defer와 async를 활용하여 내 웹페이지 최적화하기

  1. defer는 대부분의 경우 DOM 조작과 관련된 코드에 적합합니다.
  2. async는 Google Analytics와 같은 외부 도구를 로드할 때 유용하게 사용할 수 있습니다. 외부 의존성이 없는 코드에 사용에 적합합니다.
  3. Webpack, Vite 등의 번들링 도구를 통해 파일 크기를 줄이고 로딩 속도를 개선할 수 있습니다.

🎁 마무리

deferasync는 프론트엔드 개발자가 알아야 할 중요한 최적화 도구입니다. 적합한 속성을 사용해 렌더링 블로킹을 방지하고 페이지 로딩 속도를 개선하여 더 나은 UX를 제공할 수 있습니다. 프로젝트마다 상황에 맞는 속성을 선택해 효율적인 최적화를 달성해보세요! 💪

 

참고

https://www.youtube.com/watch?v=7qVc4Ez0fnY&t=33s

728x90