Skip to main content

google.com을 입력하면 생기는 일

과연 주소창에 google.com을 검색하면 무슨일이 일어날까? 이를 비교적 상세히 나열해보면 다음과 같다.

  1. 사용자가 Browser에서 google.com을 검색한다.
  2. Browser DNS Cache에 해당 도메인(google.com)을 질의한다(Query 요청을 보낸다).
    • Chrome의 경우 chrome://net-internals/#dns 에서 확인 가능하다.
    • Cache를 찾을 때 질의를 하기 전, expiration date 등의 유효성을 검증한다.
  3. 만약 Browser DNS Cache에서 못 찾으면 OS의 host 파일이 위치한 OS DNS Cache에서 해당 도메인을 질의한다(Query 요청을 보낸다).
    • macOS의 경우, /etc/hosts에, Windows의 경우, %WinDir%\HOSTS에 존재한다.
    • Cache를 찾을 때 질의를 하기 전, expiration date 등의 유효성을 검증한다.
  4. 만약 두 가지 캐시에서도 찾지 못하면 Router DNS Server(DNS 기능이 없는 Router일 수도 있음)에서 조회한다.
    • 이는 macOS의 경우 /etc/resolv.conf에, Windows의 경우, Get-DnsServerRootHint 명령어를 통해 확인할 수 있다.
    • Cache를 찾을 때 질의를 하기 전, expiration date 등의 유효성을 검증한다.
  5. 그래도 존재하지 않는다면, root 네임서버부터 조회하게 된다.
    • 가령, google.com인 경우 .(root) → com(top-level 도메인 네임서버) → google(second-level 도메인 네임서버) → third-level 도메인 네임서버 순서로 redirect시키며 recursive하게 찾는다.
  6. 해당 도메인 기록을 가진 DNS를 찾게되면, 찾은 주소를 DNS recursor로 보낸다.
    • 이때, ISP(Internet Service Provider)에서 제공하는 DNS recursor는 클라이언트와 DNS 사이의 중간 매개자 역할을 하는데, 네임서버로부터 받은 정보를 Cache하게 된다.
    • DNS recursor는 전달 받은 응답을 권한 있는 네임서버에 보내게 되는데, 이로써 IP주소를 최종적으로 확인하게 된다.
  7. 획득한 서버의 IP주소로 TCP Socket을 열고, HTTP 1.1 GET Request를 요청한다.
  8. TCP 3-way handshake 방식으로 연결을 수립한다.
    • netstat 명령어로 수립된 연결을 확인할 수 있다.
  9. 연결이 완료되면, 웹 브라우저가 서버에 HTTP 프로토콜을 기반으로 Resource를 요청한다.
  10. 브라우저의 HTML파서는 HTML 문서를 파싱하고, 각 태그를 활용해 DOM(Document Object Model, HTML 문서를 JavaScript의 객체로 표현한 것. Browser에서 제공하는 고차원의 Web API이다.) Tree를 구성한다.
    • 서버로부터 Response Header가 Content-Type: text/html로 설정 돼 있는 binary stream format을 받는다.
    • HTML파서는 이를 읽을 수 있는 text 형태로 변환한다.
  11. CSS파서는 CSS 파일을 파싱하고, 각 스타일 규칙을 만든다.
  12. DOM Tree와 스타일 규칙을 포함해 Render Tree 혹은 Frame Tree를 구성한 뒤, 이들을 화면에 배치하고 브라우저 상에서 그리게 된다.
  13. 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를 실행한다.
Related Links