[번역] 브라우저는 어떻게 작동하는가? (모든 개발자들이 알아두어야 할 사실)

나의 개발 일지·2023년 11월 8일
8

번역해보았다. 🌎

목록 보기
2/2

최근에 크롬을 제외하고 한 브라우저(Arc)를 접하게 되었는데 너무나 잘 사용하게 되어서 이를 통해 브라우저라는 것에 관심이 많이 생겼다. 프론트엔드 개발자로서 브라우저를 더 알아보고 싶어졌기에 관련 글이나 내용을 번역 또는 정리 해보려고 한다.


본문은 브라우저와 브라우저 엔진의 원리보다는 브라우저를 사용하기 위해 필요한 네트워크와 브라우저의 기본을 설명하고 있다. 언젠가 마주친 질문 "주소창에 Google을 입력하면 무슨일이 일어날까요?"의 긴 대답이라고 생각하면 좋겠다.

원글)
How Browsers Work: Everything Developers Need To Know by Jan Kammerath




브라우저가 내부적으로 스스로를 가르키는 이름은 "Navigator"이다.


서문

나는 테크리더이자 매니저 그리고 다수의 개발 팀들을 관리하는 CTO로서, 지난 20여년 동안 수십명의 소프트웨어 개발자들을 인터뷰했다.

나는 적합성을 판가름하는 인터뷰 질문 리스트를 특정하게 정해놓고 사용하지는 않지만, 프로그래밍과 컴퓨팅 그리고 네트워킹이라는 분야에 대한 지식을 판단할 수 있는 좋아하는 몇 가지의 질문들을 가지고 있다.

내가 계속해서 개발자들에게 물어보기 좋아하는 질문들 중 하나는 이것이다.

"당신이 브라우저 아이콘을 클릭하는 그 순간부터 당신이 스크린에서 홈페이지를 보기까지의 순간에 무슨 일이 일어나는지 설명해주겠는가?"

나는 이 질문을 백번도 넘게 물어보았던 것 같다. 단순히 개발자들과의 직무 면접에서 뿐만 아니라 소프트웨어 비즈니스에서 기술직군 비기술직군의 직원들을 상대로 하는 다양한 프로그램에서도 말이다.

이 질문은 한 사람이 인터넷에 대해서 어느정도로 이해하고 있는 가를 판단할 수 있는 질문일 뿐만 아니라 사람들에게 실제로 인터넷이 어떻게 동작하는지 훈련시킬 수 있는 훌륭한 시작점이다.

많은 개발자들과 함께했던 나의 경험들 속에서 나는 많은 개발자들이 사실은 인터넷과 브라우저가 정확히 어떻게 동작하는지 알지 못하고 IP 프로토콜이 무엇을 위한 것이며 또한 어떻게 이러한 서비스들이 서로 간의 연결되어있는지를 알지 못한다는 것을 발견했다.

우리는 매일 매일 배워 나가고 있으며 지식들에 대한 각자마다의 성취도가 다르기 때문에 모든 것을 다 알지 못해도 괜찮다.

우리는 이제 부터 브라우저 아이콘을 클릭해 렌더링된 웹 페이지를 보기까지의 과정을 경험할 것이다. 당신이 이러한 모든 세부사항들을 전부 알고 있는지 한 번 살펴보고 그렇지 않다면 이 과정은 훌륭한 학습 경험이 될 것이다.




당신이 "인터넷을 열면" 어떠한 일이 일어나는 가

일반적인 비기술 직군의 사람들은 그들의 인터넷 브라우저를 소위 "인터넷" 이라고 생각한다. 그들은 인터넷과, IP 프로토콜을 통해 동작하는 과정과, 월드 와이드 웹, HTTP 프로토콜을 통해 동작하는 과정들이 모두 다르다고 생각하지 않는다. 그들은 브라우저 어플리케이션을 실행시키는 것을 "온라인에 접속한다", "인터넷을 연다" 또는 "웹을 실행시킨다" 라고 이야기한다. 사회적으로는 이러한 문장들이 용인되고 받아들여질 수 있긴 하지만 기술적으로 이러한 이야기는 거의 전부 옳지 않다.

