본문 바로가기
이론/Frontend

주소창에 google.com을 입력하면

by 유세지 2023. 12. 30.

 

 

 

 

 

 

들어가며

 

"브라우저 주소창에 google.com을 입력하면 어떤 일이 일어날까요?"

 

 

위 질문은 기술 면접에 종종 나오는 단골 주제로 굉장히 유명합니다.

"개발자 신입 기술 면접 대비" 와 같은 주제의 글에서는 빠지지 않고 등장하는 편인데,

브라우저 렌더링에 대해서만 정리되어 있거나, 해당 서버에 접근하는 과정만 있는 글이 많길래

이번 포스트에서는 두 내용을 한 번에 담아보았습니다.

 

과연 브라우저에 페이지 주소를 입력하면 어떤 일이 일어나는지 시간 순서에 따라 알아보겠습니다.

 

 

 

 

데이터 받아오기

 

흔히 볼 수 있는 브라우저 화면

 

 

브라우저에 특정 사이트의 주소를 입력하게 되면 잠깐의 시간 뒤에 해당 사이트가 나타납니다.

우리는 이 과정을 두 가지로 분리해 볼 수 있습니다.

 

  • 데이터를 받아오는 과정
  • 받아온 데이터를 띄워주는 과정

 

먼저 데이터를 받아오는 과정을 살펴보겠습니다.

 

 

서버 주소 찾기

우리가 입력한 https://google.com 이라는 주소는 URL이라고 부릅니다. 그중에서 https프로토콜google.com 부분은 도메인(domain) 이라고 부릅니다. 도메인은 보통 사이트의 이름과 같은 특성을 나타내고 있으며, 기억하기 쉬운 이름을 사용해 쉽게 접근할 수 있도록 돕는 역할을 합니다.

 

다만 도메인 주소는 사용자들을 위해 만들어진 별칭이기 때문에, 이를 컴퓨터가 이해할 수 있는 IP 주소로 변환해주어야 통신이 가능합니다. 이러한 역할을 수행해주는 것이 DNS(Domain Name System)입니다.

 

 

DNS는 도메인과 IP를 매칭해주는 역할을 합니다.

 

 

브라우저에 주소가 입력되면 DNS로부터 해당 도메인에 매칭된 IP 주소를 찾으려고 시도하는데, 매번 DNS 서버에 접근할 필요는 없습니다. 한 번 네임서버에 등록된 IP는 쉽게 변하지 않으므로, 로컬에 캐싱해두고 사용하는 것이 합리적이겠죠?

 

때문에 곧바로 DNS에 IP 정보를 요청하는 것이 아니라 브라우저에 해당 도메인이 캐시되어 있는지 확인합니다. 브라우저에서 캐시된 내역을 찾을 수 없다면 운영체제에 캐시되어 있는지 확인합니다. 여기에도 캐시된 내역이 없다면, 그제서야 PC의 DNS Resolver에서 외부의 DNS 서버로 요청을 전송합니다.

 

사용자에게 캐시된 내역이 없을때 가장 먼저 요청을 받게 되는 것은 Local DNS 서버입니다. 이 Local DNS 서버는 KT, SKT, LG U+ 와 같은 인터넷 서비스 공급자(ISP)들이 관리하고 있으며, Google이나 Cloudflare 같은 기업에서도 DNS 서버를 운영하고 있습니다. 여러분이 사용하시는 업체에 따라 각각 해당 사업자가 관리하는 Local DNS 서버로 연결됩니다.

 

만약 Local DNS에도 해당 도메인에 대한 정보가 없다면, 해당 도메인의 정보를 갖고 있을 것으로 추정되는 Root DNS에게 요청을 보내봅니다. Root DNS는 해당 요청을 받고, 도메인의 구조에 따라 하위의 DNS 서버에게 질의를 시작합니다.

 

 

Local DNS 서버는 도메인의 정보가 없을때 Root DNS에게 요청합니다.

 

 

 

요청한 도메인인 google.com는 콤마를 기점으로 google과 com으로 나뉘어집니다. 이때 맨 뒤에 오는 .com은 TLD(Top Level Domain, 최상위 도메인)이, 가장 앞에있는 google은 도메인 이름(Domain Name)이 됩니다. 만약 .com이 아닌 .co.kr로 끝났었다면 .co 부분이 SLD(Second Level Domain, 2단계 도메인)이 되고, google.com에서 google의 경우 도메인 이름이자 2단계 도메인이라고 할 수 있겠습니다. 이처럼 Root 도메인의 하위 DNS 서버는 도메인의 단계에 따라 트리 구조로 나누어져 있습니다.

 

 

