오늘은 브라우저의 동작 원리에 대해서 살펴볼 예정입니다. 프론트엔드 개발자 면접에서도 많이 나오는 질문이기도 하고요. 우선 브라우저가 먼지 먼저 살펴볼까요 ?
브라우저란 ?
인터넷을 통해 웹 페이지를 탐색하고 보는 데 사용되는 소프트웨어입니다.
브라우저의 내부 구성
다들 많이 보신 기억이 있는 사진일 거 같은데요.
브라우저는
- 유저 인터페이스 : 유저의 상호작용을 받는 부분으로 브라우저에 위쪽에 보면 뒤로, 앞으로 가기 버튼, 새로고침, 주소 입력창, 북마크 등이 있는 영역입니다.
- 브라우저 엔진 : 사용자 인터페이스와 렌더링 엔진 사이의 동작을 제어하는 엔진입니다.
- 렌더링 엔진 : 요청받은 내용을 화면에 표시합니다.
- 네트워킹 : 네트워크 호출을 하고 통신, 보안의 역할도 수행합니다.
- 자바스크립트 해석기 : 자바스크립트 코드를 해석하고 실행합니다.
- UI 백엔드 : 기본 위젯을 그리는데 사용하는 인터페이스를 말하며, 예를 들어 콤보 박스나 대화 상자 같은 요소들이 있습니다. 사용자의 이벤트를 감지하고 처리하는 부분은 이벤트 처리 시스템입니다.
- 데이터 저장소 : 데이터를 저장하기 위한 구성 요소. 쿠키, 스토리지, indexedDB, web SQL 등을 사용할 수 있습니다.
이렇게 구성되어 있습니다.
브라우저 주소창에 URL을 입력하면 발생하는 일
이제 프론트엔드 면접에서 자주 나오는 질문인 브라우저 주소창에 URL을 입력하면 발생하는 일에 대해서 알아보겠습니다.
1. DNS 서버 조회
입력한 URL에 해당되는 IP 주소를 가져옵니다. 가져온 IP 주소는 일정 시간 동안 캐시됩니다. 호스트 별로 한 번씩 수행되어서 폰트, 이미지, 스크립트, 광고 등 다양한 호스트가 있다면 여러 요청을 수행합니다.
2. TCP 3way Handshake
DNS서버를 통해 IP 주소를 알고 난 후에 TCP 3way Handshake
를 합니다.
TCP 3way handshake는 TCP/IP 프로토콜을 사용한 통신을 하기 전에 먼저 연결하는 방법을 말합니다.
- SYN
- SYN-ACK
- ACK
이 순서로 진행됩니다.
3. TLS Handshake
이 TLS Handshake
는 TCP 3way Handshake이후에 실행됩니다. 이 사진처럼 수행이 됩니다.
통신 암호화에 쓰일 암호를 결정, 서버를 확인하여 안전한 연결이 이루어지도록 합니다.
- clientHello
- serverHello & Certificate
- ClientKey
- Finished (server to cleint)
- Finished (cleint to server)
4. 응답
연결이 완료된 뒤에 HTTP Request를 보내 응답을 내려받습니다. 보통 웹사이트는 HTML을 내려주는데요. 모든 HTML을 한번에 내려주는 것이 아닙니다. TCP Slow Start(14kb rule)
이라는 것에 의해서 점진적으로 내려받습니다.
TCP Slow Start(14kb rule)
을 간단하게 알아보면 첫 응답 패킷은 14kb입니다. 그리고 그다음 패킷은 두 배의 크기인 28kb로 늘리고 미리 지정한 임계치에 도달하거나, 혼잡의 징후가 나타나기 전까지 2배씩 증가합니다.
5. DOM
드디어 서버로부터 HTML을 받았는데요. 이제 이 HTML을 바로 화면에 그래픽으로 파싱하면 될까요 ? 아닙니다. 웹에서는 Javascript라는 언어를 사용하여 HTML에 있는 여러 요소들을 동적으로 다룰 수 있어야 하는데 그러려면 DOM (Document Object Model) 이라는 것을 만들어야 합니다.
Token
토큰화라는 과정을 거칩니다. html을 하나씩 읽으면서 의미 있는 최소 단위
로 나누는 과정을 의미합니다.
의미 있는 최소 단위는 태그, 속성, 텍스트 등 HTML를 구성하는 기본적인 요소를 말합니다. 토큰화를 거친 뒤에 DOM Tree를 만듭니다.
이 DOM을 만드는 과정에서 async, defer으로 설정되지 않은 script 태그
를 만나면 javascript로 인해 새로운 DOM 요소가 추가, 수정, 삭제될 수 있기 때문에 DOM 만드는 과정을 중지합니다.
6. CSSOM
CSSOM(CSS Object Model)
은 Javascript로 css를 조작할 수 있는 API의 집합을 의미합니다. CSSOM을 만들 때도 똑같이 토큰화 과정을 거칩니다.
7. Render Tree
만들어진 DOM, CSSOM을 사용해 Render Tree로 합성합니다. Render Tree에는 화면에 필요한 모든 정보가 들어있습니다. 참고로 display : none
은 화면에 보이지 않음으로 렌더 트리에 포함되지 않습니다.
8. Layout
Reflow
라고도 불리는 단계입니다. 각각 요소들의 height, width, position 등을 계산하고 배치를 합니다. 스타일이 다시 계산되는 경우에는 다시 Reflow 단계를 수행합니다.
9. Paint
Repaint
라고도 불리는 단계입니다. 각각 요소들의 background color, color, border-color, box shadow 등을 사용하여 화면에 색을 더합니다. 그리고 브라우저가 특정 HTML 요소들을 독립적으로 관리하고 그리는 단위인 Layer
을 만들어서 그립니다. 복잡한 애니메이션 등 성능을 최적화하기 위해 여러 레이어를 만듭니다.
10. Composite
나눠져 있는 레이어들을 합성하여 화면에 그립니다.
번외) script 태그에 관하여
브라우저 동작과 관련해서 script 태그에 대해서 좀 더 설명하고 넘어가겠습니다.
script를 Body 밑에 넣는 이유
위에서 한번 언급한 적이 있는데 브라우저가 html을 DOM으로 파싱할때 script
태그를 만나면 DOM 파싱을 중단
합니다. 왜냐하면 javascript로 DOM 조작이 가능하고 DOM에 새로운 요소를 추가하거나 수정하거나 삭제를 하면 다시 DOM을 파싱 해야할 수 있기 때문이죠.
그리고 script가 위에 있으면 DOM 요소가 생기기 전이라서 문제가 발생할 수 있는데요.
<body>
<script>
const div = document.querySelector("div");
console.log(div); // null
</script>
<div>111</div>
</body>
예를 들면 이런 식으로 말이죠.
script의 defer, async ?
이번에는 script의 defer, async에 대해서 알아보겠습니다.
defer
<script defer src="./test.js"></script>
defer
은 해당 스크립트를 백그라운드에서 병렬적으로 다운로드합니다. 그리고 DOM이 준비가 되면 그때 실행됩니다.
defer
은 외부 스크립트일 때만 유효하게 동작합니다. (script 태그에 src로 외부 스크립트를 받아오는 게 아니면 동작하지 않습니다.) 그리고 나중에 실행 순서를 봐야 하는데요. 용량이 작은 스크립트를 백그라운드에서 먼저 다운로드를 해도 스크립트의 순서대로 실행됩니다.
async
<script async src="./test.js"></script>
async
은 페이지와 완전히 독립적으로 동작합니다. defer와 마찬가지로 백그라운드에서 다운로드 되며, 다운로드가 완료되면 바로 실행됩니다. (실행될 때는 DOM 파싱을 멈춥니다.) defer와 다르게 스크립트의 순서가 보장되지 않습니다.
참고자료
'frontend' 카테고리의 다른 글
프론트엔드 SEO 구글 검색 엔진과 최적화 (0) | 2024.06.20 |
---|---|
(React 19 + Next js 15 + Panda Css) 2. SVGR 적용 (1) | 2024.06.15 |
(React 19 + Next js 15 + Panda Css) 1. 프로젝트 세팅 (1) | 2024.06.11 |
웹 어셈블리 찍먹 ! (0) | 2024.05.23 |
싱글스레드 언어인 JS에서는 Promise가 어떻게 동작할까 ? (0) | 2024.05.15 |