Typescript 강의: script defer과 async속성 DOM으로 알아보기 #99클럽2일차 #TIL

2024. 4. 1. 23:49_ExtracurricularActivities

728x90


#99클럽 #99일지 #코딩테스트 #개발자스터디 #항해 #TIL

 

✅ defer?

✅ async?

✅ 동적스크립트 (dynamic script)

✅ 요약


✅ defer?

 

defer 속성 추가 : script defer 속성을 추가하면 어떤 일이 일어나는지를 알아보도록 했습니다.

 

https://ko.javascript.info/script-async-defer

 

defer, async 스크립트

 

ko.javascript.info

 

코드가 브라우저 화면에서 바로 변경, 콘솔에 로그를 기록하고 있다면 브라우저 개발자 도구에 표시한다는 강의 내용에 좀더 깊은 이해가 필요해서 위 문서를 읽고 자세하게 알아보겠습니다  다음은 해당 문서에서 발췌한 내용입니다.

 

 

모던 웹브라우저에서 돌아가는 스크립트는 대부분 HTML보다 무겁습니다. 따라서 <script> </script>를 만났을 때 스크립트를 실행해야하므로 DOM 생성을 멈춥니다. 이러한 동작 방식은 2가지 이슈를 생성합니다.

 

1. 스크립트에서는 스크립트 아래에 있는 DOM 요소에 접근할 수 없습니다. 따라서 DOM 요소에 핸들러를 추가하는 것과 같은 여러 행위가 불가능해집니다.

2. 페이지 위쪽에 용량이 큰 스크립트가 있는 경우 ❗스크립트가 페이지를 "막아버립니다" 페이지에 접속하는 사용자들은 스크립트가 완료될 때까지 아래 페이지를 볼 수 없습니다.

 

뒤 콘텐츠를 볼 수 없습니다.

 

위와 같은 이슈는 <script>를 맨 아래에 두어 순서대로 실행하게 함으로써 일시적으로 해결할 수 있지만 HTML문서가 굉장히 큰 경우 페이지의 속도는 굉장히 느려지게 됩니다. 네트워크 속도가 느린 열악한 환경, 모바일 화면❗에서 이러한 문제는 대두됩니다.

 

브라우저는 defer 속성이 있는 스크립트(defer script, 지연 스크립트)를 백그라운드에서 다운로드합니다. 따라서 지연 스크립트를 다운로드 하는 중에도 HTML 파싱이 멈추지 않습니다. 그리고 지연 스크립트 실행은 페이지 구성이 끝날 때까지 지연됩니다.

 

정리하면 defer, 지연 스크립트는 페이지 생성을 막지 않으며, DOM이 준비된 후에 실행되긴 하지만 DOMCotentLoaded 이벤트 발생 전에 실행됩니다. 따라서 ❗페이지 콘텐츠는 바로 출력되며, DOMCotentLoaded 이벤트는 지연 스크립트 실행을 기다리고, alert창은 DOM트리가 완성되고 지연스크립트가 실행된 후에 보입니다.

 

지연 스크립트상의 순은, HTML에 추가된 순으로 실행됩니다. 먼저 다운은 되지만, 실행은 나중에 됩니다. 또한 defer속성은 외부 스크립트에만 유효하고 src가 없으면 무시됩니다.

 

 

✅ async?

 

async 속성이 붙은 스크립트는 비동기 스크립트로 불리며 페이지와 완전히 독립적으로 동작합니다.

ex) api 통신

 

defer 스크립트와 마찬가지로 백그라운드에서 다운로드 되며, HTML 페이지는 async 스크립트가 다운로드가 완료되길 기다리지 않고 페이지를 출력합니다. 하지만 HTML 파싱은 멈춥니다. DOMCotentedLoaded 이벤트와 async 스크립트는 서로 기다리지 않으며 우선순위가 바뀔 수 있습니다. 따라서 ❗실행 순서가 제각각이 됩니다.

 

PS. 그래서 해피뉴히어 할때 사용자의 데이터를 불러오고, 이를 이용해 메세지를 출력하는 순차적인 api 통신이 필요했다. 왜냐 제각각이라서 사용자 데이터를 불러오기도 전에 메세지를 출력하며 유의해야했던 부분, 아무래도 메세지 출력이 더 코드가 가벼웠던걸까? 

 

위치상으로는 small.js(더 작은 스크립트)가 아래긴하지만 먼저 다운로드가 되었기 때문에 먼저 실행됩니다. 이를 load-first order 라고 부릅니다. 비동기 스크립트는 방문자수 카운터나, 광고 관련 스크립트처럼 독립적인 역할을 하는 서드 파트 스크립트를 현재 개발하려는 스크립트에 통합하려 할때 아주 유용합니다. 각자의 독립성이 보장되기 때문!

 

 

✅ 동적스크립트 (dynamic script)

 

자바스크립트를 사용하면 문서에 스크립트를 동적으로 추가할 수 있습니다.

let script = document.createElement('script');
script.src = "/article/script-async-defer/long.js";
document.body.append(script); // (*)

위 예시에서 외부 스크립트는 관련 요소가 문서에 추가되자 마자 다운로드가 시작됩니다. 동적 스크립트는 기본적으로 'async' 스크립트처럼 행동하여 다음과 같은 특징이 있습니다.

 

1. 그 어떤 것도 기다리지 않습니다. 서로 독립적입니다.

2. 먼저 다운로드된 스크립트가 먼저 실행됩니다. load-first order

 

function loadScript(src) {
  let script = document.createElement('script');
  script.src = src;
  script.async = false;
  document.body.append(script);
}

// async=false이기 때문에 long.js가 먼저 실행됩니다.
loadScript("/article/script-async-defer/long.js");
loadScript("/article/script-async-defer/small.js");

 

script.async=false; 를 추가하면 문서에 추가된 순서로 실행됩니다.

 


 

✅ 요약

async(비동기스크립트) defer 스크립트(지연스크립트)는 다운로드 시 페이지 렌더링을 막지 않는다는 공통점으로

사용자가 오래 기다리지 않고 페이지 콘텐츠를 볼 수 있게 합니다.

 

실무에선 defer을 DOM 전체가 필요한 스크립트나, 실행 순서가 중요한 경우에 적용하며

async는 방문자 수 카운터나 광고 관련 스크립트같이 독립적인 스크립트 혹은 실행 순서가 중요하지 않은 경우 적용합니다.

 

그러나 스크립트 다운로드가 끝나지 않았어도 페이지는 동작해야합니다. ❗

defer을 사용하면 스크립트가 실행되기 전에 페이지가 화면에 출력된다는 점을 항상 유의해야합니다.

사용자는 그래픽 관련 컴포넌트들이 준비되지 않은 상태에서 화면을 보게되고 지연 스크립트가 영향을 주는 영역엔 반드시 "로딩 인디케이터"가 있어야합니다. 관련 버튼도 사용불가(disable)처리를 해줘야하죠. 이렇게 해야 사용자에게 현재 어떤 것은 사용할 수 있는지, 어떤 것은 사용할 수 없는지를 알려줄 수 있습니다.

 

=> ShareIT 일시적인 트래픽증가로 인해 프리티어 서버가 느려져 프론트-백 서버사이의 간격이 발생했고, DB처리를 받지 못한채 프론트 페이지가 동작되어 멤버변수가 없는 유령유저가 발생했다. 이 문제를 위와같은 로딩 인디케이터로 해결할 수 있을거같다.