면접에서 나오는 단골 질문이며,
웹 프론트엔드 개발자로써 주소창에 특정 웹 페이지의 주소를 입력했을 때,
어떤 과정을 통해 데이터가 전달되고, 화면에 렌더링되는지를
확실하게 알고 있어야 한다고 생각했다.
이참에 해당 과정 한번 제대로 정리해보기로 마음먹었다.
웹 브라우저에 해당 도메인 주소를 입력했을 때의 과정을 크게 13단계로 나눴으며,
1~5 단계는 데이터를 받아오는 과정,
6~12단계는 웹 브라우저에 렌더링되는 과정에 대한 설명으로 구분했습니다.
웹 브라우저는 DNS 서버에 검색하기 전에
캐싱된 DNS 기록들을 먼저 확인합니다.
만약 해당 도메인 이름에 맞는 IP 주소가 존재하면,
DNS 서버에 해당 도메인 이름에 해당하는 IP주소를 요청하지 않고
캐싱된 IP주소를 바로 반환합니다.
일치하는 IP주소가 존재하지 않는다면,
다음 과정인 DNS 서버 요청으로 넘어갑니다.
ISP(ex. SK 브로드밴드, KT...)를 통해
DNS서버가 호스팅하고 있는 서버의 IP주소를 찾기 위해
DNS query를 전달합니다.
DNS query는
현재 DNS서버에 원하는 IP주소가 존재하지 않으면
다른 DNS 서버를 방문하는 과정을
원하는 IP주소를 찾을 때까지 반복합니다.
해당 도메인 이름에 맞는 IP주소로 변환하는 과정은
점(.)을 기준으로
계층적으로 구분하여 구성이 됩니다.
해당 계층의 탐색 순서는
뒤에서부터 해당 도메인 이름에 맞는 지역 DNS를 탐색하며,
root DNS 서버가 나올때까지
거꾸로 탐색합니다.
Ex) . -> com -> google.com
이와 같이 Local DNS 서버가
여러 DNS 서버를 차례대로 물어봐서 답을 찾는 과정을
Recursive Query라고 부릅니다.
해당 HTTP 요청 메세지는
TCP/IP 프로토콜을 사용하여 서버로 전송됩니다.
TCP는 전송 제어 프로토콜로
데이터의 전송을 제어하고
데이터를 어떻게 보낼 지, 어떻게 맞출 지 정합니다.
IP의 특징인 비신뢰성과 비연결성으로 인해
IP 프로토콜 만으로는 통신을 할 수 없습니다.
그렇기에, 신뢰성과 연결성을 책임지는
TCP를 활용하여 통신을 합니다.
TCP는 3 way handshake 과정을 통해
연결 및 데이터를 수신받고,
4 way handshake 과정을 통해
연결을 종료합니다.
3 way handshake의 과정
- 만약, Client에서 세션을 종료시킨 뒤 도착하는 패킷이 있다면
해당 패킷은 Drop되고 데이터는 유실되게 됩니다.- 이러한 현상을 위해
Client는 Server로부터 FIN을 수신하더라도
일정시간동안 세션을 남겨놓고 잉여 패킷을 기다리는
TIME_WAIT과정을 마지막으로 거치게 됩니다.
웹 서버 혼자서 모든 로직 처리 및 데이터 관리를 하게되면
서버에 과부하가 일어날 가능성이 높습니다.
그렇기에 서버의 일을 돕는 조력자 역할을 하는 것이 WAS입니다.
WAS는 사용자의 컴퓨터나 장치에 웹 어플리케이션을 수행해주는 미들웨어 입니다.
특정 데이터 요청을 브라우저로부터 받게되면,
웹 서버는 페이지의 로직이나 데이터베이스의 연동을 위해
WAS에게 이들의 처리를 요청합니다.
WAS는 해당 요청을 통해 동적인 페이지 처리를 담당하고,
DB에서 필요한 데이터 정보를 받아 그에 맞는 파일을 생성합니다.
- 웹 서버 : 정적인 파일(HTML, CSS, 이미지 파일)을 처리
- WAS : 동적인 파일(JS, TS)을 처리
전달 과정에서 status code를 통해
서버 요청에 따른 결과 및 상태를 전달합니다.
- 1xx : 정보가 담긴 메세지
- 2xx : response 성공
- 3xx : 클라이언트를 다른 URL로 리다이렉트
- 4xx : 클라이언트 측에서 에러 발생
- 5xx : 서버 측에서 에러 발생
웹 브라우저에 출력되는 단계를
Critical Rendering Path라고 하며
크게 6단계로 분류됩니다.
성능을 최적화하려면
수신받은 HTML, CSS, JS파일들을
어떤 단계를 걸쳐 일어나는지를 파악한 후,
해당 과정들을 최소화하는 것이 매우 중요합니다.
이전 단계에서 통신을 통해 받아온 HTML 파일들은
바이트 형태로 전달되게 됩니다.
바이트 -> 문자 -> 토큰 -> 노드 -> 객체 모델로 전환하는 작업이 수행됩니다.
"<" 문자를 만나면 상태를 태그 열림으로 변하며,
이후 만나는 a~z의 문자들을 ">" 문자를 만날때까지
태크 이름의 상태로 인식하게 됩니다.
">" 문자를 만난 후,
현재 토큰을 발행되고 상태는 다시 자료로 돌아갑니다.
이후 문자들을 소비하면서 문자 토큰이 생성되고
해당 과정은 "<" 문자를 만날 때까지 진행됩니다.
"<" 문자에 만나면 다시 태크 열림 상태로 변합니다.
"/" 문자는 종료 태그 토큰을 생성하며 태그이름 상태로 변경됩니다.
해당 상태는 ">" 문자를 만날때까지 유지됩니다.
해당 과정을 모든 파일의 자료를 확인할 때까지 반복합니다.
해당 프로세스의 최종 출력은 DOM이며,
해당 형태가 트리 형태를 띄고 있기 때문에
DOM Tree라고도 부릅니다.
HTML에서 사용했던 객체 모델로 전환하는 작업이
CSS 파일에 똑같이 적용됩니다.
CSSOM 트리 형태를 만듬으로써
특정 객체에 최종 스타일을 계산할 때
상위 객체의 스타일을 하향식 규칙을 적용하는 방식으로
계산되는 스타일을 재귀적으로 세분화하게 됩니다.
기존에 제작된
DOM과 CSSOM을 결합하여
Render Tree를 생성합니다.
Render Tree는
렌더링에 필요한 노드만 선택하여
페이지를 렌더링하는데 사용합니다.
Render Tree의 노드들에 대한
위치와 크기를 계산하는 단계입니다.
페이지 상에 존재하는 객체의 크기를
렌더링 트리의 루트부터 시작하여
모든 객체의 정확한 위치와 크기를 계산합니다.
계산된 값들을 기반으로
화면에 필요한 요소들을
실제로 그리는 작업을 실행합니다.
레이아웃 단계에서 계산된
모든 위치, 크기를
실제 픽셀로 변환하여 화면에 출력합니다.
특정 액션과 이벤트에 따라
html의 요소의 크기나 위치의 크기를 변경해야 하는 경우가 발생하며
해당 과정을 reflow라고 합니다.
해당 과정이 발생하면
렌더링 트리와 각 요소들의 크기와 위치를
다시 계산해야 합니다.
reflow에 따라
다시 페인팅을 해줘야하는 repaint 단계 역시 수행됩니다.
하지만, reflow가 발생해야 repaint가 발생하는 것이 아닌
레이아웃에는 영향을 주지 않지만,
다시 페인팅을 해야하는
background-color, visibility와 같은 스타일을 변경할 때는
독단적으로 수행됩니다.
Reflow와 Repaint를 최대한 줄여야
해당 과정들을 다시 거치지 않기에
가능한 과정을 최소한으로 고려해야
성능 최적화와 연결됩니다.
레아아웃과 페인트를 수행하지 않고
레이어의 합성만 실행시키는 단계입니다.
Transform, opacity와 같은 요소들을 의미합니다.
해당 주제에 대한 학습을 하며,
컴퓨터 네트워크 관련 CS지식이
매우 부족하다는 점을 깨달았다.
나도 모르는 사이에
네트워크 관련 학습을
"일단 다른것부터 하고 공부해야지"
라고 계속 미뤄두었던 것 같다.
컴퓨터가 소통하는 방식도
제대로 모르고 코딩을 하는
내 자신이 매우 부끄러워 졌다.
지금부터라도
네트워크에 대한 학습을
우선순위로 두고 공부하는 것이,
좋은 개발자로 성장하기 위한
필수 과정이라고 생각한다.
보통 DNS서버를 탐색부터 HTML 문서 수신받는 부분까지만 알려주거나 알고있는경우가 많은데 이렇게 받은 HTML/CSS/JS 문서들이 어떻게 렌더링 되는 부분까지 알려주신점이 인상깊네요. 😮
좋은글 잘보고갑니다! ㅎㅎ
깔끔한 정리 너무 보기좋네요 ㅎㅎ
좋은 글 감사히 잘보고갑니다~!