'www.google.com'을 주소창에 입력하면 일어나는 일

hangkemiii·2022년 9월 28일
1

CS

목록 보기
1/1
post-thumbnail

짠하면 뿅하고 나오는 거 아님?

그동안 우리는 너무 쉽게 웹 페이지에 접근을 해왔다. 그냥 검색창에 우리가 가고 싶은 URL을 타이핑하고 엔터만 치면 뿅하고 사이트가 나왔으니 이 얼마나 쉬운 세상인가. 하지만 우리가 그렇게 쉽게 웹 사이트에 접근할 동안 브라우저는 정말 많은 일들을 처리하고 있었다. 개발자의 길을 걷기로 결정한 만큼, 브라우저의 고충을 이해해 보며 어떤 일들이 일어나는 지 한번 알아보자.

브라우저?

우선 브라우저가 무엇인지에 대해서 부터 알아보자. 웹 브라우저란, 웹 서버와 통신하여 인터넷의 WWW(World Wide Web) 서비스를 이용할 수 있게 하는 컴퓨터 응용 프로그램이다. Browse라는 뜻은, 원래 둘러보다, 훑어보다 라는 뜻인데 웹에서 여러 문서들을 잠깐식 펼쳐보거나 훑어보는 도구라는 뜻에서 웹 브라우저라는 이름이 지어졌다.

현재 대표적으로 사용되는 웹 브라우저에는 구글의 크롬(Chrome), Mozilla의 파이어폭스(Firefox), 애플의 사파리(Safari), 마이크로소프트의 엣지(Edge) 등이 있다. 우리의 유년기를 함께 했던 마이크로소포트의 Internet Explorer는 현재 서비스가 종료되어 사장된 웹 브라우저이다.

웹 브라우저의 구조는 브라우저마다 조금 다를수는 있겠지만, 평균적으로 다음과 같이 구성되어 있다.

