모던 자바스크립트 Deep Dive #4

Yejung·2022년 11월 5일
0

📚 22.11.05 4회차 스터디 정리본

📌 브라우저 렌더링 과정

  • 브라우저의 렌더링 과정에 대해 설명해보세요

    1. 주소창에 URL을 입력하고 엔터키를 누르면 DNS를 통해 IP 주소로 변환

    2. 이 IP 주소를 갖는 서버에게 요청을 전송 (HTML, CSS, JS, 이미지, 폰트 파일 등 렌더링에 필요한 리소스를 요청)하고 서버로부터 응답을 받는다.

    3. 브라우저의 렌더링 엔진은 서버로부터 응답한 HTML과 CSS를 파싱하여 DOM과 CSSOM을 생성하고 이들을 결합하여 렌더 트리를 생성한다. (바이트 > 문자 > 토큰 > 노드 > DOM 또는 CSSOM)

      • 렌더 트리 : 렌더링을 위한 트리 구조의 자료구조
      • 브라우저 화면에 렌더링되지 않는 노드와 CSS에 의해 비표시 되는 노드는 포함 X (meta 태그, script 태그, display: none)
    4. 브라우저의 자바스크립트 엔진은 서버로부터 응답된 자바스크립트를 파싱하여 AST(Abstract Syntax Tree)를 생성하고 바이트코드로 변환하여 실행한다. 이때 자바스크립트는 DOM API를 통해 DOM이나 CSSOM을 변경할 수 있다. 변경된 DOM과 CSSOM은 다시 렌더 트리로 결합된다.

      • AST : 토큰에 문법적 의미와 구조를 반영한 트리 구조의 자료구조
    5. 렌더 트리를 기반으로 HTML 요소의 레이아웃(위치와 크기)을 계산하고 브라우저 화면에 HTML 요소를 페인팅(화면에 픽셀 렌더링)한다.

  • 브라우저의 렌더링 과정에 자바스크립트는 어떻게 동작하나요? 

    • <script></script> 태그를 만나면 DOM 생성을 일시 중단

    • JS 파일을 서버에 요청해 로드한 JS 파일이나 script 태그 내의 JS 코드를 파싱하기 위해 JS 엔진에 제어권 넘김 (자바스크립트의 파싱과 실행은 브라우저 렌더링 엔진이 아닌 자바스크립트 엔진이 처리)

    • JS 엔진은 자바스크립트를 해석하여 AST(추상적 구문 트리)를 생성

    • AST를 기반으로 인터프리터가 실행할 수 있는 중간 코드인 바이트코드 생성해 실행

    • JS 소스코드 → 토큰 → AST → 바이트코드

  • <script></script> 태그를 <body></body> 태그 밑에 둬야하는 이유가 있을까요?

    • 렌더링 엔진과 자바스크립트 엔진은 병렬적으로 파싱을 실행하지 않고 직렬적으로 수행하기 때문이다.

    • 브라우저는 위에서 아래 방향으로 순차적으로 HTML, CSS, JS를 파싱하고 실행

    • script 태그 위치에 따라 HTML 파싱이 블로킹되어 DOM 생성이 지연될 수 있다

    • DOM 생성이 지연된 상태에서 DOM을 조작하는 경우 문제가 발생

    • <script></script> 태그를 <body></body> 태그 밑에 뒀을 때 자바스크립트 로딩/파싱/실행으로 인해 HTML 요소들의 렌더링에 지장받는 일이 발생하지 X → 페이지 로딩 시간 단축

  • asyncdefer어트리뷰트

    • HTML 파싱과 외부 자바스크립트 파일의 로드가 비동기적으로 동시에 진행
    • async
      • JS 파싱과 실행은 JS 파일의 로드가 완료된 직후 진행되며 이때 HTML 파싱이 중단
      • 여러개의 script태그에 async를 지정하면 script태그 순서와는 상관없이 로드가 완료된 자바스크립트부터 먼저 실행되므로 순서가 보장X
    • defer
      - JS 파싱과 실행은 HTML 파싱이 완료된 직후(DOM 생성이 완료된 직후) 진행


📌 DOM

  • DOM이 뭔가요?

    • HTML 문서의 계층적 구조와 정보를 표현하며 이를 제어할 수 있는 API를 제공하는 트리 자료구조
  • DOM을 구성하는 건 뭐가 있나요?

    • HTML 요소는 렌더링 엔진에 의해 파싱되어 DOM을 구성하는 요소 노드 객체로 변환

    • HTML 요소 어트리뷰트는 어트리뷰트 노드로, HTML 요소의 텍스트 콘텐츠는 텍스트 노드로 변환된다.

    • DOM은 노드 객체의 계층적인 구조로 구성

      • 노드 객체는 12개 종류
        • 문서 노드
        • 요소 노드
        • 어트리뷰트 노드
        • 텍스트 노드
        • 외 기타 등등


