script 태그 async defer의 차이-면접질문(프론트)

HaydenOH·2021년 7월 2일
0

웹개발공부

목록 보기
4/10

자바스크립트 : parser blocking resource 이다.

async / defer 모두 사용하지 않는 디폴트 모드에서 브라우저는 문서를 파싱해 읽다가 자바스크립트를 만나면 진행하고 있었던 파싱을 멈추고 스크립트를 다운 -> 파싱 -> 실행한 후 -> 문서를 파싱하게 된다.

"script async"
async속성을 쓰면 문서를 파싱하는 동안 스크립트를 만나면 문서 파일과 함께 스크립트를 다운 받고 스크립트 다운이 완료되면 즉시 스크립트를 실행한다. 다운로드가 끝나면 스크립트를 실행하는 동안은 문서(HTML)파싱을 멈추고 스크립트 실행이 끝난 후 남은 문서를 읽는다.
async 속성이 붙는 스크립트는 페이지와 완전히 독립적으로 동작한다.

  • async 스크립트는 defer스크립트와 마찬가지로 백그라운드에서 다운로드된다. 따라서 HTML페이지는
    async 스크립트 다운이 완료되길 기다리지 않고 페이지 내 콘텐츠를 처리 출력한다.
    BUT async 스크립트 실행중에는 html파싱이 멈춘다.
    -DOMContentLoaded 이벤트와 async 스크립트는 서로를 기다리지 않습니다.
    페이지 구성이 끝난 후에 async 스크립트 다운로딩이 끝난 경우, DOMContentLoaded는 async 스크립 트 실행 전에 발생할 수 있다.
  • async 스크립트가 짧아서 페이지 구성이 끝나기 전에 다운로드 되거나 스크립트가 캐싱처리 된 경우,
    DOMContentLoaded는 async스크립트 실행 후에 발생할 수도 있습니다.
  • 다른 스크립트들은 async 스크립트를 기다리지 않습니다. async 역시 다른 스크립트를 기다리지 않는다.
    -> async 스크립트가 여러개 있는 경우, 그 실행 순서가 제각각이 된다. 실행은 다운로드가 끝난 스크립 트 순으로 진행.

"script defer"
브라우저가 defer스크립트를 만났을 때 스크립트를 다운로드 하지만 문서 파싱을 멈추지 않고 끝까지 수행하고 스크립트는 태그를 만났을 때 실행한다. 즉 DOMContentLoaded 발생 이전에 실행해야 함을 나타내는 불리언 속성이다.(디폴트는 true이다.)즉 defer스크립트 실행은 페이지 구성이 끝날때 까지 지연된다.

  • 페이지 콘텐츠는 바로 출력이 된다.
  • DOMContentLoaded 이벤트는 지연 스크립트(defer)실행을 기다린다
    지연 스크립트는 일반 스크립트와 마찬가지로 HTML에 추가된 순(상대순, 요소순)으로 실행된다
    따라서 길이가 긴 스크립트가 앞에, 길이가 짧은 스크립트가 뒤에 있어도 짧은 스크립트는 긴 스크립트가 실행될 때까지 기다린다.

"동적 스크립트"
자바 스크립트를 사용하면 문서에 스크립트를 동적으로 추가가 가능하다. 이렇게 추가한 스크립트를 동적 스크립트라고 부른다.

let script = document.createElement('script');
script.src = "/article/script-async-defer/long.js";
document.body.append(script); // ()
위 예시에서 외부 스크립트는 관련 요소가 문서에 추가되자 마자((
)로 표시한 줄) 다운로드가 시작됩니다.

동적 스크립트는 기본적으로 'async' 스크립트처럼 행동한다.

  • 동적 스크립트는 어떤 문서도 기달리지 않는다. 어떤 문서도 동적스크립트를 기달리지 않는다.

  • load-first order이다.(먼저 다운 스크립트가 먼저 실행)

    아래 예시에선 두 스크립트를 동적으로 문서에 추가합니다. 그런데 script.async=false가 없었다면 이 스크립트들은 'load-first order’로 실행됩니다. 그럼 크기가 작은 small.js가 먼저 실행되겠죠. 하지만 script.async=false가 있기 때문에 실행은 '문서에 추가된 순서’대로 됩니다.

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");

profile
underdog

0개의 댓글