목차
반응형
브라우저 렌더링 과정
브라우저 렌더링 과정에 대해 설명해주세요. (프론트엔드 위주)
다운로드
- 웹 브라우저에 사용자가 입력한 URL 주소를 DNS를 통해 IP 주소를 검색하고, 그 IP 주소에 HTTP GET 요청 메시지를 전송한다.
- 네트워크를 통해 웹서버로부터 요청에 대한 웹 서버로부터 응답 메세지를 전달 받는다.
파싱 (DOM 트리, CSSOM 트리 생성)
- 브라우저는 응답 메세지의 body에 있는 HTML를 문서를 파싱해 DOM 트리 생성을 시작한다.
- 먼저 HTML 상단의 DOCTYPE 을 읽어서 HTML 버전을 체크하고, 그 이후 버전에 따라 HTML 파일을 마크업 단위로 시리얼라이징 한다.
- 파싱 과정 중 link, script, img 와 같은 특수한 태그를 만나면 추가적인 일을 진행한다.
- 스타일 파일을 가져오는 link 태그를 만날 경우, 파싱 과정을 잠시 멈추고 src에 있는 주소로 요청을 보내고 응답이 오면 파싱 과정과 병렬적으로 파일을 파싱한다. 즉, 이런 스타일 파일들을 파싱해서 CSSOM 트리를 생성한다.
- 스크립트 파일을 가져오는 script 태그를 만날 경우, 마찬가지로 파싱 과정을 잠시 멈추고 스크립트 해석과 실행이 끝날 때 까지 기다린다. (script 태그는 async, defer 속성을 통해 파싱 순서를 변경 할 수 있다.)
Render 트리 생성
- 이런 파싱 과정이 끝나면, DOM 트리와 CSSOM 트리가 완성되고, DOM 과 CSSOM을 결합하여 렌더트리를 생성한다.
레이아웃/페인트
- 마지막으로 레이아웃과 페인팅 과정을 통해 생성된 렌더 트리를 실제 브라우저에 표현한다.
- 레이아웃 과정은 어떤 렌더 아이템이 어느 위치에 그려야 하는지 계산하는 과정이다.
- 페인트 과정은 레이아웃 과정을 통해 얻은 위치에 실제로 요소를 그려내는 과정이다.
리플로우/리페인트
- 브라우저는 위와 같은 방식으로 화면을 표시하고, 만약 DOM 이 조작되거나 하는 등의 이유로 화면을 다시 그려야 한다면 경우에 따라 다시 레이아웃 작업을 하는 리플로우와 다시 페인트 작업을 하는 리페인트 과정이 발생한다.
브라우저 렌더링 과정에서 자바스크립트는 어떻게 작동하나요?
- HTML 파일 파싱 과정에서 script 태그를 만나면 파싱 과정을 멈추고, 만약 src 속성이 있다면 스크립트 파일을 받고, script 태그의 자바스크립트 파일을 해석하고 실행한다.
- script 태그에 async 속성이 있을 경우, 파싱과 병렬적으로 스크립트를 다운로드하고, 다운로드가 종료된 직후에 파싱 과정을 멈추고 스크립트를 처리한다.
- script 태그에 defer 속성이 있을 경우, async 속성처럼 파싱과 병렬적으로 스크립트를 다운로드하지만, HTML 파일의 파싱이 종료된 이후에 스크립트를 처리한다.
- 스크립트를 처리할 때, 자바스크립트 파일을 해석하고 실행하기 위해서 렌더링 엔진은 자바스크립트 엔진에게 제어권을 넘겨준다.
- 제어권을 받은 자바스크립트 엔진은 자바스크립트 코드를 해석해서 AST를 생성하고, AST를 기반으로 인터프리터가 실행할 수 있는 중간 코드를 생성해서 실행한다.
- AST(Abstract Syntax Tree)는 프로그래밍 언어에서 소스 코드의 추상 구문 구조를 나타내는 트리 자료 구조를 말한다.
AST는 소스 코드를 파싱하고, 그것을 추상적인 트리 형태로 변환한다. - 모든 스크립트 처리가 끝나면 다시 자바스크립트 엔진에서 렌더링 엔진으로 제어권을 돌려주고, 남은 HTML 파일 파싱 과정을 진행한다.
script 태그를 body 태그의 가장 아래 부분에 놓으면 좋은 이유가 있을까요?
- HTML 파일 파싱 중 script 태그를 만나면 HTML 파싱 과정을 멈추고 스크립트를 처리한다.
- HTML 파싱이 끝나지 않은 상태에서 스크립트를 처리하는 동안 남은 HTML 부분에 대한 지연 시간이 발생할 수 있다.
- 따라서 HTML의 콘텐츠가 다 로딩된 body 태그의 마지막 부분에 script 태그를 위치시키면 로딩 지연을 줄일 수 있다.
- 하지만 기본적인 script 태그를 사용하면 body 태그의 마지막에 선언된 script 태그를 만난 이후에 다운로드를 시작하는 문제점이 있다. 이 문제를 해결하기 위해 script 태그에 defer 속성을 추가해 병렬적으로 다운로드 한 후, HTML 파싱이 끝난 후 스크립트를 처리할 수 있다.
DOM
DOM 에 대해 설명해주세요.
- DOM은 HTML같은 문서의 구조와 정보를 나타내는 트리 형태의 인터페이스다.
- DOM을 조작해서 HTML 요소의 속성이나 스타일, 이벤트 등을 수정할 수 있다.
- DOM에 접근해서 변경하는 프로퍼티나 메소드를 DOM API라고 한다.
DOM 구성 요소에 대해 알고 있나요?
- DOM 은 트리 형태의 자료구조이고, 크게 4가지 종류의 노드로 구성되어 있다.
- 첫번째는 Document Node로 트리 최상위에 위치하는 노드가 있다.
- 두번째는 Element Node로 HTML Element 를 표현하는 노드가 있다.
Element Node는 Attribute Node와 Text Node를 하위 노드로 가질 수 있다. - 따라서 세번째와 네번째인 Attribute Node와 Text Node는 각각 해당 HTML Element의 속성이나 텍스트를 나타내는 노드다.
이벤트
이벤트 핸들러를 등록하는 방식을 아는만큼 소개해주세요.
이벤트 핸들러 Attribute (onClick)
- HTML Element의 onClick과 같은 Attribute에 이벤트 핸들러 함수를 직접 등록할 수 있다.
<button onClick="()=>{...}"></button>
이벤트 핸들러 프로퍼티
- 자바스크립트에서 HTML Element를 참조하고, HTML Element의 이벤트 핸들러 프로퍼티를 직접 수정해서 이벤트 리스너를 등록할 수 있다.
const button = document.querySelector('button');
button.onclick = () => {...};
addEventListener 방식
- 자바스크립트에서 HTML Element를 참조하고, HTML Element에 addEventListener 메소드를 호출해서 이벤트 리스너를 등록할 수 있다.
const button = document.querySelector('button');
button.addEventListener('click'), (event) => {...});
이벤트 전파에 대해 알고 있나요?
- DOM 트리에 존재하는 Element에 대한 이벤트가 발생하면 DOM 트리를 통해 전파되는 특징이 있다.
- 이벤트 전파는 이벤트가 발생했을 때, 크게 캡처링 단계와 타겟 단계, 그리고 버블링 단계로 진행된다.
- 캡처링 단계 (상위 ➡️ 하위) : 상위 Element에서 하위 Element로 전파되는 과정으로, 처음 window 객체에서 시작해서 DOM 트리를 통해 이벤트가 등록된 이벤트 타겟까지 전파된다.
- 타겟 단계 : 이벤트가 이벤트 타겟에 도달했을 때 과정으로, 이벤트 타겟에 등록된 이벤트 핸들러가 실행된다.
- 버블링 단계(하위 ➡️ 상위) : 이벤트 타겟 Element에서 상위 Element로 전파되는 과정으로, 마찬가지로 window 객체까지 DOM 트리를 통해 전파된다.
event.target과 event.currentTarget 차이점을 설명해주세요.
- 실제로 이벤트가 발생한 가장 안쪽의 Element 를 타겟이라고 부르고, 이벤트 핸들러의 event.target으로 접근할 수 있다.
- 그리고 이벤트 핸들러가 직접 등록된 Element 는 이벤트 핸들러에서 event.currentTarget 또는 this로 접근할 수 있다.
- 차이점으로는 전파 단계에 따라 event.target은 변할 수 있지만, 이벤트가 처리될 때 핸들러가 등록된 event.currentTarget 은 변하지 않는다는 점이 있다.
이벤트 버블링과 캡쳐링을 적용하는 방법을 설명해주세요.
- 기본적으로 이벤트는 버블링이 적용되어 있다.
- DOM Element의 addEventListener 메소드의 세번째 파라미터인 useCapture 파라미터를 사용하면 전파 방법을 변경할 수 있다.
- 기본값은 false로, 이 경우 버블링이 적용되고 true를 전달 할 경우 캡처링이 적용된다.
이벤트 전파를 막는 방법이 있나요?
- 이벤트 전파를 막기 위해 이벤트 리스너의 이벤트 객체의 몇가지 메소드를 사용할 수 있다.
- 먼저 Element 에 있는 기본 이벤트를 제거하기 위해 e.preventDefault() 메소드를 사용할 수 있다.
- 그리고 e.stopPropagation() 메소드를 사용하면 이벤트 전파가 이후의 Element로 전달되지 않도록 제한할 수 있다.
- 만약 동일한 Element에 여러개의 이벤트 리스너가 있을 때, e.stopImmediatePropagation() 메소드를 사용하면 다른 이벤트 리스너 호출을 제한한다.
이벤트 위임에 대해 알고 있나요?
- 이벤트 위임은 연속되는 Element들 각각에 이벤트 리스너를 등록하는 대신, 상위 Element에만 이벤트 리스너를 등록하는 방식이다.
- 이벤트 위임을 사용하면 등록할 이벤트 리스너를 줄일 수 있어서 메모리를 아낄 수 있다.
- Element 추가나 삭제마다 이벤트 리스너를 관리할 필요가 없어지는 장점이 있다.
이벤트를 처리할 때 debounce나 throttle에 대해 알고 있나요?
- 마우스 scroll이나 resize와 같은 이벤트는 연속적으로 일어나기 때문에 짧은 시간동안 이벤트 리스너가 과도하게 호출될 수 있다.
- 과도한 함수 호출이 발생하면 성능이 떨어질 수 있기 때문에, 이런 성능 저하를 막기 위한 방법인 debounce와 throttle이 있다.
- debounce : 이벤트가 실행했을 때 일정 시간만큼 지연한 후 이벤트를 수행하도록 하고, 지연할 동안 같은 이벤트가 발생하면 이전 요청을 취소한다.
- throttle : 일정 시간동안 일어난 이벤트들을 한 번만 실행하도록 한다.
타이머
타이머 함수에 대해 알고 있나요?
- 일정 시간 후나 일정 시간마다 작업을 처리하는 함수를 타이머 함수라고 한다.
- 타이머 함수의 종류로는 대표적으로 setTimeout과 setInterval 이 있다.
- 그리고 기본적으로 시간을 ms(밀리초)단위를 사용한다.
setTimeout에 대해 설명해주세요.
- setTimeout은 일정 시간 이후에 콜백 함수로 등록된 함수를 호출하는 함수로, 타이머가 만료될 때 딱 한 번 실행된다.
- setTimeout 함수의 반환값으로 타이머를 식별하는 고유한 값을 반환하는데, 이를 clearTimeout 함수에 전달하면 타이머를 취소할 수 있다.
setInterval에 대해 설명해주세요.
- setInterval은 일정 시간마다 콜백 함수로 등록된 함수를 호출하는 함수다.
- setInterval도 마찬가지로 함수의 반환값으로 고유한 값을 반환하는데, clearInterval 함수를 통해 반복 호출을 취소할 수 있다.
동기/비동기
동기와 비동기의 차이를 알고 계신가요?
- 동기와 비동기는 작업을 처리하는 순서와 관련이 있다.
- 동기적으로 처리할 경우 현재 작업이 끝난 후 다음 작업이 시작하는 순차적인 작업 순서를 가지고 있지만,
- 비동기적으로 처리할 경우 작업이 끝나지 않았더라도 다음 작업을 시작할 수 있는 작업 순서를 가질 수 있다.
비동기 호출은 어떤식으로 진행되나요?
- 기본적으로 자바스크립트는 싱글 스레드로 동작해서 한번에 하나의 작업만 처리할 수 있다.
- 즉 콜 스택에 쌓인 실행 컨텍스트를 위에서 아래로 하나씩 처리하고, 작업이 끝나면 스택에서 pop 하는 방식으로 동작한다.
- 이 때, 자바스크립트는 브라우저에서 동작한다. 자바스크립트가 동작할 때 브라우저는 자바스크립트를 처리하기 위해 자바스크립트 런타임이라고 하는 환경을 제공한다. 싱글 스레드인 자바스크립트 엔진을 포함해서 Web API, 이벤트 루프, 태스크 큐가 여기에 해당된다.
- 그래서 비동기 호출은 이 자바스크립트 런타임에 의해 처리할 수 있다.
- 콜 스택에서 비동기 호출이 발생하면 Web API 에서 처리하게 된다. Web API는 비동기 호출을 처리하고, 비동기 호출에 대한 콜백함수 등을 태스크 큐에 등록한다.
- 이벤트루프는 콜 스택과 태스크 큐를 확인하면서 콜 스택이 모두 처리되었을 때 태스크 큐에서 콜백 함수를 콜 스택으로 가져와서 처리하게 된다.
- 그래서 아래 코드는 ABC가 아닌 ACB 순서로 출력하게 된다.
console.log('A');
setTimeout(() => console.log('B'), 0);
console.log('C');
마이크로 태스크 큐에 대해 알고 있나요?
- 마이크로 태스크 큐는 또다른 종류의 태스크 큐로, 이벤트 루프가 콜 스택으로 태스크를 처리할 때 일반 태스크 큐보다 높은 우선순위로 처리하는 태스크 큐다.
- Promise의 then, catch, finally에 있는 콜백 함수거나, await 문법이 사용되었을 때 마이크로 태스크 큐에 등록된다.
통신 (Ajax, JSON, REST API)
Ajax에 대해 설명해주세요.
- Ajax는 자바스크립트의 비동기 통신을 이용해 클라이언트와 서버간에 XML 데이터를 주고받는 기술을 의미한다.
- Ajax는 브라우저 호스트 API인 XMLHttpRequest 객체를 기반으로 동작한다.
Ajax를 활용한 방식의 장점이 있을까요?
- Ajax를 통해 특정 부분만 렌더링하는 방식의 개발이 가능해졌다.
변경이 필요한 부분의 데이터만 Ajax 통신을 통해 요청하고, 응답한 데이터를 통해 특정 부분만 다시 렌더링 할 수 있기 때문이다. - 변경이 필요한 부분만 다시 렌더링하기 때문에 새로고침이나 새로운 문서를 받았을 때 처럼 화면 깜빡임이 발생하지 않고, 비동기 통신이기 때문에 블로킹이 따로 발생하지 않는다.
Ajax 통신을 위한 방법을 설명해주세요.
- 전통적인 방법으로 XMLHttpRequest 객체를 생성하고 설정해서 사용하는 방법이 있다.
- 최근에는 fetch API를 주로 사용하고 있다. fetch API는 비교적 최근에 추가된 Web API로 HTTP 요청 기능을 제공하는 함수이다.
XMLHttpRequest와 fetch의 차이점이 있나요?
- 공통적으로는 둘 다 Ajax 통신을 위해 사용된다.
- 하지만 fetch의 장점은 Promise를 기반으로 구성되어 있어서 더 간편하게 사용할 수 있다고 생각한다.
JSON에 대해 설명해주세요.
- JSON은 JavaScript Object Notation의 약자로, HTTP 통신을 위한 일종의 데이터 포맷이다.
- 이름에 자바스크립트가 들어가지만, 자바스크립트에 종속되지 않은 언어 독립형 데이터 포맷이다.
- JSON의 형태는 자바스크립트의 객체와 비슷하게 key-value 형태로 구성되어 있다. 하지만 key를 포함한 문자열을 항상 쌍따옴표로 표시해야 하고, 함수나 undefined와 같은 몇가지 자바스크립트의 타입을 사용할 수 없는 차이점이 있다.
자바스크립트에서 JSON 처리를 위한 메소드를 알고 있나요?
- 자바스크립트는 JSON 처리를 위해 표준 빌트인 객체로 JSON 객체를 가지고 있다. 그리고 JSON 객체의 메소드로 parse와 stringify 메소드가 있다.
- JSON.parse : JSON 텍스트를 분석해서 자바스크립트 값이나 객체를 생성하는 메소드이다.
- JSON.stringify : 자바스크립트 객체를 JSON 문자열로 변경하는 메소드이다.
- 여기서 자바스크립트에서 서버 전송을 위해 객체를 문자열로 변경하는 것을 직렬화, 그리고 문자열을 다시 객체로 변경하는 것을 역직렬화라고 한다.
REST API에 대해 알고 있나요?
- REST는 어떤 리소스를 이름으로 구분해서 자원의 상태를 주고받는 방식을 의미한다.
- HTTP URI를 통해 리소스을 명시하고, HTTP 요청 메소드를 통해 해당 리소스의 상태를 주고받는 방식을 의미한다.
URI는 특정 리소스를 식별하는 통합 자원 식별자(Uniform Resource Identifier)를 의미한다. - REST API는 이런 REST를 기반으로 작성된 API 서비스를 의미하고, REST 원칙을 잘 지킨 디자인을 RESTful이라고 표현한다.
REST API의 구성요소에 대해 알고 있나요?
- 크게 리소스, 행위, 표현으로 구성되어 있다.
- 리소스 : 해당 리소스 그 자체를 가지고 있고 URI를 통해 표현한다.
- 행위 : 리소스에 대해 어떤 행위를 할 지를 의미하고 HTTP 메소드를 통해 전달한다.
- 표현 : 리소스에 대한 구체적인 행위의 내용이고 페이로드를 통해 전달한다.
REST API에서 HTTP 요청 메소드에 대해 아는만큼 설명해주세요.
- GET : 리소스를 가져오기 위해 사용한다.
- POST : 새로운 리소스를 생성하기 위해 사용한다.
- PUT/PATCH : 메소드는 기존 리소스를 수정하기 위해 사용한다.
PUT은 리소스 전체를 변경하고, PATCH는 일부만 수정한다는 차이가 있다. - DELETE : 리소스를 삭제하기 위해 사용한다.
Promise
콜백 함수를 설명해주세요.
- 콜백 함수는 다른 함수의 파라미터로 전달되는 실행 가능한 코드로, 어떤 작업이 끝나거나 이벤트가 발생했을 때 호출되는 함수를 의미한다.
- 일반적으로 비동기 함수 처리가 끝나면 실행할 작업으로 콜백 함수를 전달한다.
Promise 문법에 대해 설명해주세요.
- Promise는 비동기 처리를 위해 ES6에서 추가된 문법이다.
- Promise 객체는 new 키워드를 통해 생성할 수 있고, resolve와 reject를 파라미터로 하는 함수를 전달받는다.
resolve는 비동기 처리가 성공했을 때 호출할 함수고 reject는 비동기 처리가 실패했을 때 호출할 함수이다. - Promise는 비동기 처리중인 pending, 수행이 성공적으로 끝난 fulfilled, 오류가 발생한 reject로 세가지 상태가 있다.
그리고 pending이 아닌 두 상태는 setteled 상태로 더이상 변경되지 않는 상태이다. - fulfilled 상태의 Promise(성공) : .then()을 통해 처리 값을 전달받아서 추가적인 처리가 가능한다.
- reject 상태의 Promise(실패) : .catch()를 통해 실패에 대한 처리가 가능한다.
Promise 표준 빌트인 객체가 제공하는 메소드를 알고 있나요?
- Promise.all 메소드는 여러개의 비동기 처리를 병렬적으로 처리할 때 사용한다. 각각의 비동기 호출이 순서가 상관 없을 때 사용한다.
- Promise.race 메소드는 여러개의 비동기 처리 중 가장 먼저 fulfilled 된 처리 결과를 가져올 때 사용한다.
- 마지막으로 Promise.allSettled 메소드는 여러개의 비동기 처리의 모든 fulfilled나 reject된 처리 결과를 resolve하는 Promise를 반환한다.
async/await
async/await 문법에 대해 알고 있나요?
- ES8에 추가된 async/await는 Promise를 기반으로 동작하는 비동기 처리 방식이다.
- async/await를 사용하면 비동기 처리를 동기 처리처럼 보이는 코드를 작성할 수 있다.
- Promise에 await 키워드가 사용된 경우 항상 프로미스가 settled(완료된) 상태가 될 때 까지 기다리기 때문이다.
Promise와 차이가 있나요?
- async/await를 사용하면 에러 핸들링이 더 간단하다.
- Promise도 catch를 통해 에러 핸들링이 가능하지만, try/catch를 사용할 수 있는 async/await가 더 간단하다고 느꼈다.
- 그리고 Promise도 후속 처리가 많아질수록 .then() 내부에 코드가 중첩되면서 코드 흐름이 복잡해지는데 이를 해결할 수 있다.
Generator
제너레이터에 대해 알고 있나요?
- ES6에서 추가된 문법으로, 코드 블록의 실행을 중지했다가 필요한 시점에 다시 실행할 수 있는 특수한 객체다.
- 제너레이터를 사용하면 제너레이터 함수의 제어권을 양도할 수 있고, 제너레이터 함수의 상태를 주고받을 수 있다.
제너레이터에 대해 조금 더 자세히 설명해주세요.
- 제너레이터 함수는 function 뒤에 *(star)를 붙인 키워드로 선언한다.
- 제너레이터 함수 내부에는 yield 키워드를 사용할 수 있다.
- 제너레이터 함수를 호출하면 제너레이터 객체를 반환하는데, 바로 함수가 실행되지는 않는다.
- 제너레이터 객체의 next 메소드는 현재 상태에서 가장 가까운 yield 키워드가 있는 곳 까지 실행된다.
그리고 메소드의 반환값으로 yield 키워드 뒤에 있는 값이 value로 반환됩니다. 이 때, value와 함께 제너레이터의 마지막을 나타내는 Boolean값인 done도 함께 객체로 반환된다.
제너레이터의 특징을 알고 있나요?
- 제너레이터는 iterable로 취급된다. 그래서 제너레이터 객체를 for-of 문법 등으로 순회할 수 있다.
- 주의점으로는 제너레이터에서 done: true 가 되는 지점은 순회하지 않는다는 특징이 있다.
Reference
반응형