script의 실행 시점 조절하기

Seung·2022년 2월 13일
0

script 실행 시점 알아보기

  • 동기

  • 비동기

  • async

  • defer


😄 Code 1. 동기적 실행

// JavaScript
<script>
	const span2 = document.querySelector('.span');
    console.log(span2);
</script>
// HTML
<span class="span">안녕하세요?</span>
// JavaScript
<script>
	const span = document.querySelector('.span');
    console.log(span); // output : <span class="span">안녕하세요?</span>
</script>

같은 코드임에도 불구하고 결과는 왜 다르게 나올까 ?

  • 일반적으로 브라우저는 한줄씩 parsing한다

  • 한줄씩 parsing 하다가 위의 코드처럼 script 태그를 만나면 parsing을 멈추고 script 파일을 다운 받아서 실행한 후에 이어서 남은 HTML을 parsing 한다.

  • 즉 첫번째 script는 아직 parsing 하지도 않은 span 클래스명을 가진 요소를 선택할려고 했기 때문에 null이 나오고 두번째 script는 앞서 span 클래스명을 가진 요소를 parsing 하고 실행했기 때문에 정상적인 결과값이 나온다

  • 위의 코드처럼 실행할려면 DOM을 따라 반드시 순서대로 실행되어야 할 때 용이한 코드라고 할 수 있다

그러면 script 파일을 무조건 body 끝에 넣으면 되겠네 ??

  • 땡!!🤣

  • body 끝에 script 파일을 추가하면 HTML을 끝까지 parsing하고 마지막에 script 파일을 다운받고 실행한다

  • 하지만 사용자가 웹과 상호작용을 시도하면 제대로 동작하지 않을 수도 있다

    왜??

    • 사용자 눈에는 완성된 웹사이트처럼 보이지만 실제 백그라운드에서는 script를 해석해서 실행하는 중일 수도 있기 때문이다. 이 때 사용자가 상호작용을 시도하면 에러가 나올 수도 있다
  • 따라서 이런 동기적으로 하는 방법보다는 비동기적으로 하는게 좋다


😄 Code 2. 비동기적 실행

어떻게 비동기적으로 불러오지??

  • 키워드는 바로 async, defer !!
// load 되는데 5초
<script src = 'main.js' async></script>
// load 되는데 1초
<script src = 'main2.js' async></script>
  • 브라우저가 HTML을 parsing 하다가 async script를 발견하면 병렬로 다운 명령만 내리고 이어서 남은 HTML을 parsing 한다
    async script 다운로드가 완료되면 진행중이던 HTML parsing을 멈추고 다운로드 된 async script를 실행한다

  • async script를 만나면 병렬로 명령을 내리기 때문에 시간절약이 가능하다

  • 하지만 async script는 JS 파일이 여러개라면 먼저 다운로드가 끝난 JS를 먼저 실행한다. 즉 위의 코드처럼 main2.js의 다운로드가 먼저 끝나면 main2.js를 먼저 실행한다. 따라서 웹사이트가 JS 순서에 의존적이라면 좋지 않다

  • 중요한 실행 순서 조정도 못하기 때문에 async는 권장하지 않는다

  • 또 async script는 완전히 비동기로 불러오기 때문에 DOM이 모두 load된 경우에 발생하는 DOMcontentLoaded를 보장할 수 없다

    Why?

    • async script는 DOM Rendering이 끝나기전에 JS가 다운로드 된다면 JS를 먼저 실행하기 때문이다.
      따라서 async script는 웹사이트가 script에 의존성이 없고 JS 실행 순서가 중요하지 않을 때 용이하다
      (그래도 웬만하면 쓰지 말자🤣)

🥰DOMcontentLoaded에 대한 자세한 설명은 제 벨로그에 있습니다🥰

그럼 진짜 뭐 쓰지..??

해결방법은 defer!!😘

// load되는데 5초
<script src="main.js" defer></script>
// load되는데 3초
<script src="main2.js" defer></script>
  • defer은 async와 비슷하게 HTML을 parsing하다가 병렬로 JS 파일을 다운 명령만 시키고 남은 HTML을 끝까지 parsing한다.

  • 하지만 async와 제일 큰 차이점은 async는 JS 다운이 완료되면 그 내용이 즉시 실행되는 반면에 defer은 모든 HTML이 다운된 이후에 JS가 실행된다

  • 위의 코드처럼 더 빨리 load되는 script가 있어도 선언한 순서에 따라 JS 파일이 실행된다

  • 따라서 JS 파일을 전부 다운받은 뒤에 순서대로 실행하기 때문에 웹사이트가 JS 순서에 의존적일 때 좋으며 DOM 구성이 끝난 이후에 script 파일을 실행하기 때문에 async보다 좋다고 할 수 있다

  • 결론적으로 가장 범용적으로 사용할 수 있는 속성은 defer인 것 같다


😍 코드 지적은 언제나 환영입니다. 읽어주셔서 감사합니다. 😍

profile
지적은 제 발전의 원동력입니다. 사소한 것이라도 지적해주세요 :)

0개의 댓글