브라우저 렌더링은 브라우저(Chrome, Edge, Safari 등)가 HTML, CSS, JS로 작성된 문서를 파싱하여 브라우저에 시각적으로 출력하는 것을 말합니다. 파싱(Parsing)이란, 프로그래밍 문법에 맞게 작성된 텍스트를 읽어 들여 실행하기 위해 텍스트 문서의 문자열을 토큰으로 분해하고, 토큰에 문법적 의미와 구조를 반영하여 파스 트리를 생성하는 과정을 말합니다.
브라우저는 아래의 과정을 거쳐 렌더링을 수행합니다.
렌더링 과정을 단계별로 자세히 알아보겠습니다.
예를 들어 브라우저의 주소창에 https://velog.io/을 입력하고 엔터 키를 입력하면 velog.io 서버로 루트 요청이 전송됩니다. 루트 요청이란 /, 스킴(scheme)과 호스트만으로 구성된 URI에 의한 요청을 말합니다. 일반적으로 서버는 루트 요청에 대해 암묵적으로 index.html을 응답하도록 기본 설정되어 있습니다.
따라서 서버는 루트 요청에 대해 서버의 루트 폴더의 index.html을 클라이언트(브라우저)로 응답합니다. 이때 index.html뿐 아니라 CSS, JS, 이미지, 폰트 파일들도 응답됩니다. 이는 렌더링 엔진이 HTML을 파싱하는 도중에 외부 리소스를 로드하는 태그를 만나면 HTML 파싱을 일시 중단하고 해당 리소스 파일을 서버로 요청하기 때문입니다.
브라우저의 렌더링 엔진은 응답받은 HTML 문서를 파싱하여 브라우저가 이해할 수 있는 자료구조인 DOM을 생성합니다.
렌더링 엔진은 HTML을 한 줄씩 파싱합니다. 그러다가 CSS를 로드하는 link/style 태그를 만나면 DOM 생성을 일시 중지하고 CSS 파일을 서버에 요청합니다. 그리고 HTML과 동일하게 CSS를 파싱하여 CSSOM을 생성하는 과정을 거칩니다. CSS 파싱을 완료하면 HTML 파싱이 중단된 지점부터 다시 HTML을 파싱하기 시작하여 DOM 생성을 재개합니다.
렌더링 엔진은 DOM과 CSSOM를 생성하고, 렌더링을 위해 렌더 트리로 결합합니다.
완성된 렌더 트리는 각 HTML 요소의 레이아웃(위치와 크기)을 계산하는 데 사용되며 브라우저 화면에 픽셀을 렌더링하는 페인팅 처리에 입력됩니다. 여기까지의 과정으로 사용자는 화면에 렌더링된 결과물을 확인할 수 있습니다.
그러나 지금까지 설명한 렌더링 과정은 반복되어 실행될 수 있습니다. 다음과 같은 경우 반복해서 레이아웃 계산과 페인팅이 재차 실행됩니다.
위 경우들이 브라우저의 리렌더링을 발생하게 하는 요인들인데요, 리렌더링은 비용이 많이 드는, 성능에 악영향을 끼칩니다. 이 과정을 리플로우, 리페인트라고도 합니다.
리플로우는 레이아웃 계산을 다시 하는 현상입니다. 노드 추가/삭제, 요소의 크기/위치 변경, 윈도우 리사이징 등 레이아웃에 영향을 주는 변경이 발생하면 실행됩니다. 리페인트는 재결합된 렌더 트리를 기반으로 다시 페인트하는 것을 의미합니다.
리플로우와 리페인트에 관한 자세한 내용은 다음 글에서 기술하겠습니다.
지난 주 레벨1을 진행하는 동안 학습한 것에 대한 인터뷰(이하 레벨 인터뷰)를 진행했습니다. 얕디 얕은 학습 상태를 메타인지할 수 있는 귀중한 시간이었어요.😭 인터뷰 중 리플로우에 대한 꼬리 질문으로 브라우저 렌더링의 과정에 대한 질문이 있었습니다. 리플로우를 설명한다면 당연하게도 선행학습이 되어있어야 할 브라우저 렌더링에 대해서 제대로 설명할 수가 없더라구요...😇
이러한 작금의 사태를 타개하기 위해 앞으로도 부족한 학습 상태의 보충분을 기록하고자 합니다. 이 글에 넘버링이 된 이유이기도 하구요. 어렵겠지만 제발 꾸준히 작성하길 다짐해봅니다..