초보 개발자들은 보통, 그들의 직업을 고려했을 때, 실제로 어떠한 일들이 발생하는 가에 대해서 보다 더 잘 알고 있다. 내가 인터뷰 중에 이에 대해서 더 깊게 질문하면, 그들의 지식이 여전히 중요한 세부 사항들을 놓치고 있다는 사실들이 드러나기는 하지만 말이다. 많은 개발자들은 HTTP 와 같은 응용계층의 프로토콜이 어떻게 작동하는지에 대해서 어느정도 익숙하다. 하지만 종종 IP, TCP 그리고 DNS에 대해서 깊은 지식을 가지고 있지는 않아 보인다. 현대의 다양한 환경에서 배포되어있는 어플리케이션들에 대해서(클라우드, 온프레미스, 모바일, 임베디드), 이러한 지식들은 굉장히 중요하다. 특히 어플리케이션이나 시스템의 네트워킹 활동과 관련되어 있는 에러들을 해결해야 할 때 말이다.

1998년 Excite와 파트너쉽을한 애플의 홈페이지를 Netscape Navigtor를 통해 연 모습


모든 것이 보다 단순하고 좀더 느렸던 1995년에 나는 처음으로 월드 와이드 웹을 접하긴 했지만, 이 과정 자체는 지금까지 거의 동일하게 유지되고 있다. 오늘날과 그 당시의 가장 큰 차이점이라고 하면, 현재는 네트워킹을 사용하지 않는 어플리케이션이 거의 남아있지 않다는 사실이다. 90년대 이야기를 하자면, 그때 당시에는 윈도우 95 데스크탑 어플리케이션을 네트워킹과 관련된 어떠한 것도 한 번 신경쓰지 않고 만들어낼 수 있었다. 인터넷, IP, ICMP, TCP 그리고 UDP 말이다.

웹사이트를 컴퓨터에서 로딩하고 렌더링하는 과정은 거의 모든 컴퓨팅 플랫폼에서 동일하게 동작한다. Windows 에서도 그렇고, Linux, macOS, iOS, Android나 삼성TV에서도 말이다. 그들은 다양한 물리적 환경에서 동일한 작업을 수행한다. 현재의 가장 물리적으로 흔한 미디어는 IEEE 802.3 (이더넷, 종종 LAN이나 로컬 네트워크라고), IEEE 802.11 (와이파이나 무선 LAN) 그리고 3GPP 15 (모바일 네트워크나 4G, 5G) 이후 버전에 정의되어 있다. 간단 명료하게 하기 위해서, 우리는 이 과정을 사람들이 가장 비슷하게 사용하고 있는 Windows, Linux, macOS, iOS 그리고 Android에 집중하도록 하겠다.



#1 브라우저 어플리케이션을 로딩시키기

당신의 기기의 운영 체제에는 "인터넷 브라우저" 라고 불리우는 어플리케이션이 설치되어있다. 오늘날의 대부분의 운영체제들은 브라우저 어플리케이션이 탑재되어 나온다. Windows의 경우에는 "Microsoft Edge", macOS와 iOS의 경우에는 "Safari", Android에는 "Google Chrome", 대부분의 Linux의 배포버전에는 "Mozilla Firefox" 가 설치되어 있다.

Windows 11은 Microsoft Edge 가 기본 설정으로 따라온다.


당신은 브라우저 어플리케이션을 실행프로그램(데스크탑이나 홈스크린에 존재하는 바로가기 아이콘)을 클릭하는 것으로 "실행 " 시킨다. 실행시킨다는 것의 정확한 뜻은 당신이 운영체제에게 응용프로그램의 바이너리 파일을 디스크나 저장소등의 그것이 존재하는 위치로부터 기기의 메인메모리(RAM)로 로딩하라는 명령을 내린 것을 의미한다. 그리고 CPU에서 바이너리에 존재하는 프로그램을 실행시킨 것이 해당한다. 모든 브라우저들이 대부분 시스템 언어인 C, C++, Rust, Go로 작성되어있기에, 브라우저의 실행파일 또는 바이너리는 실제 기계어를 포함하고 있다.

