[웹] 프론트엔드 면접 단골 질문 HTML 파싱 최적화하기 (feat. defer, async)

Woonil·2025년 3월 27일
0

목록 보기
4/4
post-thumbnail

프론트엔드 면접을 복기하다가 예전에 정리해 놓은 부분에서 질문이 나왔다는 것을 확인해버린 것이다.. 이번 참에 확실히 개념을 짚고 넘어가고자 한다.

브라우저는 HTML을 읽다가 <script>를 만나면 스크립트를 먼저 실행해야 하므로 DOM 생성을 멈추며, 이는 src 속성이 있는 외부 스크립트를 만난 경우도 동일하게 작동한다. 외부에서 스크립트를 다운받고 실행한 후에야 남은 페이지를 이어서 처리하게 된다.

이 때, 스크립트 파싱 시에는 스크립트 아래에 있는 DOM 요소에 접근할 수 없기 때문에 DOM 요소에 핸들러를 추가하는 것과 같은 여러 행위가 불가능해진다. 따라서, 페이지 상단에 용량이 큰 스크립트가 있는 경우, 해당 스크립트가 페이지 생성을 막기 때문에 페이지에 접속하는 사용자들은 스크립트를 다운받고 실행할 때까지 스크립트 아래쪽 페이지를 볼 수 없게 되는 상황이 생긴다. 그렇다면 이러한 문제를 어떻게 해결할 수 있을까?

HTMLScriptElement - Web APIs | MDN

🤔개념

사용자에게 웹페이지가 보여지는 과정

index.html 파일의 <script> 태그가 어디에 위치하느냐에 따라 파싱 과정의 차이가 생긴다.

  • <head><script>

    • 순서
      1. <script>진입 시, html Parsing(분석)을 잠시 중단한다.
        2. 필요한 Javascript 파일을 서버에서 다운로드 및 실행한 후 복귀한다. ⇒ 파일크기가 크거나 인터넷 속도가 느린 경우 많은 시간이 소요될 수 있는 문제가 있다.
  • <body><script>

    <body> 내 마지막에 Javascript 파일을 서버에서 다운로드한 후 실행하므로, 웹페이지의 동작이 Javascript에 존재하는 코드에 의존적일 경우에는 사용자로 하여금 의미있는 컨텐츠를 보게 하는 것이 어렵다.

파싱 최적화

이제 이 부분이 면접에서 나온 부분이다. 사실 파싱 과정은 브라우저 렌더링 과정의 일부인데, 결국 이 부분을 defer나 async를 적절히 사용하여 최적화할 수 있다.

defer를 사용하여 스크립트 실행을 지연하기

defer는 사전적 의미로 '지연하다'라는 뜻이다. 브라우저는 defer 속성이 있는 스크립트(이하 defer 스크립트)를 백그라운드에서 다운로드한다. defer 스크립트를 다운로드 하는 도중에도 HTML 파싱이 멈추지 않으며, defer 스크립트 실행은 페이지 구성이 끝날 때까지 지연된다.

  • 특징
    • defer 스크립트는 페이지 생성을 절대 막지 않는다.
    • defer 스크립트는 DOM이 준비된 후에 실행되긴 하지만 DOMContentLoaded 이벤트 발생 전에 실행된다.
    • 일반 스크립트와 마찬가지로 HTML에 추가된 순서(상대순, 요소순)로 실행된다.
    • 브라우저는 성능을 위해 페이지에 어떤 스크립트들이 있는지 모두 살펴본 후, 스크립트를 병렬적으로 다운로드한다. ⇒ 작은 크기의 스크립트는 먼저 다운되지만, 실행은 나중에 된다.
    • <script>에 src가 없으면 defer 속성은 무시된다.
    • 적용 예시) DOM 전체가 필요한 스크립트를 실행해야 하는 경우, 실행 순서가 중요한 경우

async를 사용하여 스크립트 다운로드를 병렬로 처리하기

async 속성이 붙은 스크립트(이하 async 스크립트)는 페이지와 완전히 독립적으로 동작한다.

  • 특징

    • defer 스크립트와 마찬가지로 백그라운드에서 자바스크립트를 다운로드하며, HTML 페이지는 async 스크립트 다운이 완료되길 기다리지 않고 페이지 내 콘텐츠를 처리, 출력한다. (단, async 스크립트 실행중에는 HTML 파싱이 멈춘다.)
    • DOMContentLoaded 이벤트와 별개로 동작한다. (기다리지 않는다.)
    • 다른 스크립트의 다운로드 완료 여부와 독립적이다. ⇒ 다운로드가 끝난 스크립트 순으로 진행된다. (load-first order)
    • 적용 예시) 방문자 수 카운터나 광고 관련 스크립트같이 독립적인 스크립트를 실행해야 하는 경우, 실행 순서가 중요하지 않은 경우 (Javascript에서 DOM 요소를 조작할 시에는 해당하는 HTML 요소 정의를 필수적으로 선행해야 한다.)
  • 순서

    1. <script> 진입 시, 병렬적으로 Javascript 파일을 서버에서 다운로드한다.
    2. 다운 완료 시, Parsing을 잠시 중단한다.
    3. Javascript 파일 실행 후 복귀한다.

참고자료
https://ko.javascript.info/script-async-defer

profile
프론트 개발과 클라우드 환경에 관심이 많습니다:)

0개의 댓글

관련 채용 정보