티스토리 뷰
브라우저의 주요 기능
브라우저의 주요 기능은 사용자가 서버에 필요한 자원을 요청하면 요청한 자원을 브라우저에 표시하는 것이다. 요청하는 자원은 대부분 HTML 문서 형식이지만, PDF나 이미지 등의 다른 형식일 수도 있다. 브라우저는 HTML, CSS 명세에 따라서 HTML을 해석해서 표시하는데, 이 명세는 웹 표준화 기준인 W3C(World Wide Web Consortium)에서 정해진다. 대표적인 웹 브라우저는 크롬, 파이어폭스, 사파리 등이 있다.
요청과 응답
- 요청(request) : 클라이언트가 웹 서버에게 웹 페이지를 달라고 하는 것
- 응답(response) : 요청한 웹 페이지를 클라이언트에게 제공하는 것
브라우저의 기본 구조
1) 사용자 인터페이스
사용자 인터페이스는 사용자가 접근할 수 있는 영역이다. URI를 입력할 수 있는 주소 표시줄, 이전/다음 버튼, 북마크 메뉴 등 요청한 페이지를 보여주는 창을 제외한 나머지 모든 부분이다.
2) 브라우저 엔진
사용자 인터페이스와 렌더링 엔진 사이 동작을 제어한다. 자료 저장소를 참조하며 로컬에 데이터를 쓰고 읽으면서 다양한 작업을 한다.
3) 렌더링 엔진
웹 서버로부터 응답 받은 자원을 웹 브라우저 상에 나타낸다. HTML, CSS를 파싱해 화면에 요청한 컨텐츠를 표시하는 역할을 한다.
4) 통신
HTTP 요청과 같은 네트워크 호출에 사용된다. 플랫폼 독립적인 인터페이스이고 각 플랫폼 하부에서 실행된다.
5) JS 엔진
자바스크립트 코드를 해석하고 실행한다.
6) UI 백엔드
기본적인 위젯을 그린다. 플랫폼에서 명시하지 않은 일반적인 인터페이스로서, OS 사용자 인터페이스 체계를 사용한다.
7) 자료 저장소
자료를 저장하는 계층으로 쿠키 등을 저장하는 웹 데이터베이스이다.
브라우저의 동작 원리
1. 데이터를 받아오는 과정
1) 브라우저에 웹 주소 입력
웹 브라우저의 주소 창에 웹 주소를 입력하는 단계이다. 예를 들면 Google이라는 사이트에 접속하기 위해서는 주소 창에 www.google.com을 입력하게 된다.
2) 캐싱된 DNS 기록들을 통해 해당 도메인 주소와 대응하는 IP 주소 확인
DNS 서버에 요청을 보내서 IP 주소를 찾기 전에, 이전에 접속한 기록이 있는지 확인해보면서 기록이 있다면 대응하는 IP 주소를 확인한다. 만약, 캐싱된 기록에 없을 경우에는 다음 단계로 넘어간다.
3) 브라우저가 DNS 서버에 요청을 보내 주소 획득
웹 브라우저가 DNS 서버에 요청을 보내서 웹 사이트의 도메인 주소에 해당하는 IP 주소를 얻는다. 이때 DNS 서버는 웹 사이트의 IP 주소와 도메인 주소를 이어주는 역할을 하는 서버이다. 간단히 생각해서 웹 사이트의 주소록 같은 곳이라고 보면 된다. 처음부터 IP 주소를 이용하지 않는 이유는 사용자들이 직관적으로 이해하고, 사용하기 쉽도록 하기 위해서이다. 또한, IP 주소가 변경되더라도 사용자는 같은 도메인 주소를 통해서 접근하도록 할 수 있다.
4) DNS가 웹 브라우저에게 찾는 사이트의 IP 주소 응답
일치하는 IP 주소를 찾을 때까지 서로 다른 DNS 서버를 오가며 에러가 날 때까지 반복적으로 검색한다. DNS 서버는 한 개가 아니라 여러 조직이나 기업, 개인 등이 운영한다.
5) IP 주소를 받은 브라우저는 해당 요청을 IP 주소와 일치하는 서버로 전달
서버에 웹 사이트 사본을 요청하기 위해서 HTTP 메시지를 전송한다. 이때 전송되는 모든 데이터는 TCP/IP 연결을 통해서 전송된다. TCP/IP(Transmission Control Protocal / Internet Protocol)은 데이터가 웹을 건너서 전송되기 위한 자세한 규칙을 지정하는 통신 규약이다.
6) 서버는 웹 사이트 파일들을 데이터 패킷을 통해 브라우저로 전송
서버는 브라우저에게 응답을 보낸다. 이때, 응답은 status code로 서버 요청에 따른 상태를 보낸다. 또한, 웹 사이트의 파일들을 데이터 패킷을 통해 전송한다. 효율성을 위해 패킷이라 불리는 작은 덩어리들로 나눠서 전송하게 된다.
HTTP Status Code
- 1xx : 정보가 담긴 메시지
- 2xx : response 성공
- 3xx : 클라이언트를 다른 URL로 리다이렉트
- 4xx : 클라이언트 측에서 에러 발생
- 5xx : 서버 측에서 에러 발생
2. 렌더링 엔진 동작 과정
위 과정의 마지막 단계인 서버로부터 요청한 문서의 내용을 얻는 것부터 렌더링 엔진의 동작이 시작된다.
1) DOM Tree 구축을 위한 HTML 파싱
서버에서 응답 받은 HTML 문서를 파싱하여서 Dom Tree를 생성한다. 이때 파싱이란 브라우저가 코드를 이해하고 사용할 수 있는 구조로 변환하는 것이다. HTML을 파싱하고 Dom Tree를 구축하는 단계는 아래와 같다.
(1) 브라우저로부터 요청 받은 HTML 파일을 읽어들인 후 메모리에 저장하고 바이트를 응답한다.
(2) 브라우저는 응답 받은 바이트 형태의 문서를 <meta> 태그의 charset 속성에 지정된 인코딩 방식에 따라 문자열로 반환한다.
(3) 반환된 문자열을 HTML 표준에 따라 최소 단위인 토큰으로 분해한다.
(4) 토큰들의 내용에 따라 객체로 변환하여 각 노드를 생성한다.
(5) HTML은 요소 간의 부자 관계인 중첩 관계를 갖는데, 이를 반영하여 모든 노드들을 트리 구조로 구성하여 DOM을 만든다.
2) CSS 파일을 읽어서 CSSOM 구축
HTML 문서를 파싱하다가 CSS를 불러오는 태그를 만나면 CSS 요청을 받아온다. CSS 파싱도 HTML가 유사한 형식으로 진행되며 만들어진 Tree를 CSSOM이라고 부른다.
3) Render Tree 생성
DOM Tree가 구축되는 동안 브라우저는 Render Tree를 구축한다. 이 과정을 Attachment라고 부른다. Render Tree는 DOM Tree와 CSSOM을 결합한 형태이다. 여기에는 페이지를 렌더링하는데 필요한 가시적인 노드만 포함된다. 따라서, <meta>나 <script> 같은 노드나 display: none으로 스타일이 지정된 노드는 제외된다. 다만, visibility: hidden이 적용된 노드는 보이지 않지만 공간을 차지하기 때문에 Render Tree에 포함된다
4) Layout 과정
Render Tree에서 노드들이 가지고 있는 속성과 스타일에 따라서 브라우저에 출력될 크기와 위치를 받아온다. 이때 CSS에서 %, rem, vh 등의 모든 상대적인 값이 절대적인 값인 px 단위로 변환된다.
5) Paint 과정
Layout 과정에서 계산된 값들을 기반으로 화면에 필요한 요소들을 실제로 그리는 작업이다.
Javascript 파일 처리
위 과정을 통해서 HTML과 CSS 파일들이 처리되는 과정을 살펴보았는데 그렇다면 Javascript 파일은 어떻게 처리될까? Javascript는 렌더링 엔진이 아니라 자바스크립트 엔진이 처리한다. HTML 파서는 HTML 파일을 위에서부터 처리하다가 <script> 태그를 만나면 Javascript 코드를 실행하기 위해서 DOM 생성 프로세스를 중지하고 자바스크립트 엔진으로 제어 권한을 넘긴다. 제어 권한을 넘겨 받은 자바스크립트 엔진은 <script> 태그 내의 Javascript 코드 또는 src 속성에 정의된 Javascript 파일을 로드하고 파싱하여 실행한다. Javascript의 실행이 완료되면 다시 HTML 파서로 제어 권한을 넘겨서 중지했던 시점으로 돌아가 DOM 생성을 재개한다.
이처럼 브라우저는 동기적으로 HTML, CSS, Javscript 코드를 처리한다. 다르게 말하면 <script>의 위치에 따라서 DOM 생성이 지연될 수 있기 때문에 <script> 태그를 적절한 위치에 배치하는 것이 중요하다. 그래서 <script> 태그는 <body> 요소의 가장 아래 쪽에 위치시키는 것이 좋다.
참고 자료
https://d2.naver.com/helloworld/59361
https://bbangson.tistory.com/87
https://hanamon.kr/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EA%B8%B0%EB%B3%B8-%EB%8F%84%EB%A9%94%EC%9D%B8%EA%B3%BC-dns-%EB%84%A4%EC%9E%84%EC%84%9C%EB%B2%84%EB%9E%80-%EA%B0%9C%EB%85%90%ED%8E%B8/
https://velog.io/@eassy/www.google.com%EC%9D%84-%EC%A3%BC%EC%86%8C%EC%B0%BD%EC%97%90%EC%84%9C-%EC%9E%85%EB%A0%A5%ED%95%98%EB%A9%B4-%EC%9D%BC%EC%96%B4%EB%82%98%EB%8A%94-%EC%9D%BC
https://poiemaweb.com/js-browser
https://lsw0150305.gitbook.io/til/web/web-browser-working-flow
https://velog.io/@thyoondev/%EC%9B%B9-%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80%EC%9D%98-%EB%8F%99%EC%9E%91%EC%9B%90%EB%A6%AC%EB%A5%BC-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90