보다 장황하지 않고 간단하고 짧게 설명하기 위해서, 어떻게 운영 체제가 이러한 응용프로그램을 다루고 실행시키는지에 대해서는 설명하지 않을 것이다. 우리는 운영체제에 대한 부분에 대해서 추상적인 단계로 남겨두고, 운영체제가 드라이버를 통해서 NIC(네트워크 인터페이스 카드)와 어떻게 소통하고 기저에서 네트워킹에 어떻게 접속하는지에 대한 사실을 살펴볼 것이다.



#2 브라우저가 네트워크 라이브러리를 초기 설정하기

그 당시에 내가 Windows 95에서 Netscape Navigator를 사용했던 많은 날들에서, 나는 브라우저가 실행된 직후 곧 바로 다이얼-업 프롬프트롤 볼 수 있었다. (과거 인터넷에 접속하기 위해서는 전화를 통해서 인터넷 연결을 할 수 있었고 이를 컴퓨터에서 연결시키는 과정을 보여주는 화면을 말한다.) 이렇게 작동했던 이유는 브라우저가 시스템 라이브러리가 네트워킹을 위해서 연결을 초기설정하기 위해서였다. 이러한 라이브러리들은 브라우저 응용프로그램으로부터 모든 네트워킹 기능들을 추상화했고 이를 통해서 근본적으로 네트워크 스택들에 대해 처리하지 않도록 하기 위해서였다. Windows 95 에서는 이것이 윈도우즈 소켓 API를 제공했던 winsock.dll (Windows Socket Library) 였다. 소켓 라이브러리는 저단계의 프로토콜인 IP(Internet Protocol)와 같은 것들을 신경쓰지 않고도 TCP 연결들을 다룰 수 있도록 해주는 TCP
(Transport Control Protocol) 소켓을 제공해 주었다. 나의 Windows 95 컴퓨터가 다이얼-업 모뎀을 사용했기 때문에, 운영 체제는 나(사용자)로 부터 다이얼-업 연결을 통해 네트워킹 기능을 브라우저 응용프로그램에 제공할 것인지 확인받았다.

Windows 95가 PPP 를 통해 연결된 모뎀창을 보여주고 있다.


Windows 95 나 Macintosh System 9 과 다르게, 현대의 시스템들인 Windows 11, macOS, Linux, iOS 그리고 Android 는 항상 연결 되어있다고 여겨진다. 이는 운영 체제가 항상 인터넷 연결이 되어있다고 판단하는 상태로 작동한다는 것을 의미한다. 90년대 초의 Macintosh 나 DOS 그리고 Windows 3.1의 TCP/IP 스택은 종종 꽤 비싼 값을 요구하기도 했는데, 현대의 모든 운영 체제들은 모두 이것을 포함하고 있다. 현대의 운영 체제들 또한 역시 초기 설정을 필요로 하는데, 그들이 어떠한 응용프로그램이 네트워킹을 어떻게 사용하는 지에 대한 정보가 필요하기 때문이다. 운영체제는 이러한 정보를 바탕으로 에너지를 절약하거나 네트워크 인터페이스의 다른 기능들을 사용하거나 한다.(이더넷 혹은 와이파이 카드, 5G 또는 와이파이 칩)

네트워크 연결이 끊어지면 나타나는 Google Chrome 에러 메시지


브라우저가 네트워크 연결을 초기화려고 시도할 때, 여러가지 사항들이 문제를 일으킬 수 있다. Google Chrome의 에러코드 ERR_INTERNET_DISCONNECTED 는 시스템의 어떠한 어댑터도 작동하고 있는 공공 인터넷의 라우트에 접근할 수 없다는 것을 의미한다. Google Chrome의 모든 에러 코드들은 그들의 소스코드를 통해 확인할 수 있다. net_error_list.h

이런 과정들의 뒤에서, 운영 체제와 관련된 드라이버들은 모든 네트워크 어댑터들을 살펴본다. 이들은 IP 주소들을 할당하며 시스템 라우팅 테이블로 부터 IP 라우트를 확정한다. 이더넷, 와이파이 혹은 5G를 통한 물리적인 연결은 네트워크 인터페이스(NIC)들을 통해서 처리된다. 운영체제 또는 드라이버들은 DHCP(Dynamic Host Configuration Protocol: 동적으로 해당 IP주소에 대한 정보들을 호스트에 할당하는 프로토콜) 를 통해서 동적인 IPv4나 IPv6를 통한 IP 주소 할당을 처리한다. 따라서 브라우저는 인터넷 프로토콜에 대해서 처리할 필요가 전혀 없다.

