프론트엔드 엔지니어 면접에서 자주 나오는 질문 1편 (추후에도 정리할 수 있음 더 정리하기…)
해당 영상 에서 나온 것들을 위주로 정리
1. Virtual-DOM이란?
Virtual DOM은 무엇인가요? Virtual DOM (VDOM)은 UI의 이상적인 또는 “가상”적인 표현을 메모리에 저장하고 ReactDOM과 같은 라이브러리에 의해 “실제” DOM과 동기화하는 프로그래밍 개념입니다. 이 과정을 재조정이라고 합니다. (React 공식 문서 참조)
(1) 브라우저는 HTML을 전달 받으면 이를 파싱하여 DOM 노드로 이루어진DOM 트리를 생성 한다 (2) CSS파일과 각 엘리먼트의 inline 스타일을 파싱, 스타일 정보를 사용해서 Render 트리를 생성 한다 (3) 이 노드 스타일을 동기적으로 attachment하고 렌더 트리가 다 만들어지면 레이아웃(reflow) 과정을 통해 노드들에 스크린의 좌표가 주어지며 위치가 정해진다 (4) 렌더링이 끝나면 paint() 메소드를 통해 렌더링된 요소들에 색을 입힘
그렇다면 왜 Virtual DOM은 효율적인걸까?
DOM을 직접 조작한다면 그 때마다 레이아웃의 재계산과 리렌더링이 일어날 것
이 변화가 일어날 때 Virtual DOM에서 계산한다면 이 DOM은 가상 DOM이기 때문에 렌더링되지 않고, 그렇기 때문에 연산 비용의 절감 효과가 있다
Virtual DOM은 DOM fragment를 관리하는 과정을 자동화 및 추상화하고 어떤 부분이 바뀌었는지를 파악해준다
velopert님 블로그 를 참조함
2. useMemo와 useCallback (1) useMemo
1 const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
메모이제이션된 값을 반환합니다 (React 공식 문서)
복잡한 함수의 return값을 기억해야 할 때 사용
렌더링 중에 실행되므로 사이드 이펙트가 일어나는 것을 useMemo로 처리해선 안된다 → useEffect()를 사용할 것!
(2) useCallback
1 2 3 const memoizedCallback = useCallback(() => { doSomething(a, b); }, [a, b]);
메모이제이션된 콜백을 반환합니다 (React 공식 문서)
불필요한 렌더링을 방지하기 위해 설계된 함수
의존성을 갖는 reference(여기서는 [a, b])가 변경되었을 때 실행됨
→ 사실 useMemo()나 useCallback()은 (렌더링 최적화를 위해 사용 가능하지만) 이제 useState()와 useEffect()로 거의 다 처리할 수 있다
참고자료: React.memo() 현명하게 사용하기
3. 리렌더링의 조건
React에서 렌더 순서는 App → 부모 → 자식 순
React에서 마운트 순서는 자식 → 부모 → App 순
React는 컴포넌트의 상태가 변하면 컴포넌트의 리렌더링을 발생시킨다
자신의 상태가 변경될 때
부모 컴포넌트가 리렌더링 될 때
자신이 전달받은 props가 변경될 때
forceUpdate()가 실행될 때
4. 자바스크립트의 실행 컨텍스트 참고 페이지
실행 컨텍스트란 실행 가능한 코드를 형상화하고 구분하는 추상적 개념으로 코드가 실행되기 위해 필요한 환경
실행 가능한 코드는 전역 코드, Eval 코드, 함수 코드로 나뉜다
(1) 실행 컨텍스트의 실행 과정
컨트롤이 실행 가능한 코드로 이동하면 새 실행 컨텍스트가 생성된다
전역 코드로 컨트롤이 진입하면 전역 실행 컨텍스트가 생성되고 실행 컨텍스트 스택에 쌓인다(이 전역 실행 컨텍스트는 웹페이지를 나가거나 브라우저를 닫을 때 까지 유지됨)
함수를 실행하면 해당 함수의 실행 컨텍스트가 생성되고 직전에 실행된 코드 블록의 실행 컨텍스트 위에 쌓인다
함수 실행이 끝나면 실행 컨텍스트를 파기하고 직전의 실행 컨텍스트에 컨트롤을 반환
(2) 실행 컨텍스트의 구조
실행 컨텍스트는 변수 객체(Variable Object), 스코프 체인, this로 이루어져 있다
변수 객체 는 변수, 매개변수, 인수정보, 함수 선언 등을 담고 있다
전역 컨텍스트는 전역 함수와 전역 변수를 가지고, 함수 컨텍스트는 매개변수 객체와 내부 함수, 지역 변수를 갖는다
스코프 체인 은 해당 전역/함수 컨텍스트가 참조할 수 있는 변수, 함수 선언 등의 정보를 담고 있는 전역 객체, 활성 객체의 리스트를 가리킨다
실행 컨텍스트 스택 내 활성 객체를 선두로 리스트의 마지막은 당연히 전역 객체를 가리킨다
자바스크립트 엔진은 스코프 체인을 통해 렉시컬 스코프(함수가 중첩될 때 상위 스코프를 따라 올라가는 것)를 파악한다
자바스크립트의 함수는 호출 될 때 매개변수 인자 이외에 arguments 객체와 this 를 전달 받는다
this는 어떤 스코프에 위치해 있느냐에 따라 다른데 전역 객체에 있다면 this는 window(브라우저), global(Node.js) 객체를 의미한다
메소드의 내부함수나 콜백의 경우에도 this는 전역 객체에 바인딩 된다
함수가 객체의 프로퍼티 값이라면 메서드로 호출되는데, 이 메서드 내부의 this는 해당 메서드를 호출한 객체에 바인딩된다
new 연산자로 생성자를 호출할 경우 자바스크립트는 빈 객체를 먼저 생성하여 this를 바인딩하고 바인딩된 this를 통해 프로퍼티를 생성하여 객체를 리턴한다
5. 클로저
함수를 일급 객체로 취급하는 함수형 프로그래밍 언어에서라면 클로저가 사용된다
클로저는 반환된 내부함수가 자신이 선언되었을 때의 환경인 스코프를 기억하고 자신이 선언됐을 때의 스코프 밖에서 호출되어도 그 스코프에 접근할 수 있는 함수를 말한다
말이 어려운데 클로저는 함수 안에 함수가 있게 되면 기본적으로 생성된다
그렇게 되면 자연스레 스코프 체인이 형성될 텐데 이 스코프 체인이 형성될 때 변수 값들을 보존하고 기억하게 된다 (이는 메모리에서 해당 함수가 없어질 때까지 존재함)
6. 이벤트 루프와 이벤트 버블링, 이벤트 위임 참고 페이지: 이벤트 버블링, 이벤트 캡처 그리고 이벤트 위임까지
이벤트 버블링 은 특정 화면 요소에 이벤트가 발생했을 때 해당 이벤트가 더 상위의 화면 요소들로 전달되는 특성 → 이는 HTML요소가 트리 구조를 가지기 때문
이런 버블링은 stopPropagation()을 통해 막을 수 있다
이벤트 캡쳐 는 이와 반대 방향으로 진행되는 전파 방식
하위 요소에 각각 이벤트를 붙이지 않고 상위 요소에서 하위 요소의 이벤트를 제어하기 위한 것이 이벤트 위임
7. promise, async, await 자바스크립트에서 비동기 처리란?
특정 로직의 실행이 끝날때 까지 기다리지 않고 나머지 코드를 먼저 실행하는 것
이를 해결하기 위해 콜백 함수를 사용했었음
promise는 이 비동기 처리에 사용되는 객체로 Pending(대기), Fulfilled(이행), Rejected(실패)의 3가지 상태를 가진다
new promise()
가 호출되면 대기 상태가 되며 첫번째 매개변수로 콜백 함수를 선언할 수 있으며 이 콜백 함수는 resolve와 reject 인자를 가진다
resolve가 실행되었을 때에 이행 상태가 되고 reject가 실행되었을 때 실패 상태가 된다
이행 상태가 된다면 then()
을 사용하여 처리 결과 값을 받을 수 있고 실패 상태가 된다면 catch()
로 처리 결과 값을 받을 수 있다
비동기 처리 패턴에 사용되는 async와 await
코드의 순서를 보장하기 위해 사용하는 예약어(async)와 연산자(await)
await의 처리 코드는 promise를 반환해야 한다
async와 await의 예외를 처리하려면 try catch문을 사용해야 한다
8. 자바스크립트의 가비지 컬렉션
자바스크립트는 도달 가능성(reachability)이라는 개념을 사용해 메모리를 관리한다
가비지 컬렉터는 루트 정보를 수집하고 이를 기억한다
루트가 참조하고 있는 모든 객체를 방문하고 이것들을 기억한다
기억한 모든 객체에 방문하여 그 객체가 참조하는 객체까지 기억한다 (한 번 방문하면 다시 방문하지 않음)
루트에서 도달 가능한 모든 객체를 방문할 때까지 반복한다
이 때 기억되지 않은 모든 객체를 메모리에서 삭제
최적화 기법으로 세대별 수집(새로운 객체/오래된 객체로 나누어 감시), 점진적 수집(가비지 컬렉션을 나누어 수행), 유휴 시간 수집(CPU가 유휴 상태일 때만 실행) 기법을 사용함
잘 정리된 문서 가 있으므로 링크만 남김
10. 브라우저가 display: none;을 처리하는 법 참고 페이지 : 렌더링 트리 생성, 레이아웃 및 페인트
DOM과 CSSOM 트리는 결합해 렌더링 트리를 형성
페이지를 렌더링하는 데 필요한 노드만 포함시킴
레이아웃을 통해 위치와 크기 계산
페인트 및 픽셀 렌더링
이 때 display: none;
은 요소가 보이지 않고 레이아웃에도 포함되지 않도록 렌더링 트리에서 요소가 완전히 제거됨 (visibility: hidden은 레이아웃에서 공간을 차지함)
Comment and share