Root DNS는 TLD 네임서버들의 정보를 대신 전해줍니다.

 

 

Root DNS가 google.com의 IP 주소를 가지고 있지는 않지만, 요청받은 도메인이 .com으로 끝나기 때문에 대신 .com DNS에 대한 주소를 응답합니다. 그러나 .com 또한 google.com의 IP 주소를 갖고 있지는 않습니다. 대신, google.com를 관리하는 인증된 DNS의 주소는 알고 있으니 이를 응답합니다.

 

마지막으로 도착한 google.com의 IP 주소를 알고있는 DNS 서버는 권한이 있는 서버(Authoritative DNS Server) 라고 하며, 요청을 받아 google.com의 실제 IP 주소를 응답해줍니다. 

 

 

DNS resolver는 DNS에 차례로 접근하여 IP 주소를 받아옵니다.

 

 

 

 

이렇게 DNS의 탐색 과정을 거쳐 도메인의 IP 주소를 찾았습니다.

이제 클라이언트와 서버가 명확히 정해졌으니 연결을 시작할 차례입니다.

 

 

서버와 통신하기

클라이언트는 서버와 안정적으로 통신하기 위해 먼저 확인 작업을 거칩니다.

이 과정을 TCP 3-way handshake라고 합니다.

 

이름처럼 세 가지 단계를 거쳐 완료되는데, 다음과 같습니다.

 

 

1. 클라이언트가 서버에게 SYN 패킷을 보냅니다.

SYN(Synchronize sequence numbers) 패킷은 연결을 요청하고, 초기화하기 위해 사용되는 패킷으로

3-way handshake 과정에서 가장 먼저 발송되는 패킷입니다.

 

앞의 세글자를 따서 SYN 패킷이라고 부르며 랜덤한 초기 Sequence Number를 가지고 있습니다.

 

 

2. 서버가 클라이언트에게 SYN/ACK 패킷을 보냅니다.

클라이언트가 보낸 SYN 패킷을 서버가 받으면,

서버는 확인의 의미로 클라이언트에 SYN/ACK(Acknowledge) 패킷을 보냅니다.

 

SYN/ACK 패킷은 일반 SYN 패킷과 다르게 Acknowledgment Number가 존재하는데,

이전에 수신한 패킷의 마지막 시퀀스 번호 + 1의 값으로 설정되어 있습니다.

 

이를 통해 수신받는 쪽에서 자신의 요청이 정상적으로 전해졌는지 확인할 수 있고,

계속해서 통신을 이어갈 수 있습니다.

 

 

3. 클라이언트가 서버에게 ACK 패킷을 보냅니다.

클라이언트가 서버로부터 정상적인 SYN/ACK 패킷을 수신했다면,

이에 대한 응답으로 서버에게 ACK 패킷을 전송합니다.

 

서버가 정상적으로 ACK 패킷을 수신하면 통신 준비가 모두 끝납니다.

 

 

TCP 3-Way Handshake의 진행과정

 

 

 

3-way handshake를 통해 안정적으로 연결이 설정되었다면 이제 리소스를 받아올 차례입니다.

 

브라우저는 서버에게 HTTP 요청을 통해 google.com에 대한 리소스를 요청합니다.

HTTP 메서드에는 GET, POST, PUT, PATCH, DELETE... 등등 다양한 종류가 존재하는데,

이때는 GET 메서드를 사용하여 요청합니다.

 

 

GET 메서드를 통해 페이지를 요청합니다.

 

 

요청을 받은 서버는 response를 구성하여 클라이언트로 넘겨줍니다.

response에는 요청했던 페이지 문서 외에도 상태 코드, 캐시 컨트롤, 컨텐츠 타입과 같은

HTTP 요청/응답이 갖고 있는 속성들이 함께 포함되어 있습니다.

 

 

서버로부터 응답받은 페이지 문서

 

 

이렇게 받은 페이지 문서는 브라우저에 의해 파싱되어 최종적으로 화면에 띄워지게 됩니다.

 

 

 

받아온 데이터를 띄워주기

서버의 역할은 끝났고, 이제부터는 브라우저의 시간입니다.

응답에 포함된 HTML 파일의 구문을 분석하는 파싱(parsing) 단계입니다.

 

 

파싱 (parsing)

파싱 단계에서는 HTML 파일의 구문을 분석하여 토큰화를 진행하고,

이 토큰을 토대로 트리 모양의 그래프를 만듭니다.

이렇게 만들어진 트리를 DOM(Document Object Model) 트리라고 부릅니다.

 

HTML 파일에 명시된 부모 - 자식 관계에 따라 구조화를 하는데,
그림으로 나타내면 아래와 같습니다.

 

 