📌 이벤트

  • 마우스 이벤트 타입에는 뭐가 있나요? click 말고 클릭을 대체할 수 있는 이벤트가 있나요?
    • mouseup으로 대체

      이벤트 타입이벤트 발생 시점
      click마우스 버튼 클릭
      dblclick마우스 버튼 더블 클릭
      mousedown마우스 버튼을 눌렀을 때
      mouseup누르고 있던 마우스 버튼을 놓았을 때
      mousemove마우스 커서를 움직였을 때
      mouseenter마우스 커서를 HTML 요소 안으로 이동했을 때 (버블링 X)
      mouseover마우스 커서를 HTML 요소 안으로 이동했을 때 (버블링 O)
      mouseleave마우스 커서를 HTML 요소 밖으로 이동했을 때 (버블링 X)
      mouseout마우스 커서를 HTML 요소 밖으로 이동했을 때 (버블링 O)
  • 그 외에 알고 있는 대표적인 이벤트가 있나요?

    이벤트 타입이벤트 발생 시점
    keydown모든 키를 눌렀을 때 발생
    focusHTML 요소가 포커스 받았을 때 (버블링 X)
    blurHTML 요소가 포커스 잃었을 때 (버블링 X)
    submit1. form 요소 내의 input, select 입력 필드에서 엔터키 눌렀을 때
    2. form 요소 내의 submit 버튼을 클릭했을 때
    scroll웹페이지 또는 HTML 요소를 스크롤할 때 연속적으로 발생
    inputinput, select, textarea 요소의 값이 입력되었을 때
  • 이벤트 핸들러를 등록하는 방식에는 어떤 것들이 있나요?

    1. 이벤트 핸들러 어트리뷰트

      HTML 요소의 이벤트 핸들러 어트리뷰트를 할당

    2. 이벤트 핸들러 프로퍼티

      이벤트 타깃의 이벤트 핸들러 프로퍼티에 함수를 바인딩

    3. addEventListener 메서드 방식

      이벤트 타깃의 addEventListener 메서드 사용 (이벤트타입, 이벤트핸들러, capture 사용 여부)

  • 이벤트 전파(propagation)에 대해서 알고 있나요?

    • DOM 트리상에 존재하는 DOM 요소 노드에서 발생한 이벤트는 이벤트 타깃을 중심으로 DOM 트리를 통해 전파되는데 이것을 이벤트 전파라고 한다.
    1. 캡쳐링 단계
      • Event Capturing
        • 캡쳐링 이벤트를 캐치하려면 addEventListener 세번째 인수로 true를 전달
    2. 타깃 단계 : 이벤트 타깃에 도달
    3. 버블링 단계
      • Event Bubbling
        • bubbling 되지 않는 이벤트
          • focus/blur
          • load/unload/abort/error
          • mouseenter/mouseleave
  • 이벤트 위임(delegation)에 대해서 알고있나요?

    • 여러 개의 하위 DOM 요소에 각각 이벤트 핸들러를 등록하는 대신 상위 DOM 요소에 이벤트 핸들러를 등록하는 방법
    • 여러개의 하위 요소에 이벤트 핸들러를 등록할 필요 X
    • 동적으로 추가되고 삭제되는 DOM 요소에 일일이 핸들러를 등록하고 삭제할 필요 X
  • e.preventDefault 에 대해 알고 있나요?

    • DOM 요소의 기본 동작을 중단시키는 메서드
  • e.stopPropagation

    • 이벤트 전파를 중지시키는 메서드


