브라우저는 다음과 같은 구조로 되어있습니다.
브라우저 주소창에 www.google.com을 검색하게 되면 구글의 검색 페이지가 화면에 보이는 것을 확인할 수 있습니다. 브라우저는 어떻게 구글이 서버에서 필요한 정보를 받아서 화면에 띄워주는지 확인해보겠습니다.
전체적인 그림은 다음과 같습니다.
브라우저의 주소 표시줄에 URL을 입력하면 어떻게 되나요?
브라우저는 주소 창 입력된 www.google.com을 IP로 변환해야 합니다. 그러기 위해서 브라우저는 DNS
에 www.google.com의 IP주소를 요청합니다. 그리고 DNS
는 해당 도메인으로 캐싱된 IP 주소가 있는지 확인합니다. 캐시는 브라우저, 운영 체제, 라우터, ISP (Internet Service Provider)에서 확인합니다. 만약 캐시에서 IP 주소를 찾지 못하면 DNS
쿼리를 통해서 도메인을 호스팅하고 있는 서버의 IP 주소를 찾습니다.
TCP 통신이란 컴퓨터 네트워크에서 신뢰성 있는 통신을 제공하는 인터넷 프로토콜입니다. TCP 통신은 3-way handshake
을 통해서 클라이언트와 서버 간에 연결을 설정합니다.
3-way handshake
의 연결 과정은 다음과 같습니다.
SYN (Synchronize)
클라이언트가 서버에게 SYN
패킷을 보냅니다. 이때 SYN
패킷에는 클라이언트가 사용할 임시 포트 번호와 초기 순서 번호가 포함됩니다. 클라이언트는 SYN
패킷을 보내고, SYN_SENT
상태로 전환됩니다.
SYN-ACK(Synchronize-Acknowledgment)
서버는 클라이언트의 연결 요청을 받고, SYN
패킷에 응답하기 위해 SYN-ACK
패킷을 보냅니다. 이때 SYN-ACK
패킷에는 서버가 사용할 임시 포트 번호와 클라이언트의 초기 순서 번호에 1을 더한 값이 포함됩니다. 서버는 SYN-ACK
패킷을 보내고, SYN_RECEIVED
상태로 전환됩니다.
ACK (Acknowledgment)
클라이언트는 서버의 SYN-ACK
패킷을 받으면, 연결 수립을 확인하기 위해 ACK
패킷을 보냅니다. ACK
패킷에는 서버의 초기 순서 번호에 1을 더한 값이 포함됩니다. 서버는 ACK
패킷을 받으면 연결이 수립되었다는 것을 확인하고, ESTABLISHED 상태로 전환됩니다. 클라이언트는 ACK
패킷을 보내고, ESTABLISHED
상태로 전환됩니다.
서버와 연결되면 브라우저는 필요한 리소스들을 요청합니다. 그리고 서버에서는 브라우저에서 요청한 파일들을 찾고, 브라우저에게 전달합니다. 브라우저는 서버로부터 받은 파일을 가지고 렌더링 과정을 시작합니다
브라우저는 화면을 그리기 위해 필요한 HTML, CSS, JS, 이미지 등을 서버에 요청합니다. 그리고 해당 파일들을 파싱하여 DOM
, CSSOM
, Render Tree
등을 생성합니다. 이를 통해서 브라우저는 화면에 각 요소들을 배치하고 스타일을 적용시켜 페이지를 렌더링합니다.
브라우저는 먼저 서버에 요청해서 받은 HTML 파일을 파싱하여 DOM
을 생성합니다.
DOM
은 웹 페이지의 구조를 객체 트리 형태로 표현하고 있습니다. 그리고 각각의 HTML 요소(태그), 속성, 텍스트 등은 DOM
의 노드(Node)로 표현됩니다. 웹 개발자는 JavaScript를 통해 DOM
을 조작하면 웹 페이지의 요소를 동적으로 변경하거나 이벤트를 처리할 수 있습니다.
HTML에서 <link>
와 <style>
태그를 사용하면 웹 페이지에 스타일을 적용할 수 있습니다. 브라우저는 DOM
을 생성하다가 두 태그를 만나면 DOM
의 생성을 잠시 중단합니다. 그리고 CSS를 파싱해서 CSSOM
을 생성합니다. 그리고 CSSOM의 생성이 완료되면 브라우저는 DOM을 이전에 중단된 부분부터 다시 생성하기 시작합니다.
CSSOM
은 웹 페이지에 적용된 CSS 스타일 규칙을 객체 트리 형태로 표현하고 있습니다. 각각의 CSS 선택자, 속성, 값 등은 CSSOM
의 객체로 매핑되어 웹 페이지의 스타일 정보를 제어할 수 있습니다. 웹 개발자는 JavaScript를 통해 CSSOM
을 조작하면 웹 페이지의 스타일을 동적으로 변경하거나, 애니메이션 등을 만들 수 있습니다.
Attachment
는 DOM
과 CSSSOM
을 연결하여 Render Tree
를 생성하는 과정을 의미합니다. Render Tree
는 화면에 표시되는 요소들과 그들의 스타일, 레이아웃 정보를 포함합니다. Render Tree
는 DOM
의 일부 요소를 선택하여 생성되며, 실제로 화면에 표시될 요소들을 결정합니다.
Render Tree
에는 display: none
과 같이 화면에 표시되지 않는 내용들은 포함되지 않습니다. 하지만 opacity: 0
, visibility: hidden
과 같이 크기를 가지고 있는 요소들은 Render Tree
에 포함됩니다.
Render Tree
가 완성되면 각 요소를 실제로 화면에 그리기 위한 과정을 진행합니다.
Reflow
는 Render Tree
의 각 요소에 대해 레이아웃을 계산합니다. 레이아웃은 요소의 크기, 위치, 배치 등을 결정합니다. 레이아웃의 계산은 DOM
의 변경과 크기를 결정하는 width
, height
같은 스타일이 변경되었을 때 다시 실행됩니다.
Repaint
는 계산된 레이아웃을 화면에 요소를 그리는 과정입니다. Repaint
는 Reflow
가 실행되면 항상 다시 실행됩니다. 하지만 Repaint만 실행되는 경우도 있습니다. CSS에서 color
가 변경되었을 경우에는 레이아웃을 유지하고 픽셀에 색상만 변경합니다. 이러한 경우에는 Reflow
는 생략되고 Repaint
만 실행됩니다.
동적인 웹 사이트를 개발할 때는 Reflow
와 Repaint
를 신경 써야 합니다. Reflow
와 Repaint
과정은 굉장히 빠르게 실행되고 반영됩니다. 하지만 수십 번 반복적으로 발생한다면 사이트의 성능을 저하시키고 사용자 경험을 떨어트릴 수 있습니다.