DOM Tree의 구조

 

 

 

이때 img 태그처럼 외부에 리소스를 요청하는 태그를 만난 경우

브라우저는 해당 리소스를 요청하고 파싱을 이어갑니다.

그러나 script 태그를 만나면 파싱을 중지하고, script를 불러오기 시작합니다.

 

script 태그를 그냥 사용하는 경우 렌더링이 멈춰버리는 현상이 발생할 수 있기 때문에
async나 defer와 같은 키워드를 추가해 이러한 블로킹을 막을 수 있습니다.

 

 

DOM 트리 분석이 끝나면 CSS 파일에 대해서도 동일하게 분석을 시작합니다.

정리하면, 파싱 단계에서는 HTML 파일을 분석해서 DOM 트리를,

CSS 파일을 분석해서 CSSOM 트리를 만듭니다.

CSSOM 트리가 구성되면 이전에 만들어둔 DOM 트리와 합쳐서

페이지를 렌더링하는데 필요한 정보들만 모인 렌더링 트리(Rendering Tree)를 구성합니다.

브라우저는 이 렌더링 트리를 기반으로 화면을 그릴 준비를 하게 됩니다.

 

 

레이아웃 (Layout)

렌더링 트리가 만들어지고 나면 곧바로 레이아웃 단계가 시작됩니다.

파싱 단계에서 구성한 렌더링 트리를 기반으로 각 요소가

화면의 어떤 위치에 얼마만큼의 크기로 그려져야 하는지 계산하는 단계입니다.

 

한 번 레이아웃이 완료된 이후에도 각종 속성의 변경으로 인해 요소의 위치나 크기가 변해야 하는 경우가 있습니다.

대표적으로는 위에서 요청했던 이미지가 뒤늦게 로딩되거나, 사용자와의 인터렉션을 통해 UI가 변경되는 경우 등이 있습니다. 이때도 위치와 크기 계산을 다시 수행하게 되는데, 이 과정은 리플로우(reflow)라고 부릅니다.

 

width, height, margin, padding ... 등등 요소의 위치를 변경하는 속성들은 리플로우를 일으킵니다.

 

 

페인트 (Paint)

레이아웃 과정이 끝나고, 계산된 요소들을 실제 화면에 그려내는 단계입니다.

일반적으로는 CPU의 메인 쓰레드에서 실행되지만, 몇몇 속성의 경우 GPU를 통해서 이루어집니다.

 

canvas, opacity, transform3d, will-change 등의 속성이 이에 해당됩니다.
GPU 레이어에서 이루어지는 페인트는 CPU에서 보다 빠른 속도로 완료됩니다.
다만 CPU 작업보다 메모리를 더 사용하기 때문에 적당한 수준에서 사용하기를 권장하고 있습니다.

 

페인트가 완료된 이후에 요소의 색 등을 변경하면 리페인트(repaint)가 일어납니다.

위에서 본 리플로우와도 비슷한 효과인데, 리플로우가 발생하면 리페인트 또한 자동으로 일어납니다.

 

요소의 위치나 크기를 변경하지 않고, 색이나 모양과 같은 요소만 변경하는 경우
리플로우는 일어나지 않고 리페인트만 발생합니다.
background, color, border-radius 등의 속성이 이에 해당합니다.

 

이 과정까지 모두 마치게 되면 드디어 브라우저에 페이지가 표시됩니다.

 

 


 

 

마치며

마지막으로 주소창에 google.com을 입력하고 페이지가 렌더링 되는 과정을 처음부터 정리해보면,

 

 

주소창에 google.com을 입력하면

  • DNS Resolver를 통해 서버의 IP 주소 찾기
  • TCP 3-Way Handshake를 통해 통신 준비하기
  • HTTP 요청을 통해 리소스를 받기
  • 받은 리소스를 파싱하여 DOM 트리, CSSOM 트리를 구성하기
  • 두 트리를 합쳐 렌더링 트리를 구성하기
  • 레이아웃 과정을 거쳐 요소들의 위치와 크기 계산하기
  • 페인트 과정을 통해 브라우저에 페이지 렌더링 하기

 

 

이렇게 요약할 수 있겠네요.

 

 

통신부터 렌더링까지 모두 담으려니 글이 살짝 길어졌습니다.

자세하게 다루지 못한 부분도 있어서 이런 부분들은 별도의 포스팅으로 정리해 두어야겠네요.

 

잘못된 내용은 댓글로 남겨주시면 곧바로 수정하겠습니다.

긴 글 읽어주셔서 감사드립니다.

반응형

댓글