📌 타이머

  • 호출 스케쥴링이 무엇인가요?

    • 함수를 일정 시간이 경과된 이후에 호출되도록 타이머 함수를 사용하는 것
  • 타이머 함수에는 어떤 것들이 있나요?

    • setTimeout / clearTimeout

      두번째 인수로 전달받은 시간 이후 첫번째 인수로 전달받은 콜백 함수가 호출 (단 한번 실행)

      const timeoutId = setTimeout(func|code[, delay, param1, param2, ...]);
        
       clearTimeout(timeoutId);

      setTimeout 함수는 생성된 타이머를 식별할 수 있는 고유한 타이머 id 반환 (브라우저 : 숫자 , Node.js : 객체)

      반환한 타이머 id를 clearTimeout의 인수로 전달해 타이머 취소 가능

    • setInterval / clearInterval

      두번째 인수로 전달 받은 시간이 경과할 때마다 첫번째 인수로 전달받은 콜백 함수가 반복 호출

      const timeoutId= setInterval(func|code[, delay, param1, param2, ...]);
         
       clearInterval(timeoutId);
  • 이벤트가 과도하게 호출되어 성능에 문제를 일으킬 경우에 할 수 있는 어떤 일을 통해 해결할 수 있나요?

    • scroll, resize, mousemove와 같은 이벤트들이 과도하게 호출되어 성능에 문제를 일으킴
    • 디바운스와 쓰로틀을 사용한다
  • 디바운스에 대해서 알고 있나요?

    • 짧은 시간 간격으로 이벤트가 연속해서 발생하면 이벤트 핸들러를 호출하지 않다가 일정시간이 경과한 이후에 이벤트 핸들러가 한 번만 호출되도록 하는 콜백 함수
  • 쓰로틀에 대해서 알고 있나요?

    • 짧은 시간 간격으로 이벤트가 연속해서 발생하더라도 일정 시간 간격으로 이벤트 핸들러가 최대 한 번만 호출되도록 한다.


📌 비동기 프로그래밍

  • 동기와 비동기의 차이점에 대해서 설명해줄 수 있나요?

    • 현재 실행 중인 태스크가 종료할 때 까지 다음에 실행될 태스크가 대기하는 방식을 동기, 현재 실행 중인 태스크가 종료되지 않은 상태라 해도 다음 태스크를 곧바로 실행하는 방식을 비동기
    • 자바스크립트는 싱글 스레드, 브라우저는 멀티 스레드
  • 이벤트 루프와 태스크 큐에 대해서 알고 있나요?

    • 이벤트 루프

      • 콜 스택에 현재 실행중인 실행 컨텍스트가 있는지, 그리고 태스크 큐에 대기중인 함수가 있는지 반복해서 확인
      • 만약 콜 스택이 비어있고 태스크 큐에 대기중인 함수가 있다면 이벤트 루프는 순차적(FIFO)으로 태스크 큐에 대기중인 함수를 콜 스택으로 이동
    • 태스크 큐

      • 비동기 함수의 콜백 함수 또는 이벤트 핸들러가 일시적으로 보관되는 영역
      function foo(){
      	console.log("foo");
      }
      
      function bar(){
      	console.log("bar");
      }
      
      setTimeout(foo, 0);
      bar();
      1. 전역 코드가 평가되어 전역 실행 컨텍스트가 생성되고 콜 스택에 푸시

      2. 전역 코드 실행되기 시작하여 setTimeout 함수 호출. 이때 setTimeout 함수의 함수 실행 컨텍스트가 생성되고 콜스택에 푸시되어 현재 실행중인 실행컨텍스트가 된다.

      3. setTimeout 함수가 실행되면 콜백 함수를 호출 스케줄링하고 종료되어 콜 스택에서 팝

      4. 브라우저가 수행하는 4-1과 JS 엔진이 수행하는 4-2는 병행처리

        4-1. 브라우저는 타이머를 설정하고 타이머 만료를 기다린다. 이후 타이머가 만료되면 콜백 함수 foo가 태스크 큐에 푸시. setTimeout 함수로 호출 스케줄링한 콜백 함수는 정확히 지연시간 후에 호출된다는 보장은 없다. 태스크 큐에 푸시되어 대기하지만 콜 스택이 비어야 호출하기 때문에 약간의 시간차 발생 가능

        4-2. bar 함수가 호출되어 bar 함수의 함수 실행컨텍스트가 생성되고 콜스택에 푸시되어 현재 실행중인 실행 컨텍스트가 된다. 이후 bar 함수가 종료되어 콜스택에서 팝

      5. 전역 코드 실행 종료 및 콜스택에서 팝

      6. 이벤트 루프에 의해 콜 스택이 비어있음이 감지되고 태스크 큐에서 대기중인 콜백 함수 foo가 이벤트 루프에 의해 콜스택에 푸시, 실행 후 팝

  • 마이크로태스크 큐에 대해서 알고 있나요?

    • 프로미스 후속 처리 메서드의 콜백 함수가 일시 저장되는 곳
  • 태스크 큐와 마이크로태스크 큐 중 어떤 것이 먼저 실행되나요?

    setTimeout(() => console.log(1), 0);
    
    Promise.resolve()
      .then(() => console.log(2))
      .then(() => console.log(3));
    
    // 2 3 1 
    • 마이크로태스크 큐가 우선 순위가 높다
profile
이것저것... 차곡차곡...

0개의 댓글