IP와 물리적 연결에 대해 작업하기

하지만 만약 당신이 인터넷 프로토콜과 네트워크 어댑터들과 상호작용 하고 싶다면, 대부분의 프로그래밍 언어들은 시스템 라이브러리를 통해 네트워크 인터페이스의 정보에 접근 할 수 있도록 해주는 추상 라이브러리들을 가지고 있다. 밑의 코드는 Go로 작성된, 모든 네트워크 인터페이스 들과 그들의 연결 상태, 가능한 IP 주소들을 보여주는 코드이다.

package main

import (
 "fmt"
 "net"
)

func main() {
 ifaces, err := net.Interfaces()
 if err != nil {
  panic(err)
 }
 for _, iface := range ifaces {
  fmt.Printf("%v:\n", iface.Name)
  addrs, err := iface.Addrs()
  if err != nil {
   panic(err)
  }
  for _, addr := range addrs {
   fmt.Printf("  %v\n", addr)
  }
  fmt.Printf("  connected: %v\n", iface.Flags&net.FlagUp != 0)
 }
}

밑의 어플리케이션의 결과는 나의 루프백 어댑터 "lo0", 맥북 와이파이 어댑터 "en0" 그리고 USB 이더넷 어댑터 "en7" 을 보여준다. 이들 모두는 연결되어 있으며 IPv4 와 IPv6 주소를 가지고 있다. 현대의 많은 사람들과 같이 내가 개인용 네트워크를 가지고 있음을 생각할때, 나의 어댑터들은 모두 개인용 IP 주소들을 가지고 있으며 그들의 IP 패킷들이 내 지하에 있는 주 라우터를 통해 라우팅하고 있다는 것을 알 수 있다.

jan@MacBook-Pro-von-Jan % go run network.go
lo0:
  127.0.0.1/8
  ::1/128
  fe80::1/64
  connected: true
en0:
  fe80::4d6:ca0d:249d:fda7/64
  192.168.1.143/24
  connected: true
en7:
  fe80::8bd:7605:50b:d8da/64
  192.168.1.70/24
  connected: true

다음의 "traceroute" 커맨드는 IP 패킷들이 Google.de의 IP 주소로 향하는 경로들을 보여준다. Traceroute 는 ICMP(Internet Control Message Protocol: 네트워크 장치에서 네트워크 통신 문제를 진단하는 데 사용하는 네트워크 계층 프로토콜, 진단에 사용할 수 있는 메세지들을 정의해놓았다)을 사용한다. 또한 유명한 진단 도구인 "ping" (해당 IP 를 가진 장비에 접속 가능한지 확인하는 프로그램 echo request 를 던지고, 이로 부터 받은 echo reply 를 확인한다. 정상적으로 echo reply 를 수신하는 경우 수신까지 걸릴 시간을 계산하여 해당 장비까지 회선 속도를 가늠할 수 있다.)을 사용하는데, 이는 ICMP Echo Request 메세지를 보낸다. 인터넷 프로토콜(IP 또는 IPv4, IPv6) 또한 ICMP와 같이 인터넷 계층에서 가장 널리 사용되는 프로토콜이다.

traceroute to 142.250.185.163 (142.250.185.163), 64 hops max, 52 byte packets
 1  192.168.1.1 (192.168.1.1)  1.616 ms  0.597 ms  0.322 ms
 2  p3e9bf1b6.dip0.t-ipconnect.de (62.155.241.182)  4.747 ms * *
 3  ip-081-210-128-120.um21.pools.vodafone-ip.de (81.210.128.120)  10.827 ms
    f-ed11-i.f.de.net.dtag.de (62.154.17.150)  13.730 ms
    f-ed11-i.f.de.net.dtag.de (217.5.109.30)  10.114 ms
 4  80.150.170.70 (80.150.170.70)  12.342 ms  12.040 ms  12.030 ms
 5  84.116.190.94 (84.116.190.94)  16.651 ms  18.213 ms  16.965 ms
 6  108.170.252.1 (108.170.252.1)  45.377 ms
    74.125.32.52 (74.125.32.52)  21.895 ms  21.209 ms
 7  * 108.170.251.144 (108.170.251.144)  9.793 ms *
 8  142.250.226.148 (142.250.226.148)  21.620 ms
    fra16s51-in-f3.1e100.net (142.250.185.163)  12.968 ms  12.779 ms

