google.com을 입력하면 생기는 일
과연 주소창에 google.com
을 검색하면 무슨일이 일어날까?
이를 비교적 상세히 나열해보면 다음과 같다.
- 사용자가 Browser에서
google.com
을 검색한다. - Browser DNS Cache에 해당 도메인(
google.com
)을 질의한다(Query 요청을 보낸다).- Chrome의 경우
chrome://net-internals/#dns
에서 확인 가능하다. - Cache를 찾을 때 질의를 하기 전, expiration date 등의 유효성을 검증한다.
- Chrome의 경우
- 만약 Browser DNS Cache에서 못 찾으면 OS의
host
파일이 위치한 OS DNS Cache에서 해당 도메인을 질의한다(Query 요청을 보낸다).- macOS의 경우,
/etc/hosts
에, Windows의 경우,%WinDir%\HOSTS
에 존재한다. - Cache를 찾을 때 질의를 하기 전, expiration date 등의 유효성을 검증한다.
- macOS의 경우,
- 만약 두 가지 캐시에서도 찾지 못하면 Router DNS Server(DNS 기능이 없는 Router일 수도 있음)에서 조회한다.
- 이는 macOS의 경우
/etc/resolv.conf
에, Windows의 경우,Get-DnsServerRootHint
명령어를 통해 확인할 수 있다. - Cache를 찾을 때 질의를 하기 전, expiration date 등의 유효성을 검증한다.
- 이는 macOS의 경우
- 그래도 존재하지 않는다면, root 네임서버부터 조회하게 된다.
- 가령,
google.com
인 경우.
(root) →com
(top-level 도메인 네임서버) →google
(second-level 도메인 네임서버) → third-level 도메인 네임서버 순서로 redirect시키며 recursive하게 찾는다.
- 가령,
- 해당 도메인 기록을 가진 DNS를 찾게되면, 찾은 주소를 DNS recursor로 보낸다.
- 이때, ISP(Internet Service Provider)에서 제공하는 DNS recursor는 클라이언트와 DNS 사이의 중간 매개자 역할을 하는데, 네임서버로부터 받은 정보를 Cache하게 된다.
- DNS recursor는 전달 받은 응답을 권한 있는 네임서버에 보내게 되는데, 이로써 IP주소를 최종적으로 확인하게 된다.
- 획득한 서버의 IP주소로 TCP Socket을 열고, HTTP 1.1 GET Request를 요청한다.
- TCP 3-way handshake 방식으로 연결을 수립한다.
netstat
명령어로 수립된 연결을 확인할 수 있다.
- 연결이 완료되면, 웹 브라우저가 서버에 HTTP 프로토콜을 기반으로 Resource를 요청한다.
- 브라우저의 HTML파서는 HTML 문서를 파싱하고, 각 태그를 활용해 DOM(Document Object Model, HTML 문서를 JavaScript의 객체로 표현한 것. Browser에서 제공하는 고차원의 Web API이다.) Tree를 구성한다.
- 서버로부터 Response Header가
Content-Type: text/html
로 설정 돼 있는 binary stream format을 받는다. - HTML파서는 이를 읽을 수 있는 text 형태로 변환한다.
- 서버로부터 Response Header가
- CSS파서는 CSS 파일을 파싱하고, 각 스타일 규칙을 만든다.
- DOM Tree와 스타일 규칙을 포함해 Render Tree 혹은 Frame Tree를 구성한 뒤, 이들을 화면에 배치하고 브라우저 상에서 그리게 된다.
- JavaScript의 코드는 parser-blocking script이기 때문에, HTML을 parsing 하는 것을 중단시킨다. 그리고 만약 외부의 JavaScript 파일이라면, 이를 다운로드 할 때까지 main thread를 중단시킨다.
- JavaScript 파일이 다운로드 되면, 해당 파일부터 실행한 다음, HTML을 마저 parsing한다.
- 만약, DOM parsing과 script execution이 병렬적으로 일어난다면, DOM parser thread와 main thread간 race condition이 발생하게 된다.
- 하지만 대부분의 경우, 외부에서 다운로드 된
<script>
때문에 DOM parsing을 멈추는 경우는 불필요하기 때문에 HTML5에서는async
옵션을 제공한다. - 덕분에 script는 백그라운드에서 다운로드 되고, 다만 다운로드가 완료되면 main thread를 중단하고, 해당 script를 실행한다.
- 참고로 외부의
<style>
파일은 parser-blocking resource가 아니지만, render-blocking resource이다. 즉, stylesheet가 모두 다운로드 될 때까지 실행되지 않는다. 만약 모든 stylesheet가 다운로드 된다면, 그제서야 stylesheet를 파싱하고, render를 실행한다.