Chapter1. 브라우저
Chapter2. 브라우저 렌더링
웹 서버에서 양방향으로 통신을 하며 HTML 문서 및 그림, 멀티미디어(ex. 동영상) 등의 컨텐츠를 열람할 수 있게 해주는 GUI 기반의 소프트웨어 프로그램.
페이지를 다운로드 하기 위해 응용 계층의 대표적인 프로토콜 HTTP를 통해 송수신 한다.
1) 사용자가 웹 브라우저를 통해 웹 페이지 URL 주소 입력
2) DNS 서버에서 사용자가 입력한 URL주소 중 도메인 네임을 검색, 해당 도메인 네임에 해당하는 IP 주소를 찾고, 사용자가 입력한 URL 정보와 함께 전달
3) 웹 페이지 URL 정보와 전달받은 IP 주소는 HTTP 프로토콜로 요청 메세지를 생성해 TCP 프로토콜을 사용해 인터넷을 거쳐 해당 IP 컴퓨터로 전송되고, 이 요청 메세지는 다시 HTTP 프로토콜을 통해 웹 페이지 URL 정보로 변환
4) 웹 서버는 이 변환이 된 정보에 해당하는 데이터를 검색하여 찾아낸 뒤 HTTP 프로토콜로 응답 메세지를 생성하고, 이 메세지는 다시 TCP 프로토콜을 이용해 인터넷을 거쳐 사용자의 컴퓨터로 전송됨
5) 사용자의 컴퓨터에 도착한 HTTP 응답 메세지는 HTTP 프로토콜을 사용해 웹 페이지 데이터로 변환, 변환된 데이터는 웹 브라우저 상에 출력되어 사용자가 볼 수 있게 된다.
주소 표시줄, 이전/다음 버튼, 북마크 메뉴 등에 관련된 GUI 부분을 통칭하고 있다. 구글 홈 화면 외의 나머지 모든 부분.
사용자 인터페이스와 렌더링 엔진 사이의 동작을 제어
역할 : HTML 문서와 기타 자원의 웹페이지를 사용자의 장치에 시각표현으로 변환, 문서 객체 모델(DOM) 자료 구조를 구현한다.
브라우저 엔진은 웹 브라우저 마다 전용 엔진을 사용하고 있다.
이름 | 설명 |
---|---|
게코(Gecko) | 모질라 재단에서 만든 브라우저 엔진. 파이어폭스가 해당 엔진을 탑재 |
웹킷(Webkit) | KHTML에서 파생된 브라우저 엔진. 사파리가 해당 엔진을 탑재 |
블링크(Blink) | 웹킷(Webkit)에서 파생된 브라우저 엔진. 크롬, 오페라가 해당 엔진을 탑재 |
트라이던트(Trident) | 마이크로소프트의 브라우저 엔진으로 인터넷 익스플로러, 아웃룩 익스프레스, 마이크로소프트 아웃룩 등이 이를 탑재 |
EdgeHTML | 트라이던트(Trident)에서 파생된 브라우저 엔진으로 마이크로소프트 엣지 스파르탄 버전(~2019)까지 탑재(현재는 블링크로 교체됨) |
역할 : 요청한 콘텐츠를 화면에 출력
HTML, CSS 등을 파싱해 최종적으로 화면에 그려주며, HTML 및 XML 문서와 이미지를 표시할 수 있다.
브라우저 엔진과 밀접하게 결합되어 있어서 보통 하나의 엔진으로 본다. 엔진의 동작 원리가 공통된 게 많음.
HTTP 요청과 같은 네트워크 호출에 사용됨.
보통 플랫폼의 독립적인 인터페이스이고 각 플랫폼의 하부에서 실행된다.
자바스크립트 엔진(JavaScript Engine)이라고도 부른다.
대체적으로 웹 브라우저에서 사용되며 브라우저마다 전용 엔진이 탑재되어 있다.
Rhino | 모질라 재단이 운영하는 오픈소스 엔진으로, 자바(Java)로 개발됨 |
---|---|
SpiderMonkey | 최초의 Javascript 엔진으로 넷스케이프 내비게이터를 지원하였으며, 현재는 파이어폭스를 지원 |
V8 | 구글이 개발한 오픈 소스 엔진으로 구글 크롬의 Javascript 엔진 |
JavascriptCore | 애플에서 개발, 사파리와 React Native App를 지원 |
Chakra | 마이크로소프트가 개발한 엔진이며, Edge 브라우저를 지원 |
자바스크립트 혹은 V8엔진은 크게 Heap Memory와 Call Stack으로 구성된다.
스택이 제거되는(pop) 과정. return 되는 순서대로 후입선출 구조로 빠진다.
함수 multiply와 함수 square에서 차례대로 return문의 결과를 얻는다. 따라서 스택 내부에서 차례대로 제거를 한다.
함수 printSquare로 돌아오면 함수 내부에 해당 메소드를 실행시킨다
console.log(squared);
해당 메소드를 실행하는 순간 스택 안에 console.log 스택이 쌓이고 실행이 끝나면 스택에서 제거되고, 함수 printSquare 또한 실행이 완료되었으므로 스택에서 제거된다. 이렇게 다시 스택이 완전히 비어있게 됨
스택 프레임(Stack Frame) : 호출 스택의 단계. ex) 스택 내에 쌓이는 printSquare(4)
하나가 프레임 하나를 의미한다.
스택 오버플로(Stack Overflow) : 스택 오버플로는 콜 스택 내부의 동일한 스택 프레임이 예상치 못한 수로 쌓일 때 일어난다. 프레임이 제한된 스택을 넘어버리게 되면 웹 브라우저는 멈춰버리게 된다.
렌더링 엔진이 분석한 Render Tree를 브라우저에 그리는 역할
Select, Input 창과 같은 기본적인 위젯을 그려주며, 플랫폼에서 명시하지 않은 일반적인 인터페이스로, OS 사용자 인터페이스 체계를 사용한다.
자료를 저장하는 계층.
모든 자원을 하드 디스크에 저장할 필요가 있다.
- 영구적인 저장소인 로컬스토리지(localStorage)
- 임시적인 저장소인 세션스토리지(sesseionStorage)를 따로 두어 데이터의 지속성을 구분할 수 있어 응용 환경에 맞게 선택할 수 있다.
탄생 배경 : HTML5 이전에는 응용 프로그램이 데이터에 서버를 요청할 때마다 쿠키에 정보를 저장했었다. 그러나 쿠키의 보안상 취약과 저장소 용량 부족으로 웹 스토리지가 나오게 되었다.
역할 : 웹 브라우저가 직접 데이터를 저장할 수 있게 해준다. 또한 사용자 측에서 정보를 안전하게 저장할 수 있게 해주고, 이 정보는 서버로 전송되지 않고 클라이언트에만 존재하기 때문에 네트워크 트래픽 비용도 줄여준다.
웹 스토리지는 데이터의 지속성과 관련해 두 가지 용도의 저장소 객체를 제공한다.
로컬스토리지(localStorage)
로컬스토리지 객체는 보관 기한이 없는 데이터를 저장한다. 따라서 브라우저 탭이 닫히거나, 컴퓨터를 재부팅해도 이 저장소에 저장된 데이터는 사라지지 않는다.
Windows 전역 객체의 localStorage라는 컬렉션을 통해 저장과 조회가 가능하며, 도메인 마다 별도의 localStorage가 생성되므로 도메인만 같으면 전역으로 데이터의 공유가 가능하다.
세션스토리지(sessionStorage)
세션스토리지 객체는 하나의 세션만을 위한 데이터를 저장한다. 데이터를 지속적으로 보관하지 않고 브라우징되고 있는 브라우저 컨텍스트 내에서만 데이터가 유지되기 때문에, 사용자가 브라우저 탭이나 창을 닫으면 이 객체에 저장된 데이터는 사라진다.
-브라우징: 브라우저 프로그램을 실행해서 인터넷에 들어가 필요한 정보를 찾는 행위
-브라우저 컨텍스트: 브라우저가 문서를 표시하는 환경.
각 브라우징 컨텍스트는 특정 출처 및 활성화되고 있는 문서의 출처, 표시했던 모든 문서의 방문기록을 갖고 있다.
저장과 조회는 Windows 전역 객체의 sessionStorage라는 컬렉션을 통해 이루어지며, 도메인 별로 별도로 생성되는데 브라우저가 다르면 서로 다른 영역이 된다. 즉, 브라우저 두 개를 실행해 같은 페이지를 열었을 때, 브라우저의 컨텍스트가 서로 다르므로 이 두 페이지의 sessionStorage는 각 별개의 영역으로 인지되어 서로 데이터의 공유가 불가능하다.
window.localStorage
: 만료 날짜가 없는 데이터를 저장할 때 사용 window.sessionStorage
: 세션이 있는 데이터를 저장할 때 사용 (브라우저 탭을 닫으면 손실되는 것을 의도한 데이터를 저장할 때 사용)브라우저 컨텍스트 내에서 저장한 데이터를 가지고 활용할 수 있기 때문에 복구 및 백업에 관련된 기능에 주로 사용
HTML, CSS, JavaScript 등 개발자가 작성한 문서가 브라우저에서 출력되는 과정.
현존하는 브라우저마다 다르지만, 브라우저는 기본적으로 렌더링을 수행하는 렌더링 엔진을 가지고 있다.
1. 사용자가 브라우저를 통해 웹 사이트 접속.
2. 브라우저는 서버로부터 HTML, CSS, JavaScript와 같은 웹사이트에 필요한 리소스를 다운
3. 렌더링 엔진은 전달받은 HTML 문서를 파싱(parsing)해 DOM(Document Object Model, 문서 객체 모델) 트리 생성
4. 이어서 다운 받은 외부 CSS 파일과 함께 포함된 스타일 요소를 파싱(parsing)해 CSSOM(CSS Object Model, CSS 객체 모델) 트리 생성
5. 만든 DOM 트리와 CSSOM 트리를 결합해 Render 트리를 구축
6. 레이아웃 과정을 통해 각 요소를 어디에 배치할 지 결정
7. 레이아웃 과정이 끝나면 UI 백엔드에서 Render 트리를 화면에 그리기 시작. ---> 이 과정을 paint라고 함
프로그래밍 언어로 작성된 파일을 실행시키기 위해 구문 분석(syntax analysis)을 하는 단계로 파서(parser)가 진행한다.
파서는 HTML 파일의 코드를 문법적 의미를 갖는 최소 단위인 토큰(token)으로 한 번 분해하고, 이 토큰들을 문법적 의미와 구조에 따라 노드(node)라는 요소로 바꾼다.
문서 파싱(document parsing): 브라우저가 코드를 이해하고 사용할 수 있는 구조로 변환하는 것.
브라우저는 HTML 문서를 받아들자마자 DOM 트리로 파싱한다.
HTML 문서를 파싱하면서 CSS스타일을 만날 경우
DOM은 HTML문서의 요소들의 중첩 관계를 기반으로 노드들을 트리 구조로 구성한 것을 의미.
브라우저는 자바스크립트 언어만 알고 HTML의 태그나 속성을 이해하지 못한다. DOM 트리는 그걸 이해할 수 있는 형태인 객체로 바꿔준다.
html 파일을 DOM 트리로 파싱하던 브라우저는 <link>
, <style>
태그를 만나게 되면 파싱을 멈추고 해당 리소스 파일을 서버로 요청한다. 이 파일을 파싱해서 만든 트리.
- CSSOM Tree를 구축하고 나면 브라우저는 다시 html 파일의 파싱을 멈췄던 부분으로 돌아가 마저 DOM 트리를 파싱한다.
CSS는 부모의 속성을 자식이 상속 받는다.
ex) 예를 들어 body가 부모 요소이고 font-size가 16px인 속성을 가지고 있는데, 그 밑에 있는 p는 자식 요소이기 때문에 부모 요소인 body가 갖고 있던 속성을 상속 받으면서 동시에 자신이 가지고 있는 속성인 font-weight 속성까지 가지므로 2개의 속성을 갖는다.
💡 DOM 트리와 CSSOM 트리는 트리 구조로 되어 있기 때문에 비슷하게 생겼지만, 애초에 리소스부터 틀린 서로 다른 속성을 가진 독립적인 트리다.
그렇기 때문에 브라우저 위에 웹사이트를 표시하기 위해선 이 둘을 합치는 작업이 필요하다.
렌더링을 목적으로 만들어지는 트리. 렌더링은 사용자에게 브라우저가 보여주고자 하는 화면을 그리는 과정이므로, 보이지 않을 요소들은 이 트리에 포함시키지 않는다.
💡 DOM, CSSOM에 있던 속성들이 합쳐서 렌더 트리를 구성했다. 그러나 아직까지 렌더 트리는 텍스트로 구성된 객체로만 보이므로 페인팅이라는 작업을 거쳐야 브라우저 위의 화면으로 그려지게 된다.
렌더 트리에는 CSSOM 트리에 있던 속성들이 합쳐져 있다. 하지만 각 요소에 관련된 정보일 뿐 그 이상은 모른다. 이런 계산은 브라우저의 렌더링 엔진이 하며, 위에서 아래로 읽어 내려가며, 모든 값은 절대적인 단위인 px값으로 변환된다
렌더트리를 기반으로 HTML 요소의 레이아웃(위치, 크기 등)을 계산하여 브라우저 화면 어디에 배치할 지 결정하는 과정.
'웹 페이지 레이아웃 짜기' 와 다른 개념이다.
각 정보를 가진 픽셀이 모여 하나의 화면을 구성한다. 페인팅은 이런 픽셀에 대한 정보들을 바탕으로 픽셀을 채워나가는 과정이며, 이 과정까지 해내야 텍스트에 불과했던 HTML 파일의 내용들이 이미지화된 모습으로 브라우저 화면에 띄워진다.
리플로우 :
어떤 웹 인터랙션으로 인해 화면에 나타나는 모습을 바꾸는 렌더링 과정의 레이아웃을 반복해 수행하는 것
리페인트 :
페인트 과정을 반복해 수행하는 것
DOM은 변경이 되면 렌더 트리를 다시 구축하기 때문에, 변경이 될 때마다 리플로우와 리페인트를 다시 해야 한다. 리플로우 과정은 렌더링을 다시 하는 것이기 때문에 배치를 위한 연산을 해야해서 CPU를 많이 차지하고,
리페인트는 페인트를 다시 하는 것이라 픽셀을 다시 화면에 찍어 그려야하므로 GPU를 많이 차지한다.
초당 60프레임으로 유지시키던 프레임의 수가 브라우저의 과부하로 인해 줄어드는 현상.
없어진 프레임은 렌더링 엔진이 인식할 수 없으므로 드랍된 프레임을 브라우저 화면에 그리지 못한다.
이러한 현상이 생기면 유저 경험(UX)에 좋지 않으므로 최적화를 고려해야 한다.
CSSOM 트리의 CSS 속성 중에 레이아웃을 발생시키는 속성을 사용하게 되면 그때마다 변경되어 렌더 트리를 만들고, 레이아웃을 발생시키고, 페인트를 하는 과정이 반복된다. 따라서 이런 레이아웃을 발생시키는 속성을 줄인다.
리플로우 시 리페인트는 필연적으로 일어나므로 가능하다면 리플로우가 발생하는 속성보다 리페인트만 발생하는 속성을 사용해주는 게 좋다.
리플로우가 일어나는 대표적 속성
- 위치, 너비와 관련된 속성
- left 속성 중 left-top, left-bottom 속성을 사용하면 위치가 변경됨
- 이 속성을 피해 transform이라는 속성을 사용한다.
리페인트가 일어나는 대표적인 속성
- visibility/display
- opacitiy를 사용한다.
JavaScript + CSS를 조합한 애니메이션이 많거나, 레이아웃 변화가 많은 요소의 경우, position을 absolute 또는 fixed를 사용해주면 영향을 받는 주변 노드들을 줄여줄 수 있다.