브라우저는 IP 나 ICMP와는 어떠한 관계도 없다. 운영체제가 이러한 부분의 모든 것들을 현대적인 운영 시스템에서 관리하고 처리한다. 90년대 초, 브라우저들은 종종 그들만의 IP나 TCP 스택들을 포함해야했는데 이것들이 가끔 운영 체제내에 포함되어 있지 않았기 때문이다. 모든 IP 설정이 완료되고 운영체제가 브라우저를 위한 네트워킹을 초기설정하고 나면, 브라우저는 이제 나서서 작업에 뛰어들 수 있다 : "웹을 탐색하는 것 말이다."



#3 브라우저를 홈페이지에 연결시키기

이론적으로, 브라우저는 시작되거 난 이후 어떠한 일도 하지 않는다. 사용자는 Uniform Resource Locator(URL)을 브라우저의 주소 창에 입력한 후 엔터를 누르는 것으로 URL에 할당되어있는 콘텐츠를 로드하고 이후에 그들을 브라우저의 도큐먼트 뷰에 보여주어야 한다. 그러나 가장 초기의 브라우저들에서부터, 브라우저들에는 "홈페이지" 라고 불리는 설정이 생겼다. 이 설정은 브라우저가 실행된 즉시 컨텐츠를 로드하고 화면에 보여줄 수 있는 URL을 설정하는 것이었다.

Windows 98의 Netscape Navigator 와 기본 설정 홈페이지


URL은 브라우저가 로드하고 화면에 그려야할 리소스가 어디에 위치해있는지에 대해 정의한다. URL은 프로토콜(http 또는 대부분의 현대 브라우저에서는 https)을 정의하며, 호스트명 또는 IP 주소를 정의하고 리소스의 경로에 대해서 정의한다. URL은 선택적으로 "HTTP 기본 인증 " 을 위한 username과 password를 선택적으로 포함할 수 있다. 더 나아가서 만약 타겟 호스트가 HTTP 기본 설정인 80 혹은 HTTPS 기본 설정인 443 포트 외에 다른 포트를 사용한다면 다른 TCP 포트 주소를 추가할 수도 있다. 오래된 브라우저들은 FTP나 gopher와 같은 또 다른 다양한 프로토콜들을 지원하기도 했다. 프로토콜 파트를 가리커 "스키마(Schema)" 라고 부르기도 한다.

 |--------------------  Schema-specific part   -----------------------|
      |                                                                    |
https://username:passwd@www.example.com:8080/index.html?p1=A&p2=B#ressource
\___/   \______/ \____/ \_____________/ \__/\_________/ \_______/ \_______/
  |         |       |           |         |       |          |         |
Protocol Username Password      Host      Port    Path      Query    Fragment

만약 현대의 브라우저가 지원하지 않는 스키마(또는 프로토콜) 를 입력받게 되면, 브라우저는 운영 체제의 스키마 핸들러를 통해서 운영 체제 내에서 지정되어있는 해당 스키마의 기본 어플리케이션을 실행시키게 된다. 브라우저가 HTTP나 HTTPS 프로토콜을 입력받게 되면, 브라우저는 URL의 Host와 Port 부분을 파싱하게 된다. 이 두 부분만이 URL에서 원격 연결의 엔드포인트에 도착하기 위해 반드시 필요한 부분이기 때문이다.

호스트의 IP주소를 찾아내기

IP 패킷이 원격 시스템의 IP주소를 필요로 하기 때문에, 운영 체제는 호스트의 이름을 통해서 곧바로 접속할 수가 없다. 현대의 시스템 라이브러리들은 호스트 네임을 찾아낼 수 있는 시스템을 지원하지만, 90년대 후반까지만 해도 어플리케이션들은 DNS 검색 요청을 통해 따로 처리해야했다.

package main

import (
 "fmt"
 "net"
)

