1. 리액트의 props와 state에 대해서 설명해주세요.
props는 부모 컴포넌트가 자식 컴포넌트에 전달하는 데이터이다.
자식 컴포넌트는 props를 수정할 수 없다.
이런 특성은 컴포넌트 간의 데이터 흐름을 예측 가능하게 하고, 컴포넌트의 재사용성을 높인다.
state는 컴포넌트 내부에서 관리되는 데이터이다. state는 동적으로 변경될 수 있고, 컴포넌트의 렌더링에 영향을 미친다.
state을 변경하면 컴포넌트는 다시 렌더링되며, UI가 업데이트된다. state는 주로 사용자 입력, 네트워크 요청의 응답에 따라 변하는 데이터를 관리할 때 사용된다.
1-1. props가 자식 컴포넌트에서 변하지 않는 이유는 무엇인가요?
리액트의 단방향 데이터 흐름 원칙 때문이다. 리액트의 이러한 설계는 컴포넌트 간의 데이터 흐름을 예측 가능하게 하고 일관성 있게 만들 수 있어, 상태 관리가 간단해진다.
props는 읽기 전용이라 부모 컴포넌트에서 전달된 값이 자식 컴포넌트 내에서 임의로 변경되지 않는다. 예측 가능성을 높이고, 디버깅을 쉽게 한다.
1-2. 만약 자식 컴포넌트에서 부모 컴포넌트로부터 받은 props를 변경해야 한다면 어떻게 해야 할까요?
부모 컴포넌트에서 상태로 해당 데이터를 관리하고, 상태 변경 함수를 자식 컴포넌트로 전달하는 방식으로 구현해야 한다.
상태 끌어올리기 방식
2. 리액트의 Controlled Component와 Uncontrolled Component의 차이점에 대해서 설명해주세요.
제어 컴포넌트는 리액트 상태를 통해 입력값을 제어하는 컴포넌트이다. 입력 요소의 값을 리액트 상태와 동기화하고, 사용자가 입력을 변경할 때마다 onChange 이벤트 핸들러를 통해 상태를 업데이트한다.
제어 컴포넌트의 장점은 입력값이 리액트의 상태로 관리되므로, 입력값을 쉽게 검증, 변경, 복잡한 폼 로직 처리하는데 유리하다.
비제어 컴포너트는 리액트 상태가 아닌 DOM 자체가 입력값을 제어하는 방식이다. 입력 요소의 값은 DOM에서 직접 관리된다.
ref를 사용하여 DOM 요소에 직접 접근해 값을 읽어오거나 조작할 수 있다.
비제어 컴포넌트의 장점은 상대적으로 간단한 폼이나 초기값이 중요한 상황에서 사용할 수 있다.
2-1. Controlled Component와 Uncontrolled Component를 통해 상태를 관리하는 것 중 어느 상황에 어떤 방법을 선택해야 하나요?
단순한 입력 필드가 포함된 폼에서 ref를 사용하는 것이 더 간단하고 성능이 좋을 수 있다. (입력할 때마다 리렌더링X)
값을 입력할 때마다 유효성 검증을 실시간으로 해줘야하는 경우에는 제어 컴포넌트를 사용하는 것이 좋다.
3. 리액트에서 성능 최적화를 위해 적용할 수 있는 방법들을 설명해주세요.
리액트에서 메모이제이션을 사용한다.
memo를 사용하면 컴포넌트를 메모이제이션할 수 있다. 컴포넌트의 props가 변경되지 않았을 때, 리렌더링을 방지하여 성능을 최적화한다. 렌더링 비용이 큰 컴포넌트에서 유용하다.
useCallback은 함수를 메모이제이션하여 불필요한 함수 재생성을 방지한다. useMemo는 값의 재계산을 방지하여 성능을 최적화한다.
(useCallback을 사용할 경우 render phase는 실행되지만, useCallback을 활용하여 props 값을 이전과 같게 유지해주었기 때문에 commit phase는 실행되지 않는다. rendear phase까지 실행되지 않게 하려면 useMemo를 사용해준다.)
자식 컴포넌트로 전달되는 함수나 값이 변경되지 않으면 리렌더링을 피할 수 있다.
코드스플링을 활용한다. 큰 애플리케이션을 여러 개의 작은 청크로 나누어, 필요한 청크만 로드하게 하여 초기 로드 시간을 줄인다.
React.lazy, Suspense를 사용하여 동적으로 컴포넌트를 로드할 수 있다.
3-1. 코드 스플리팅은 어떤 경우에 사용해야 할까요?
1. 초기 로딩이 길어지는 경우에 사용한다.
애플리케이션이 커지면, 초기 로딩에 모든 코드를 로드하는 것이 비효율적일 수 있다. 코드 스플리팅을 사용해 초기 로드 시 필요한 핵심 코드만 로드하고, 이후 추가적인 기능은 필요할 때 로드하도록 하면 초기 로딩 속도를 크게 개선할 수 있다.
2. 라우트별 코드 분할이 필요한 경우
SPA에서는 라우트별로 필요한 코드만 분리하여 로드할 수 있다. 리액트의 React.lazy, Suspense를 사용하여 라우트별 컴포넌트를 동적으로 불러올 때 유용하다.
4. 브라우저 렌더링 파이프라인에 대해서 설명해주세요.
브라우저 렌더링 파이프 라인이란?
브라우저가 웹 페이지를 화면에 표시하기 위해 거치는 과정이다.
1) DOM 생성
- 브라우저가 HTML 파일을 받으면 바이트 단위로 읽고, 문자들로 변환한 후 HTML 토큰으로 변환한다. HTML 토큰이 생성되면 HTML 문서의 구조를 트리 형태로 표현한 DOM 트리를 생성한다.
2) CSSOM 생성
- 브라우저가 CSS 파일을 파싱하고 CSS 규칙으로 나눈다. 선택자, 선언으로 구성된다. 선택자는 스타일을 적용할 HTML 요소를 정의하고, 선언은 적용할 스타일을 정의한다.
3) 렌더 트리 생성
- 브라우저는 DOM과 CSSOM을 결합하여 렌더 트리를 생성한다. 렌더 트리는 화면에 실제로 표시될 요소들로만 구성된다.
4) 레이아웃 과정
- 브라우저가 렌더 트리를 사용해 각 요소의 정확한 위치와 크기를 계산한다. 이 과정에서 렌더 트리의 각 노드가 화면의 어디에 위치할지, 얼마나 큰지를 계산한다.
+ 리플로우 : 화면 크기가 변경되면 브라우저는 레이아웃 과정을 다시 수행하게 되는데, 성능에 영향을 줄 수 있기 때문에 최소화한다.
5) 페인팅 과정
- 브라우저가 각 요소를 실제로 화면에 그리는 작업을 시작한다. 복잡한 그래픽, 애니메이션이 포함된 경우 페인트 작업이 많아져 성능이 저하될 수 있다.
6) 컴포지팅
- 브라우저가 화면에 그려질 요소들을 각각의 레이어로 분리하고, 이 레이어들을 결합하여 최종 화면을 구성한다. GPU를 활용하여 각 레이어를 빠르게 합성한다. GPU 가속을 활용하여 성능을 최적화하고, 화면에 결과를 빠르게 생성한다.
+ transform, opacity 속성은 4) 레이아웃 과정과 5) 페인팅 과정을 거치지 않고, 6) 컴포지팅 단계에서만 처리한다. 그래서 더 부드럽고 빠르게 실행될 수 있다.
5. 인터넷 창에 www.google.com를 입력하면 무슨 일이 일어나는지 설명해주세요.
1) DNS 조회
- 브라우저가 도메인 이름을 IP 주소로 변환해야 한다. 먼저 캐시된 DNS 기록을 확인하고, 없으면 로컬 DNS 서버에 요청하여 www.google.com 에 해당하는 IP 주소를 얻는다.
2) TCP 연결 수립
- IP 주소 확인 후에 브라우저는 서버와 TCP 연결을 수립한다. TCP는 데이터를 신뢰성 있게 전달하기 위한 프로토콜이다. 브라우저는 서버와 3-way handshake를 수행한다.
3) HTTP 요청
- TCP 연결이 수립되면 브라우저는 웹페이지를 요청하는 HTTP, HTTPS 요청을 보낸다. HTTPS를 사용할 경우, 이 단계 이전에 SSL/TLS 핸드셰이크도 수행된다. 이 과정에서는 브라우저와 서버가 암호화된 연결을 설정하기 위한 보안 인증서를 교환하고, 암호화 키를 협상한다.
4) 서버의 응답
- 서버는 요청을 받고, 해당 리소스를 브라우저에게 응답으로 보낸다. HTTP 응답 코드와 함께 전달된다.
이후 브라우저 렌더링 파이프라인을 진행하여 웹 페이지가 화면에 표시된다.
'Technical Interview' 카테고리의 다른 글
FE 질문 (2) (0) | 2025.01.26 |
---|