(사진 출처: https://d2.naver.com/helloworld/59361)

  1. 사용자 인터페이스
    주소 표시줄, 이전/다음 버튼, 북마크 메뉴 등. 요청한 페이지를 보여주는 창을 제외한 나머지 모든 부분이다.

  2. 브라우저 엔진
    사용자 인터페이스와 렌더링 엔진 사이의 동작을 제어한다.

  3. 렌더링 엔진
    웹 페이지가 표시되는 모든 영역을 제어하며 요청한 콘텐츠를 표시한다. 예를 들어 HTML을 요청하면 HTML과 CSS를 파싱하여 화면에 표시하게 된다.

  4. 통신
    HTTP 요청과 같은 네트워크 호출에 사용된다. 플랫폼과 독립적인 인터페이스이고 각 플랫폼 하부에서 실행된다.

  5. UI 백엔드
    콤보 박스와 창 같은 기본적인 장치를 그리게 된다. 플랫폼에서 명시하지 않은 일반적인 인터페이스로서, OS 사용자 인터페이스 체계를 사용한다.

  6. 자바스크립트 해석기
    자바스크립트 코드를 해석하고 실행한다. 자바스크립트 엔진이라고도 하며, HTML 파싱 중 script 태그를 만나게 되면 렌더링 엔진에게서 제어 권한을 넘겨받게 된다. 이 작업은 동기적으로 진행된다.

  7. 자료 저장소
    이 부분은 자료를 저장하는 계층이다. 쿠키를 저장하는 것과 같이 모든 종류의 자원을 하드 디스크에 저장할 필요가 있는데, HTML5 명세에는 브라우저가 지원하는 '웹 데이터 베이스'가 정의되어 있다.

그럼 www.google.com을 입력 해보자.

사용자가 주소창에 www.google.com을 입력하게 되면, 다음과 같은 일들이 일어나게 된다.

1. 입력한 텍스트 정보 확인

크롬과 사파리는 구글의 검색창을, 네이버 웨일은 네이버의 검색창을 주소창과 동일하게 사용하고 있다. 그렇기 때문에 브라우저는 우선 사용자의 입력 텍스트가 검색어인지 URL인지 확인하는 과정을 거친다. 이 작업은 브라우저 엔진의 UI 스레드에서 진행하게 된다.

만일 사용자가 입력한 텍스트가 검색어면, 브라우저는 검색 엔진의 URL에 검색어를 포함한 주소로 페이지를 이동시키고, URL일 경우에는 네트워크 호출을 수행하게 된다. 현재는 사용자가 www.google.com, URL을 입력했기 때문에 네트워크 호출을 수행한다.

2. 네트워크 호출

브라우저는 구글의 HTML 문서, CSS 문서, 스크립트, 이미지 등의 데이터를 미리 가지고 있지 않기 때문에 구글 서버와의 네트워크 통신을 통해 데이터를 가져와야 한다. 브라우저는 네트워크 통신을 위해 도메인 이름에 해당하는 google.com을 DNS 서버에서 검색을 하게 되는데, DNS 서버 검색 이전에 캐싱된 DNS 기록들을 먼저 확인한다.

DNS

DNS(Domain Name System)란 URL들의 이름과 IP주소를 저장하고 있는 데이터베이스다. 인터넷에 있는 모든 URL들에는 고유의 IP 주소가 지정되어있고, 이 IP 주소를 통해서 해당 웹사이트를 호스팅하고 있는 서버 컴퓨터에 접근을 할 수 있다. 따라서 도메인 네임을 IP 주소로 변환해 주는 환경이 필요한데, 이것이 바로 DNS이다.

만약 해당 도메인 이름에 해당하는 IP 주소가 존재하면, 브라우저는 DNS 서버에 해당 도메인 이름에 해당하는 IP 주소를 요청하지 않고 캐싱된 IP주소를 바로 반환한다. 만약 일치하는 IP 주소가 존재하지 않는다면, 다음 과정인 DNS 서버 요청으로 넘어가게 된다.

브라우저는 ISP(Internet Service Provider)를 통해 DNS 서버가 호스팅하고 있는 서버의 IP 주소를 찾기 위해 DNS query를 전달한다. DNS query는 현재 DNS서버에 원하는 IP주소가 존재하지 않으면 다른 DNS 서버를 방문하는 과정을 원하는 IP주소를 찾을 때까지 반복하게 된다.

IP 주소를 찾게 되면, 브라우저는 구글 서버에 데이터를 요청하는 HTTP Request를 보내게 된다. 해당 HTTP 요청 메세지는 TCP/IP 프로토콜을 통해 서버로 전송되게 된다.

TCP/IP

TCP/IP는 현재의 인터넷에서 컴퓨터들이 서로 정보를 주고 받는데 쓰이는 통신규약(프로토콜)의 모음으로 총 4개의 계층으로 이루어져 있다.


(사진 출처: https://intrepidgeeks.com/tutorial/tcpip)

HTTP Request를 받은 구글 서버는 클라이언트의 요청 문서를 받아 이를 바이트 형태로 변환 후 다시 클라이언트로 HTTP Response를 보낸다. 이때 전달 과정에서 Status Code를 통해 서버 요청에 따른 결과 및 상태를 전송한다.

3. 렌더링

브라우저 엔진은 구글 서버로부터 전달받은 데이터에 바이러스가 있는지 우선적으로 검사한 뒤, 바이트 형태의 텍스트 문서를 브라우저 엔진이 해석할 수 없기 때문에 렌더링 엔진에게 데이터 해석 및 렌더링을 요청한다.

요청을 받은 렌더링 엔진은 데이터를 바탕으로 렌더링 프로세스를 진행하고, 이 과정이 끝나면 브라우저 엔진에게 작업 완료를 알리게 된다.

이 과정들이 모두 끝나면, 마침내 사용자가 보고 있는 화면에 구글 페이지가 출력되는 것이다!

렌더링 프로세스

렌더링 프로세스는 다음과 같은 4가지 단계로 진행된다.

  1. HTML을 파싱하여 DOM 트리 구축, CSS를 파싱하여 CSSOM 트리 구축 (+ JS 파싱)

  2. DOM 트리와 CSSOM 트리를 통해 렌더 트리 구축 (Attachment / 형상 구축)

  3. 레이아웃 배치 (Layout / Reflow)

  4. 페인트 (Paint)

파싱

파싱은 단순한 텍스트 문서를 해석하지 못하는 브라우저를 위해 문서를 브라우저가 이해할 수 있는 구조로 변환시켜주는 과정을 말한다. 문자열을 의미 있는 작은 단위인 토큰(token)으로 분해하는 과정인 어휘 분석과 문자열의 문법에 따라 토큰 간의 위계관계를 분석하여 parsing 트리를 생성하는 과정인 구문 분석의 단계로 나뉜다. parsing 트리는 토큰화된 문자열의 단순한 트리에 불과하기 때문에, 브라우저는 이 parsing 트리를 DOM 트리와 CSSOM 트리로 변환하여 사용한다.

HTML 파싱, DOM 트리 생성

렌더링 엔진이 HTML 문서를 수신받으면, HTML 파서는 이를 위에서부터 읽어 내려가며 파싱을 진행하고 DOM 트리를 생성하게 된다. HTML 파싱은 다음과 같이 진행된다.

  1. 서버에서 바이트 형태의 HTML 문서를 응답 받는다.

  2. 저장된 인코딩 방식에 따라 이를 문자열로 변환한다.

  3. 변환된 문자열을 토큰으로 분해한다.

  4. 토큰을 내용에 따라 객체(노드)로 변환한다.

  5. 노드를 트리 구조로 구성하여 DOM 트리를 생성한다.

바이트 -> 문자열 -> 토큰 -> 노드 -> DOM 트리

CSS 파싱, CSSOM 트리 생성

HTML 파싱 중 CSS 문서를 가져오는 link 태그를 인식하게 되면, DOM 트리 생성을 중단하고 CSS 파싱이 진행된다. CSS 파서는 서버에서 수신받은 CSS 문서를 파싱하여 CSSOM 트리를 생성하는데, CSS 파싱 과정은 기본적으로 HTML 파싱 과정과 동일하다.

JavaScript 파싱, AST 생성

HTML 파싱 중 script 태그를 인식하게 되면, 렌더링 엔진은 DOM 트리 생성을 중단하고 서버에서 해당 JavaScript 리소스를 브라우저 엔진으로부터 받아오게 된다. 그리고 JavaScript 엔진에게 제어권을 넘겨준다.

JavaScript 엔진은 받아온 JavaScript 리소스를 파싱하여 AST(추상 구문 트리)를 생성하고 이를 바이트 코드로 변환하여 실행한다. JavaScript 파싱이 종료되면 렌더링 엔진은 다시 제어권을 돌려받고 DOM 생성을 이어나가게 된다.

만일 JavaScript 코드 내부에 DOM이나 CSSOM을 변경하는 DOM API가 사용된 경우, DOM이나 CSSOM이 변경되게 된다. 이때 변경된 DOM이나 CSSOM은 다시 렌더 트리로 결합되고 변경된 렌더 트리를 기반으로 레이아웃과 페인트 과정을 거쳐 브라우저의 화면에 다시 렌더링된다. 이를 리플로우, 리페인트라 한다.

렌더 트리(Render Tree) 생성

HTML과 CSS의 파싱 과정이 모두 끝나면, DOM 트리와 CSSSOM 트리를 서로 결합하여 렌더 트리 (Render Tree)가 생성되게 된다. 렌더 트리는 다음과 같은 과정을 통해 생성된다.

  1. html 태그와 body 태그를 처리하며 렌더 트리 루트를 구성한다.

  2. DOM의 최상위 노드부터 순회하면서 화면에 보여지지 않는 노드를 렌더 트리의 구성에서 제외한다. (이때 display:none과 같이 공간을 차지하지 않는 태그가 적용된 노드는 렌더 트리의 구성에서 제외된다.)

  3. 화면에 보여지는 나머지 노드에 CSSOM 규칙을 찾아 일치하는 스타일을 적용한다.
    (position이나 float를 사용했을 경우, 실제 그려지는 위치로 렌더 객체가 이동한다.)

레이아웃(Layout)

렌더 트리 생성이 완료되면, 렌더 트리 내 각 노드의 위치, 크기를 계산하고 이를 화면에 배치하는 레이아웃(Layout) 과정이 진행된다.

이때 노드의 위치는 (x, y) 좌표계를 사용하며, 렌더 트리의 루트부터 아래로 내려가면서 계산을 진행한다. 최상위 노드의 위치는 (0, 0)이며, CSS에서 상대적인 모든 값들은 절대값인 px 단위로 변환된다.

페인트(Paint)

마지막으로, 레이아웃 과정에서 계산된 정보들을 바탕으로 각 노드를 화면에 그려주는 페인트(Paint) 과정이 진행된다. 페인트는 렌더 트리의 각 노드를 화면의 실제 픽셀로 변환해주는 작업이다. 픽셀로 변환하는 이 과정을 Rasterizing이라 한다. 페인트까지 마무리 되면 브라우저 화면에 구글 페이지가 나타난다.

브라우저에게 감사하다.

이렇듯 우리가 단순히 www.google.com을 주소창에 입력해 구글 페이지가 우리 눈앞에 나타나기까지, 정말 수많은 과정들을 브라우저는 진행하게 된다. 우리가 일일히 이런 작업을 안하고 쉽게 페이지를 이동하게 할 수 있는 브라우저? 감사하다.

참고 자료

https://velog.io/@sylagape1231/%EC%A3%BC%EC%86%8C%EC%B0%BD%EC%97%90-naver.com%EC%9D%84-%EC%B9%98%EB%A9%B4-%EC%9D%BC%EC%96%B4%EB%82%98%EB%8A%94-%EC%9D%BC%EC%9D%84-%EC%89%BD%EA%B2%8C-%EC%9D%B4%ED%95%B4%ED%95%B4%EB%B3%B4%EC%9E%90

https://velog.io/@tnehd1998/%EC%A3%BC%EC%86%8C%EC%B0%BD%EC%97%90-www.google.com%EC%9D%84-%EC%9E%85%EB%A0%A5%ED%96%88%EC%9D%84-%EB%95%8C-%EC%9D%BC%EC%96%B4%EB%82%98%EB%8A%94-%EA%B3%BC%EC%A0%95

https://intrepidgeeks.com/tutorial/tcpip

profile
Front-End Developer

0개의 댓글