func main() {
 // Resolve IP address for www.example.com
 ipAddr, err := net.ResolveIPAddr("ip4", "www.example.com")
 if err != nil {
  panic(err)
 }

 // Print the IP address to the console
 fmt.Printf("IP address for www.example.com: %s\n", ipAddr.String())
}

위의 Go 어플리케이션은 www.example.com의 IP주소를 찾아내어 이를 standard ouput 형태로 출력한다. 이 경우와 호스트명에 연결하기 위한 TCP 소켓을 요청하게 되는 경우 운영체제는 IPv4 주소(DNS A-Record) 를 찾기 위해서 DNS (Domain Name System) 검색 작업을 실행하게 된다. IPv6 주소(DNS AAA-Record) 의 경우 네트워크 인터페이스의 IP 설정에 설정된 제공되는 DNS 서버를 사용하기 위해서 UDP(User Datagram Protocol)를 기본 DNS 포트(UDP port 53)에 연결한다. 요즘의 대부분의 경우에는 개인 사용자 홈 라우터의 DNS이거나 인터넷 서비스 제공자(ISP) 혹은 모바일 네트워크 오퍼레이터(MNO)의 DNS이다.

운영 체제가 IP 주소를 얻어낼 수 없다면, (e.g. the host does not exist) 브라우저는 오류를 보여주게 된다. 이 에러코드는 Chrome 과 Firefox에서 다음과 같이 나타난다.
DNS_PROBE_FINISHED_NXDOMAIN

원격 엔드포인트에 연결하기

운영체제가 IP 주소를 얻는 데 성공하게 되면, 운영체제는 브라우저를 위한 TCP 연결을 생성한다. HTTP 연결을 위해서 기본적인 TCP 연결을 구축하고, HTTPS를 위해서는 브라우저가 라이브러리를 통해 혹은 운영 체제 라이브러리를 통해 TCP 연결을 생성하고 TLS(Transport Layer Security) 터널을 TCP 연결을 통해 구축한다.

TCP연결이 구축되자마자, 브라우저는 Hypertext Transfer Protocol(HTTP) 프로토콜을 사용할 수 있게 된다. 브라우저는 다음과 같은 데이터를 TCP 연결을 통해 연결된 엔드포인트로 전송한다.

GET /index.html HTTP/1.1
Host: www.example.com
Accept-Language: en

원격 엔드포인트 (HTTP 서버 소프트웨어)는 이제 우리의 브라우저가 호스트명 "www.example.com" 의 root 디렉토리에서 파일명 "index.html" 을 얻길(GET) 원한다는 것을 확인할 수 있다. 해당 엔드포인트는 또한 브라우저가 영어로 된 결과물만을 필요로 한다는 것(Accept-Language header)을 알 수 있다. 엔드포인트는 이제 다음과 같은 결과물을 응답으로 전송한다.

HTTP/1.1 200 OK
Content-Type: text/html

<!DOCTYPE html>
<html>
  <head>
    <title>This is a title</title>
  </head>
  <body>
    <div>
        <p>Hello world!</p>
        <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/1/15/Cat_August_2010-4.jpg/640px-Cat_August_2010-4.jpg" alt="Felis catus" />
    </div>
    <script src="https://cdn.jsdelivr.net/npm/is-ten-thousand@1.2.0/index.min.js "></script>
  </body>
</html>

해당 응답은 HTTP 상태코드 200으로 시작하고 있으며, 이는 모든 요청이 성공적으로 완료되었고 콘텐츠가 반환되었음을 의미한다. 콘텐츠가 Hypertext Markup Language(HTML) 파일이기 때문에 서버는 콘텐츠 타입 헤더(Content-Type header)에 이를 가리키는 Media Type(이전에는 MIME type으로 불림)란에 "text/html"을 표시한다.

#4 브라우저가 도큐먼트를 렌더링하기

브라우저는 이제 HTML 콘텐츠를 읽어나가면서 추가적으로 불러와야 할 리소스가 있는지 파악한다. HTML이 작성된대로, 추가적인 리소스의 타입과 그것들이 위치한 장소를 파악하고, 브라우저는 가장 빠른 방법을 통해 리소스를 가져오려고 시도한다. 각각의 모든 추가적인 리소스들에 대해서 브라우저는 위에 적혀있는 모든 프로세스들을 다시금 실행시킨다.

