주소창에 https://www.naver.com 혹은 https://www.youtube.com등 다양한 URL을 검색하여 해당 웹 페이지에 접속한
경험이 있을 것이다. 그렇다면 어떤 동작 원리로 우리가 입력한 웹 페이지로 접속이 가능한 것 일까?
이번 포스팅에서는 주소 창에 URL 혹은 도메인을 입력했을 때 어떤 과정을 거쳐서 웹 페이지가 보이는 가를 알아보자.
1.브라우저란?
웹 브라우저는 동기(Synchronous) 적으로 HTML+CSS+Javascript 언어를 해석하여 내용을 화면에 보여주는
응용 소프트웨어 이다.
동기 적인 이유는 ?
- script 태그를 body 태그 하단에 위치시키는 아이디어에서 찾을 수 있다.
- HTML 요소들이 script 로딩 지연으로 인해 렌더링에 지장 받는 일이 발생하지 않아 페이지 로딩 시간이 단축
- DOM이 완성되기 전에 script가 DOM을 조작한다면 에러가 발생한다.
- 자바스크립트는 렌더링 엔진이 아닌 자바스크립트 엔지이 처리한다.
웹 브라우저가 웹 서버에 필요한 자원(웹 페이지)를 요청하면 서버는 응답하고 웹 브라우저는 이를 해석한 후
사용자(Client)에게 보여준다.
보통 자원은 HTML 문서이지만, PDF, 이미지 등 다양한 형태일 수 있다.
웹 브라우저에 종류는 다양한데, 크롬, 네이버 웨일, 파이어폭스, 사파리 등이 대표적인 예로 말할 수 있다.
이번 포스팅에서는 크롬 브라우저를 기반으로 설명하겠다.
2.브라우저의 구조
브라우저의 기본 구조로는 다음과 같다.
1. 사용자 인터페이스
사용자가 접근할 수 있는 영역이다. URI를 입력할 수 있는 주소 표시줄, 이전/다음 버튼, 북마크 메뉴, 새로 고침 버튼과 현재 문서의 로드를 중단할 수 있는 정지 버튼, 홈 버튼 등 요청한 페이지를 보여주는 창을 제외한 나머지 모든 부분이다.
2. 브라우저 엔진
사용자 인터페이스와 렌더링 엔진 사이의 동작을 제어한다. Data Storage(데이터 저장소)를 참조하여 로컬에 데이터를 쓰고 읽으면서 다양한 작업을 한다.
3. 렌더링 엔진
웹 서버로부터 응답 받은 자원을 웹 브라우저 상에 나타낸다. 예를 들어 HTML 문서를 응답받으면 HTML과 CSS를 파싱
하여 화면에 표시한다. 브라우저의 동작 원리를 이해하려면 렌더링 엔진의 이해가 중요하다.
브라우저는 서버로부터 HTML 문서를 응답받으면 렌더링 엔진의 HTML 파서와 CSS 파서에 의한 파싱(parsing)이 되며 DOM,CSSOM 트리로 변환되고 렌더 트리로 결합된다. 이렇게 생성된 렌더 트리를 기반으로 브라우저는 /
웹 페이지를 나타낸다.
4. 통신
HTTP 요청과 같은, 서버와 통신이 가능하게 하는 네트워크 호출에 사용된다.
5. UI 벡엔드
select, input등 기본적인 위젯을 그리는 인터페이스 이다.
6. 자바스크립트 해석기
자바스크립트 코드를 해석하고 실행한다.
7. 자료 저장소
Cookie, Local Storage, Indexed DB 등으로 브라우저 메모리를 활용하여 지정하는 영역이다.
3. 렌더링 엔진
렌더링 엔진은 HTML, XML, 이미지 등 요청받은 내용을 브라우저 화면에 표시하는 엔진이다.
각 브라우저마다 렌더링 엔진이 다르기 때문에 같은 페이지가 다르게 보이는 경우가 있다.
예를 들어, 인터넷 도구 Elements 탭에서 아래와 같은 코드를 본적이 있을 것이다.
-moz-border-radius: 1em; // 파이어폭스 브라우저에 적용
-ms-border-radius: 2em; // 익스플로어에 적용, 보통 생략
-o-border-radius: 3em; // 오페라에 적용
-webkit-border-radius: 4em; // 구글, 사파리 브라우저에 적용
출처: https://bbangson.tistory.com/87 [뺑슨 개발 블로그]
렌더링 엔진의 종류는 아래와 같다.
- Blink - 크롬, 오페라
- Webkit - 사파리
- Trident - 익스플로어
- EdgeHTML - 마이크로소프트사 엣지
* Blink는 구글이 Webkit을 대체하기 위해 자체적으로 개발한 엔진이다.
렌더링 엔진은 조금 더 나은 사용자 경험을 위해 가능하면 빠르게 내용을 표시한다. 그래서 일련의 과정들이 동기적으로 진행되지는 않는다. HTML을 파싱 할 때까지 기다리지 않고 렌더 트리 배치와 그리기 과정을 시작한다.
렌더링 엔진 동작과정
렌더링 엔진은 서버로부터 응답받은 HTML 문서를 얻는 것으로 시작한다. 이 문서의 내용은 보통 8KB 단위로 전송된다.
아래 그림은 렌더링 엔진의 기본적인 동작 과정이다.
- 렌더링 엔진은 HTML 문서를 파싱하여 DOM 트리를 구축한다.
- 그 다음 외부 CSS 파일과 함께 포함된 스타일 요소를 파싱한다.
- DOM 트리와 외부 CSS 파일의 대한 결과물을 함처 렌더 트리를 구축한다.
- 렌더 트리 각 노드에 대해 화면 상에서 배치할 곳을 결정한다.
- UI 백엔드에서 렌더 트리의 각 노드를 그려준다.
아래 그림으로는 렌더링 엔징 중 하나인 웹킷(webkit)엔진에 나타낸 그림이다.
동작 과정의 순서는 위에서 설명한 기본 동작 과정과 유사하다.
1. HTML 문서를 파싱 하면서 DOM(Document Object Modal) 트리를 구축한다.
DOM은 마크업과 1:1 관계로 성립된다.
<html>
<body>
<p>Hello World</p>
<div><img src="example.png" /></div>
</body>
</html>
위와 같은 코드는 아래와 같은 DOM트리로 변환해줄 수 있다.
브라우저에서는 서버로부터 HTML문서를 모두 전달받으면서 HTML 파서를 통한 파싱(parsing)을 하고 파싱 트리를 생성한다. 생성된 파싱트리를 기반으로 DOM트리를 생성한다.
2. CSSOM(Css Object Modal)을 생성한다.
CSS 파일은 스타일 시트 객체로 파싱되고 각 객체에는 CSS 규칙을 포함한다. CSS 규칙 객체(CSSOM)은
선택자와 선언 객체 그리고 CSS 문법과 일치하는 다른 객체를 포함한다.
3. 렌더 트리(DOM + CSSOM)을 생성한다.
DOM 트리가 구축되는 동안 브라우저는 DOM 트리를 기반으로 렌더 트리를 생성한다. 렌더 트리는 문서를 시각적인 구성 요소로 만들어주는 역할을 한다.
웹킷은 이 구성 요소를 "렌더러(rendere)" 또는 "렌더 객체(render Object)"라는 용어를 사용한다. 렌더러는 자신과 자식 요소를 어떻게 배치하고 그려내는지 알고 있다.
렌더러는 DOM 요소에 부합되지만 1:1로 대응하는 관계는 아니다. 그 이유로는 <head>, display:'none'과 같은 사용자가 볼 수 없는 DOM 요소는 렌더 트리에 추가되지 않는다 (visiblity 속성에 "hidden" 값이 할당된 요소는 트리에 나타남)
4. 렌더 트리에 대한 배치 (레이아웃)
렌더 트리는 위치와 크기를 가지고 있지 않아, 어느 공간에 위치할지 각 객체들에게 위치(postion)과 크기(size)를
결정해준다.
5.렌더 트리 그리기
렌더 트리가 만들어져 레이아웃이 구성된다면 UI 벡엔드가 동작되 렌더 트리의 각 객체를 화면의 픽셀(px)값으로 나타낸다.
Javascript 에서는 어떻게 동작할까?
Javascript 또한 렌더링 엔진을 처리해야 할까? 정답은 아니다.
자바스크립트는 자바스크립트 엔진이 대신 처리한다. HTML Parser에서는 <script>태그를 만나면 Javscript 코드를 실행하기 위해서 DOM요소를 생성해 프로세스를 중지하고 자바스크립트 엔진으로 권한을 넘긴다.
제어 권한을 넘겨받은 자비스크립트 엔진은 <script> 태그 내에 Javascript 코드 또는 src속성에 정의된
Javscript파일을 로드하고 파싱하여 실행한다. Javascript의 실행이 완료되면 다시 HTML파서로 제어 권한을 넘겨주며
중지했던 시점으로 돌아가 DOM 생성을 재개한다.
이런식으로 브라우저는 동기적으로 HTML,CSS,Javascript를 처리한다. 하지만 자바스크립트 엔진에 제어 권한이 있다고 가정하에 Javascript코드가 완성되지 않는 DOM을 조작한다면 어떻게 될까? 당연히 에러를 발생시킬 것이다.
이것이 HTML 파일에서 Javascript 코드를 <body> 태그 하단에 위치시켜주는 이유중 하나이다.
참고 자료
'웹개념' 카테고리의 다른 글
[CI/CD] CI/CD란? - 지속적 통합 / 지속적 제공 기본개념 (0) | 2022.01.30 |
---|---|
[HTTP] HTTP 상태코드 (0) | 2022.01.16 |
CORS란 무엇인가? (0) | 2021.10.12 |