주소창에 naver.com 치고 enter 입력하면!
1) 입력한 텍스트 정보 확인
2) 네트워크 호출
3) 렌더링 작업
4) naver
주소창과 검색창을 동일하게 사용한다.
먼저, 입력된 텍스트가 검색어 인지 URL 주소인지 확인한다.
=> 브라우저는 네트워크 호출을 수행하게 된다.
클라이언트에게 '네이버' 화면을 보여주려면,
HTML, CSS, 이미지 등의 데이터를 미리 가지고 있어야 한다.
현재 브라우저에는 이러한 정보가 없으므로
네이버 서버가 있는 컴퓨터에서 정보를 가져와야 한다.
따라서 네트워크 통신을 통해 정보를 브라우저로 가져와야 한다.
이를 수행하기 위해
서버 컴퓨터의 IP 주소를 파악할 필요가 있는것..
클라이언트는 자신의 host 파일에서 도메인 네임 (naver.com) 에 대응하는 IP 주소가 있는지 우선적으로 확인한다.
없다면, 네임 서버 (name server) 에 네이버의 IP 주소를 알려주세요 라는 요청을 보내게 된다.
즉, 네임 서버는 도메인 주소에 맞는 IP주소를 찾아주는 역할을 수행하는 것!
클라이언트는 네임 서버와 통신으로 IP 주소를 요청, 응답받을 수 있다.
웹 브라우저에서 URL을 입력하면, 웹 브라우저는 네임 서버에 IP 주소를 요청하고 DNS는 이에 맞는 IP 주소를 응답한다.
네임 서버와의 통신으로 네이버 서버의 IP주소를 알아냈으니
이제 네이버 서버와의 통신이 가능해졌다.
클라이언트는 네이버 서버에 데이터를 요청한다. (HTTP Request)
네이버 서버는 클라이언트의 요청에 맞는 데이터를 찾고 바이트 형태로 변환 후
클라이언트에게 HTTP Response 를 보낸다.
브라우저 엔진은 네이버 서버로부터 받은 데이터에 악성 바이러스가 있는지 먼저 검사한다.
바이트 형태의 데이터는 브라우저에서 읽을 수 없으므로 브라우저 엔진은 렌더링 엔진에게 데이터를 해석하고, 페이지를 화면에 표시하도록 요청한다.
요청받은 렌더링 엔진은 받은 데이터를 바탕으로 렌더링 프로세스를 수행하고, 이 작업이 끝나면 브라우저 엔진에게 작업 완료를 알린다.
이제 화면에 naver.com 가 보여지게 된다!
다음으로는 렌더링 엔진이 수행하는 렌더링 프로세스에 대해 자세히 알아보자.
렌더링 프로세스
1) HTML, CSS 파싱
2) 렌더 트리 구축
3) 렌더 트리 배치 (Layout)
4) 렌더 트리 그리기 (Paint)
사파리는 웹킷 (Webkit) 렌더링 엔진을 사용하고,
파이어폭스는 모질라에서 만든 게코 (Gecko) 엔진을,
크롬은 웹킷을 사용하다가 블링크 (Blink) 엔진을 사용하고 있다.
파싱(Parsing)이란?
브라우저가 코드를 이해하고 사용할 수 있는 구조로 변환해주는 과정.
파싱은 '어휘 분석' 과 '구문 분석' 두가지 과정으로 구분할 수 있다.
parsing 트리는 토큰화된 문자열의 단순한 트리에 불과함
브라우저에서는 DOM 트리로 바꾸어 사용한다.
렌더링 엔진이 HTML 문서를 받으면 HTML 파서는 위에서부터 읽어가면서 파싱을 진행하고 DOM 트리를 생성한다.
렌더링 엔진은 파싱 과정을 기다리지 않고 이후 과정을 미리 진행한다.
HTML 파싱 중 CSS 문서를 가져오는 link tag를 만나면 DOM 생성과정이 잠시 중단되고 CSS 파싱과정이 시작된다.
과정은 HTML과 동일하다.
HTML 파싱 중 script tag를 만나면 잠시 중지하고 서버에서 JS 리소스를 브라우저 엔진으로부터 받아온다. 그리고 JS 엔진에게 제어권을 넘긴다.
JS 엔진은 받아온 JS 리소스를 파싱하여 AST (추상 구문 트리)를 생성하고 이를 바이트 코드로 변환해 실행한다.
만일 script tag를 body tag 중간에 작성할 경우, HTML 파싱이 끝나지 않은 상태에서 JS로 인해 DOM이 조작되어 에러가 발생할 위험이 생긴다.
따라서, script tag를 반드시 body tag 최하단에 위치해야 한다.
HTML, CSS 파싱과정이 모두 끝나면, 결과물인 DOM 트리와 CSSOM 트리를 서로 결합하여 렌더 트리(Render Tree) 를 생성한다.
DOM 트리란?
문서 객체 모델 (Document Object Model) 의 줄임말로
객체로 표현된 HTML 문서이다.
브라우저는 HTML 문서를 바로 읽을 수 없으므로 객체의 형태로 바꾸어 브라우저가 읽을 수 있는 트리 구조로 변환해주어야 하는 것.
DOM 트리 내 하나의 객체는 노드라고 부른다. (4가지 노드)
외부에서 특정 노드에 접근하기 위해 DOM 확인해야 할 때
먼저, '문서 노드' 부터 아래 방향으로 순차적으로 탐색된다.
렌더 트리 생성이 끝나면, 각 노드의 크기와 위치를 계산하여 화면에 배치하는 과정이 진행된다.
노드의 위치는 (x,y) 좌표를 이용하고 렌더 트리의 루트부터 아래로 내려가면서 계산된다.
레이아웃은 전체의 배치과정이 필요한 경우 글로벌 레이아웃, 일부의 배치과정이 필요한 경우 로컬 레이아웃으로 구분된다.
글로벌 레이아웃 : 맨 처음에 레이아웃이 발생할 때, 전역 스타일이 변경되거나 창이 리사이즈 될때 발생.
리플로우 Reflow : 초기 배치 이후 레이아웃이 다시 일어날 때
로컬 레이아웃 : 특정 부분만 재배치가 필요할 때 발생. 로컬 레이아웃이 일어나는 경우는 모두 리플로우가 발생할 때이다.
렌더 트리의 각 노드를 화면의 실제 픽셀로 변환해주는 작업이다. 이 작업을 래스터화 (Rasterizing) 라고 한다.
브라우저에 특정 변경이 생겨서 페인트 과정이 다시 일어나는 것을 리페인트 (Repaint) 라고 한다.
리플로우가 발생하면 리페인트도 함께 발생한다.
렌더 트리와 각 요소들의 크기와 위치를 다시 계산해주는 과정. => Layout이 변경되었을 때
화면의 구조가 변경되었을 때는 Reflow를 거쳐서 Repaint를 그린다.
But, 화면 구조가 변경되지 않는 화면 변화인
예를 들어, opacity, background-color, visibility, outline 등의 스타일 변화의 경우 Repaint만 동작한다.
브라우저는 변경 사항이 생기면 최소한의 작업만으로 동작하려 한다!!
렌더링을 빠르고 효율적이게 하려면, Reflow 과정을 최소화할 수 있도록 작업해야 한다.