HTML 도큐먼트는 종종 "웹 페이지(web pages)" 또는 "페이지(pages)" 라고 불리우기도 한다. 하지만 명세에 있는 정확한 기술적 용어는 "도큐먼트(doucment)" 이다. 만약 도큐먼트가 HTML, CSS와 이미지들만을 포함하고 있다면, 브라우저가 현재로써는 추가적으로 작업할 일이 없다. 브라우저는 이제 더 복잡한 작업을 진행해야 할 것이다:도큐먼트를 그려내는 일 말이다. 이 과정은 어떠한 요소(예를 들면 이미지) 들이 스크린에 어디에 위치하게 그려야 하는지 또 어떻게 그려져야 하는지 파악하는 과정을 포함한다. 이러한 렌더링 과정을 가리켜 렌더링 사이클이라고 말한다.

자바스크립트 코드 실행시키기

가장 처음으로 자바스크립트를 지원했던 브라우저는 바로 1995년 출시된 Netscape Navigator 2.0 이었다. 오늘날, 모든 브라우저들은 자바스크립트를 지원하고 심지어는 그들 만의 자바스크립트 인터프리터 까지 가지고 있다. (e.g. Firefox는 Spider Monkey, Google Chrome 은 V8) 렌더링 과정과 더불어, 브라우저는 내부적으로 렌더링된 도큐먼트의 트리 형태의 재현체인 Document Object Mdoel(DOM)을 생성하게 된다. 자바스크립트 코드는 이러한 DOM을 조작할 수 있기 때문에 HTML 코드를 도큐먼트에 추가하거나 제공되는 DOM의 메소드들을 통해서 도큐먼트를 수정할 수도 있다.

매번 자바스크립트가 DOM을 조작할 때마다, 브라우저는 대부분 또 다른 렌더링 사이클을 실행시켜야만 한다. 형편없게 짜여진 도큐먼트의 자바스크립트는 과도한양의 렌더링 사이클을 불러일으키고 사용자에게 "느린 웹사이트" 라는 인식을 심어줄 수 있다. "느린 " 이라는 말은 UI로써의 도큐먼트의 반응성을 이야기하는 것이지 네트워크가 느리다는 의미는 아니다.

브라우저들은 각각의 자바스크립트 에러 메시지들을 2000년대 초만해도 다음과 같이 보여주었다.


브라우저들은 또한 자바스크립트 에러들을 처리해야 한다. 2000년대 초반까지만 하더라도 브라우저들은 자바스크립트 에러들을 화면을 가로막는 다이얼로그를 통해서 보여주었다. 하지만 현재 HTML 도큐먼트들이 일으키는 자바스크립트 에러의 수를 고려했을 때 브라우저들은 대부분 이 에러들을 개발자 도구 내의 콘솔창에 로그하기로 하였다. 대부분의 에러 메시지들은 일반 사용자들에게 별 다른 가치가 없기 때문이다.

현대 브라우저들의 렌더링 과정의 복잡성

만약 당신이 오늘날 Windows XP에서 Internet Explorer 6를 사용한다고 생각해보면, 이것이 제대로 동작하지 못한다는 것을 깨닫게 될 것이다. 이러한 상황은 IE6와 Windows XP가 현대의 TLS의 암호화 기준을 충족하지 못하고 현대의 HTML 과 CSS를 렌더링 하지 못하거나 또는 현대적인 자바스크립트를 실행시킬 수 없기 때문이다.

React는 HTML 도큐먼트들을 통해 배포되는 어플리케이션들의 유명한 프레임워크이다.

예전의 브라우저들의 경우에도 꽤나 발전된 형태의 HTML 도큐먼트 뷰어로써 동작할 수 있었지만, 현대의 브라우저들은 보다 어플리케이션 런타임 환경으로 변해버렸다. HTML 도큐먼트들은 HTML 프론트엔드와 CSS 스타일, 이펙트, 애니메이션 그리고 수천줄에 달하는 복잡한 자바스크립트가 합쳐져서 완전한 형태의 어플리케이션으로 발전했다. 심지어는 jQuery 라이브러리(2000년대 초반에 유행한)의 대부분의 메소드들은 이미 자바스크립트 스탠다드의 일부분이 되었거나 브라우저의 자바스크립트 엔진에 포함되게 되었다. (e.g. "querySelectorAll" 메소드)

