브라우저 동작 원리

👀·2023년 3월 28일

브라우저 동작원리

사용자가 URL을 입력하면 브라우저는 해당 URL의 도메인 이름을 DNS서버를 통해 IP주소로 변환합니다.
이 과정에서 DNS 캐시를 확인하여 이미 알고 있는 주소는 DNS 조회 과정을 생략합니다.

IP주소를 얻은 뒤, 브라우저는 해당 서버에 연결을 시도합니다. 이 때 TCP 프로토콜을 사용하는 3way hand shake 과정을 거쳐 안정적인 연결을 확립합니다.

TCP연결이 성립되면 브라우저는 HTTP 프로토콜을 통해 웹 서버에게 웹 페이지 데이터 요청을 보냅니다. 요청은 보통 GET 요청이며 헤더에는 사용자 에이전트, 허용하는 컨텐츠 타입 등이 포함됩니다.
서버는 요청을 처리한 후 HTTP응답을 보냅니다. 응답에는 상태 코드, 컨텐츠 타입 필요하면 리다이렉션 정보 등이 포함되어 있으며 HTML 문서를 비롯한 필요한 데이터가 응답 본문에 포함됩니다.

서버로 부터 HTML문서를 받으면 브라우저 엔진은 위에서 아래로 순차적으로 태그와 속성을 파싱합니다. 이 태그와 속성들을 트리 형태로 변환하여 메모리에 저장하여 DOM트리를 생성합니다.
HTML파싱 중 CSS 스타일을 만나면 CSSOM으로 변환합니다.
문서의 파싱이 완료되면 DOM과 CSSOM트리를 결합하여 렌더 트리를 생성합니다.
렌더 트리는 브라우저 상에서 요소의 위치와 크기를 결정하는 REFLOW과정을 거치며 마지막으로 요소의 색상, 경계선 등 시각적 요소를 그리는 PAINT과정을 진행합니다.

3way hanshake

브라우저가 사용자가 입력한 URL에 대한 웹 페이지를 요청하고 로드하는 과정에서 TCP 연결을 수립하는 기본적인 매커니즘입니다.
첫 번째 단계에서는 클아이언트는 서버에게 연결요청을 보냅니다. 이 때 사용되는 패킷을 SYN패킷이라고 부르며 이 패킷은 클라이언트가 생성한 무작위 시퀀스 번호를 포함합니다. 이 시퀀스 번호는 통신에서 데이터가 올바르게 전송되고 받는지 확인하는데 사용됩니다.

서버가 연결 요청을 받으면 클라이언트에게 응답으로 SYN-ACK 패킷을 보냅니다.
서버가 클라이언트의 요청을 받았고 자신의 시퀀스 번호를 통해 다음 통신을 준비하겠다는 의미로 서버의 시퀀스 번호와 클라이언트의 시퀀스 번호에 1을 더한 값을 포함하여 SYN-ACK 패킷을 보냅니다.

클라이언트가 서버의 시퀀스 번호를 받고 연결준비가 완료되었음을 서버에 알리기 위해 클라이언트는 서버의 SYN-ACK패킷을 받고 서버의 시퀀스 번호에 1을 더한 값을 ACK패킷으로 보내 응답합니다.

HTML 파싱 중 SCRIPT 태그를 만나면?

파싱 중간에 SCRIPT 태그를 만나면 브라우저는 해당 SCRIPT를 로드하고 실행하기 위해 파싱을 정지합니다. 외부 스크립트일 경우, 스크립트를 로드하고 실핼한 후 파싱을 재개하며 내부 스크립트일 경우, 실행이 완료될 때까지
파싱이 정지됩니다. 파싱속도가 저하되고 DOM트리가 완성되기 전에 SCRIPT가 DOM을 조작할 가능성이 있어 예기치 못한 상황이 발생할 수 있습니다. 이러한 문제를 방지하기 위해 async나 defer속성을 이용해 파싱에 마치는 영향을
최소화할 수 있습니다.

async와 defer

async와 defer는 스크립트를 비동기적으로 로드하는 속성입니다.
async는 스크립트가 로드되는 즉시 실행되는 반면에, defer는 스크립트를 비동기로 로드하지만 HTML파싱이 완료된 후에 실행합니다.
async는 로드 순서 상관없이 실행할때 적합하고 defer는 스크립트의 실행순서가 중요할때 적합합니다.

예를 들면 async는 Google Analytics와 같은 사용자 분석 도구에 적합하고
defer는 내부 스크립트와 같이 메인 콘텐츠를 조작하는 스크립트가 적합합니다.

REFLOW

웹 페이지 내에서 요소의 위치 또는 크기에 변화가 있을 때, 변화된 레이아웃을 다시 계산하여 렌더 트리에 적용하는 과정입니다.
width, height, padding, margin, border-width와 같은 크기 속성,
position, top, left와 같은 위치 속성,
display, flex와 같은 레이아웃 속성
font-size, font-weight와 같은 폰트 속성이 REFLOW를 유발하는 속성입니다.

DOM업데이트를 하나로 묶어 Batch Update하거나
스타일 변경이 필요한 요소에 일괄적인 CSS 클래스를 할당하여 변화를 한번에 업데이트하거나
transform, opacity 속성을 이용해서 REFLOW대신 COMPOSITE만을 유발하여 최적화할 수 있습니다.

REPAINT

웹페이지에서 시각적 요소가 변했을 때 다시 계산하여 렌더트리에 적용하는 과정입니다.
color, background-color와 같은 색상 속성,
border-color, border-radius와 같은 테두리 속성이 REPAINT를 유발하는 속성입니다.

REFLOW와 REPAINT의 성능 차이

부모 노드의 레이아웃 변화는 자식노드의 레이아웃까지 영향을 미치기 때문에 REPAINT와 다르게 REFLOW는 하위 렌더 트리를 다시 계산하고 재구성하는 과정이 필요합니다.
따라서 REFLOW는 자체만으로도 부하가 큰 작업입니다.
또한 REFLOW가 발생하면 일반적으로 REPAINT도 발생되기 때문에 성능에 큰 영향을 미치며 렌더링 최적화를 위해서 REFLOW를 최소화해야 합니다.
REFLOW는 주로 CPU를 활용하여 연산하는 반면, REPAINT는 GPU를 활용한다는 차이도 있습니다.

0개의 댓글