현대 브라우저: 하나의 런타임 환경

현대 자바스크립트 언어가 가지고 있는 모든 기능들에 더해 브라우저들은 또한 다수의 비디오 플레이백, 알림, 위치 설정, 진동, 센서, 배터리 컨트롤, 결제 등의 HTML5에 명시되어 있는 Web API들을 지원하고 있다. 또한 브라우저들은 그저 하나의 어플리케이션과는 거리가 있다. 많은 개발과정들과 런타임 환경들이 Google Chrome과 같은 브라우저 런타임 환경에 기반하고 있기 때문이다.(Visual Studio Code, MS Teams, Slack) 이들은 모두 본질적으로 Google Chrome 런타임 환경을 사용하는 Electron을 활용해서 작성되었다.

HTML, CSS, 자바스크립트는 너무나 유명해져서 당신이 상상할 수 있는 모든 것들과 종종 발견되지 말하야 할 곳들에서 발견할 수 있을 것이다. 그러나 근본은 현재까지도 동일하게 유지되어 왔다. 브라우저들은 그저 더 많은 기능들을 가지게 된 것이고 그렇기에 더 많은 복잡성이 추가되었을 뿐이다.

개발자로서 현대의 인터넷을 어떻게 다루어야 하는가

과거에도 벌써 인터넷과 웹에 관련된 모든 것들을 배운 다는 것이 쉬운 일은 아니었다. 오늘날의 한 사람의 개발자로서, 당신은 당신이 모든 것을 배울 수 없다는 것을 인정해야만 한다. 하지만, 개발자이자 CTO인 나의 입장으로서, 나는 당신에게 IP의 기본적인 부분들과 (많은 사람들이 v6를 버거워하기 때문에 v4로 시작하길 권한다.) ICMP, TCP, UDP, DNS 그리고 HTTP에 대해서 공부하길 권한다.

도메인이라는 것이 실제로 무엇인지, 어떻게 DNS가 작동하는지, HTTP 요청을 실행시키면 무엇이 일어나고 이 요청이 네트워크를 통해 어떻게 연결되는지를 이해하는 과정은 당신이 버거운 퍼즐이 되어버린 현재의 인터넷을 이해하는데에 굉장한 도움을 줄 것이다. 이러한 부분들은 그저 당신의 데브옵스 혹은 시스옵스 동료들이 당신의 웹 어플리케이션을 운영하기 위해서 필요한 부분들이 아니다. 네트워크에 대한 기본 바탕을 배우고 나면, 당신이 문제들과 에러들 그리고 실수들에 대해서 확연히 잘 이해할 수 있다는 걸 깨닫게 될 것이다.



지금쯤이면 내가 왜 브라우저가 실제로 무슨 작업을 하는지에 대해 묻는지 이해하게 되었을 것이다. 그들을 힘들게 하려는 것이 아니라 그들이 그들의 배움의 과정에서 현재 어느정도까지 위치해 있는지 이해하기 위해서이다. 스스로에 대해서는 어떻게 느끼는가? 혹시 내가 놓친 부분이 있는가? 개발자로서 네트워킹이라는 것에 관심이 생겼는가? 아니면 매일 매일 처리해야할 절망거리에 더 가까운가?


profile
반갑습니다! 오늘도 좋은 하루 입니다🙋🏻‍♂️. 프론트엔드 개발을 공부하고 있습니다!

3개의 댓글

comment-user-thumbnail
2023년 11월 9일

좋은 글 감사합니다

답글 달기
comment-user-thumbnail
2023년 11월 15일

면접 준비할 때 검색창에 구글을 입력하면 어떻게 되는가에 대해 준비한 적이 있는데 무작정 암기였던 그때에 비해 이 글을 읽으니 조금은 이해가 된 것도 같아요! 잘 보고갑니당

답글 달기
comment-user-thumbnail
2023년 11월 19일

헐! 저도 아크 쓰고있었는데 너무 편해서 브라우저라는 플랫폼에 관심 생겼어요!! 두고두고 읽어보겠습니다

답글 달기