CS/브라우저

브라우저와 렌더링에 대하여

H.E 2023. 6. 18. 23:51

[ 브라우저 ]

브라우저는 우리 접속하는 크롬, 사파리, 파이어폭스 등을 말함

브라우저는 웹에서 페이지를 검색하고 표시하며 사용자가 하이퍼링크를 통해 추가 페이지에 접근할 수 있도록 하는 프로그램임. 웹 브라우저는 동기적으로 HTML, CSS, JS 언어를 해석하여 내용을 화면에 보여주는 응용 소프트웨어(소프트웨어는 컴퓨터를 비롯한 시스템에서 특정 작업을 수행하게 하는 프로그램의 집합)

 

동기적으로 하는 이유는 DOM 트리가 완성되기 전에 script가 DOM을 조작하면 에러가 발생하게 되고, 화면에는 우선적으로 HTML 요소들로 이루어진 레이아웃 화면이 렌더링 되고, 그 다음에 script를 읽어서 사용자와 상호작용하는 순서로 이루어지기 때문임

 

브라우저는 유저가 선택한 자원을 서버로 부터 받아와서 유저에게 보여줌. 자원은 페이지 외에도 이미지, 비디오 등의 컨텐츠들이 포함됨. 받아온 자원들을 렌더링 과정을 통해 유저에게 보여주게 됨

 

[ 브라우저 구조 ]

1.  사용자 인터페이스 

 사용자가 접근할 수 있는 영역. URI를 입력할 수 있는 주소 표시줄, 이전/다음 버튼, 북마크 메뉴, 새로 고침 버튼과 현재 문서의 로드를 중단할 수 있는 정지 버튼 , 홈 버튼 등 요청한 페이지를 보여주는 창을 제외한 나머지 모든 부분

 

2. 브라우저 엔진 

 사용자 인터페이스와 렌더링 엔진 사이의 동작을 제.  Data Storage를 참조하며 로컬에 데이터를 쓰고 읽으면서 다양한 작업을 함

 

3. 렌더링 엔진 (, 브라우저의 동작원리를 이해하려면 렌더링 엔진의 이해가 중요함)

 웹 서버로부터 응답 받은 자원을 웹 브라우저 상에 나타냄

예를 들어 HTML 문서를 응답받으면 HTML과 CSS를 파싱 하여 화면에 표시함

 

 브라우저는 서버로부터 HTML 문서를 응답받으면 렌더링 엔진의 HTML 파서와 CSS 파서에 의해 파싱(parsing)되어 DOM, CSSOM 트리로 변환되고 렌더 트리로 결합함. 이렇게 생성된 렌더 트리를 기반으로 브라우저는 웹 페이지를 나타냄

 

각 브라우저마다 렌더링 엔진이 다르기 때문에 같은 페이지가 다르게 보이는 경우가 있음

렌더링 엔진은 좀 더 나은 사용자 경험을 위해 가능하면 빠르게 내용을 표시하기 위해 일련의 과정들이 동기적으로 진행되지 않음

HTML을 파싱 할때까지 기다리지 않고 렌더 트리 배치와 그리기 과정을 진행함

 

4. 통신

 HTTP 요청과 같은, 서버와 통신이 가능하게 하는 네트워크 호출에 사용됨

 

5. UI 백엔드 

 select, input 등 기본적인 위젯을 그리는 인터페이스C

 

6. 자바스크립트 해석기

 자바스크립트 코드를 해석하고 실행함 

 

7. 자료 저장소

 Cookie, Local Storage, Indexed DB 등 브라우저 메모리를 활용하여 저장하는 영역

 

다만 크롬은 대부분의 브라우저와 달리 각 탭마다 별도의 렌더링 엔진 인스턴스를 유지하며 각 탭은 독립된 프로세스로 처리되어 메모리를 상대적으로 많이 잡아 먹음

 

[ 브라우저 렌더링 동작 과정 ]

  1. HTML 파일과 CSS파일을 파싱해서 각각 Tree(DOM, CSSOM)를 만듬(Parsing)
  2. 두 Tree를 결합하여 Rendering Tree를 만듬(Style)
  3. Rendering Tree에서 각 노드의 위치와 크기를 계산함(Layout)
  4. 계산된 값을 이용해 각 노드를 화면상의 실제 픽셀로 변환하고, 레이어를 만듦(Paint)
  5. 레이어를 합성하여 실제 화면에 나타냄(Composite)

돔이란?

DOM은 Document Object Model의 약자로 HTML 내에 원하는 위치에 접근하기 위한 하나의 방식으로 W3C(World Wide Web, 표준을 개발하고 장려하는 조직) 표준임

이 방식은 프로그램이나 스크립트 보다 더 효율적으로 문서의 내용, 구조, 모양 등에 접근하여 갱신, 교체 ,삭제하도록 도와줌. HTML DOM 구조는 HTML 태그 차례와 깊은 관련이 있으며 현재 위치한 포인터를 기준으로 부모요소, 자식요소 등에 기초함. 이것을 한 눈에 알아보기 쉽도록, Tree로 표현한것을 돔트리(DOM Tree)라고 함

CSSOM은 HTML 대신 CSS가 대상인 DOM이라고 할 수 있음

 

▶ Parsing

브라우저가 페이지를 렌더링 하려면 가장 먼저 받아온 HTML 파일을 해석해야함

Parsing 단계에서는 HTML 파일을 해석하여 DOM Tree를 구성하는 단계

Parsing중에 Html에 CSS가 포함되어 있다면 CSSOM Tree 구성 작업도 함께 진행

 

▶ Style

Parsing 단계에서 생성된 DOM Tree와 CSSOM Tree를 매치싱켜서 Render Tree를 구성

Render Tree는 실제로 화면에 크려질 Tree임 DOM과 CSSM은 독립적인 개체임

DOM은 하나의 콘텐츠 CSSOM은 문서의 스타일 규칙을 설명함

브라우저는 이 두가지를 병합하여 화면에 픽셀을 렌더링 하기 위한 최종 보스인 Render tree를 만듦

즉 Render Tree는 화면에 보이는 모든 노드와 콘텐츠, 스타일 정보를 병합한 최종 출력해 해당됨

 

브라우저가 렌더 트리를 생성하는 작업

  1. DOM 트리의 루트에서 시작해서 노드 각각을 읽으며 표시합니다.
    • 메타 태그나 스크립트 태그 등의 노드는 표시되지 않음
      • 사용자에게 보이지않아도 되는 내용은 렌더링 출력에 반영되지 않음
    • 일부 노드는 CSS를 통해 숨겨지며 렌더 트리에서도 생략이 됨
      • 예를 들어 span 노드에 display : none 속성을 설정하면 렌더 트리에서 누락됨
  2. 표시된 각 노드에 대해 적절하게 일치하는 CSSOM 규칙을 찾아 적용함
  3. 표시된 노드를 콘텐츠 및 계산된 스타일과 함께 내보냄

Render Tree를 구성할 때 visibility:hidden은 보이진 않지만 요소가 공간을 차지하기 때문에 비어 있는 상자로 렌더링 되지만  Rdisplay: none의 경우는 Render Tree에서 요소를 완전히 제거됨

 

▶ Layout

브라우저 뷰포트(Viewport, 현재 환면에 보여지고 있는 다각형의 영역) 내에서 각 노드들의 정확한 위치와 크기를 계산

생성된 Render Tree 노드들이 가지고 있는 스타일과 속성에 따라서 브라우저 화면의 어느 위치에 어느 크기로 출력될지 계산하는 단계임. 레이아웃 단계에서 %, vh, vw와 같이 상대적인 위치, 크기 속성은 실제 화면에 그려지는 픽셀 단위로 변환

 

▶ Paint

Layout단계에서 계산이 완료되면 계산된 값을 이용해 이제 요소들을 실제 화면을 그리게 됨. 즉 계산된 값을 이용해 Render Tree의 각 노드를 화면상의 실제 픽셸로 변환하는 것

이때 픽셀로 변환된 결과는 하나의 레이어가 아니라 여러개의 레이어로 관리됨. 또한 처리해야하는 스타일이 복잡할수록 paint 단계에 소요되는 시간이 김(ex. 그라데이션, 그림자 효과 > 단색 배경)

 

▶ Composite

여러개의 레이어로 나누어진 픽셀값들을 우리가 실제로 보는 화면처럼 합성해주는 단계

4번의 Painting 단계에서 그려진 레이어들을 순서에 맞추어 합성해 유저가 보는 화면을 만듬

 

최종 url이 입력되었을 때 페이지가 화면에 보이는 과정

주소창에 url을 입력하고 Enter 누르면 서버에 요청이 전송됨 해당 페이지는에 존재하는 여러 자원들이 보내짐

렌더링 엔진이 html 파싱 과정을 시작. html 파서가 문서에 존재하는 어휘와 구문을 분석하면서 DOM 트리를 구축

CSS파싱 시작. CSS파서가 모든 CSS정보를 스타일 구조체로 생성

DOM과 CSSOM 을 합쳐 렌더 트리를 만듦. 렌더 트리를 통해 문서가 시각적 요소를 포함한 형태로 구성된 상태

화면에 배치를 시작하고, UI 백엔드가 노드를 돌며 형상을 그림

이때 빠른 브라우저 화면 표시를 위해 배치와 그리는 과정을 페이지 정보를 모두 받고 한꺼번에 진행된느 것이 아닌 자원을 전송 받으면서 동시에 일부분 먼저 진행하고 화면에 표시함

 

[ 브라우저 리렌더링 과정 ]

브라우저 렌더링은 이러한 한번의 작업으로 최종적으로 종료되는 것이 아님

사용자와 상호작용하기 위해 다양한 이벤트를 생성함. 상황에 따라 색을 바꾸거나, 크기를 바꾸거나, 요소를 추가 삭제하는 등이 일이 일어남. 이때 변화된 값을 토대로 Render tree 를 재계산할 필요가 있는데, 매번 렌더링의 5단계가 모두 일어나는 것은 아님. 이러한 리렌더링 과정을 총 3가지로 분류할 수 있음

 

▶ Reflow(=layout)

어떠한 이벤트나 액션에 따라서 노드의 크기나 위치가 바뀌는 경우 그에 영향을 받는 노드들을 모두 포함하여 layout 단계를 다시 수행하게 됨. 대표적으로 뷰포트의 크기가 변경되거나, 노드가 추가, 삭제되거나, 요소의 위치 혹은 크기가 변경되거나, 이미지 크기 변경에서도 Reflow 가 일어남

 

-  속성들: 주로 크기가 바뀌는 속성들, 배치를 바꾸는 속성들

backgroundtext-decorationborder-styleborder-radius , box-shadow , color , line-style , outline , visibility …

 

▶Repaint

브라우저 렌더링 과정 중 Paint 과정이 다시 일어나는 것을 말함.  Reflow 가 일어난 뒤에 뒤이어 Repaint 가 일어날수도 있고 Repaint 부터 시작될 수도 있음. background-color, visibility 와 같이 레이아웃에는 영향을 주지 않으나 스타일 속성이 변경되는 경우에는 Repaint 부터 렌더링을 다시 수행하게 된다

 

- 속성들: 색만 변화는 속성들, 두께만 변화하는 속성들

backgroundtext-decorationborder-styleborder-radius , box-shadow , color , line-style , outline , visibility …

 

▶ Composite

두가지 스타일을 변화를 일으키지 않는 시각적 변화는 두 단계를 건너뛰고 바로 Composite 과정부터 리렌더링이 시작됨

 

- transform , opacity , cursor , perspective …

 

 브라우저 렌더링 최적화

Compoite > Repaint > Reflow

 

reflow 는 layout → paint → composite 과정을 반복하며 repaint 는 paint → composite 을 과정을 반복함

즉 reflow 가 일어나면 repaint 는 반드시 일어남. 따라서 동일한 현상을 웹페이지에 나타내고자 한다면 reflow 보다는 repaint 만 일어나는 것을 가능하다면 composite만 리렌더링하는 것이 브라우저 최적화에 도움이 됨

 

[ 자바스크립트의 처리 ]

JS는 렌더링 엔진에서 처리되는 것이 아닌 JS엔진에서 처리

HTML 파서(Parser)는 <script> 태그를 만나면 JS코드를 실행하기 위해 DOM 생성 프로세서를 중지하고 JS엔진을 권한을 넘김. 제어 권한을 넘겨받은 JS 엔진은 <script> 태그 내의 JS 코드 또는 src 속성에 정의된 JS 파일을 로드하고 파싱하여 실행함. JS의 실행이 완료되면 다시 HTML 파서로 제어권한을 넘겨서 중지했던 시점으로 돌아가 DOM 생성을 재개

 

script의 위치가 body 밑으로 하는 이유

더보기
닫기

 HTML태그들 사이에 script 태그가 위치하면 두가지 문제가 발생함

  1. HTML을 읽는 과정에 스크립트를 만나면 중단 시점이 생기고 그만큼 Display에 표시되는 것이 지연됨
  2. DOM 트리가 생성되기전에 자바스크립트가 생성되지도 않은 DOM의 조작을 시도할 수 있음

위와 같은 상황을 막기 위해 script 태그는 body 태그 최하단에 위치하는 게 가장 좋음

만약 script 태그를 body 태그 최하단에 놓기 싫거나 할 수 없는 상황에는 async와 defer 속성을 활용하여 스크립트 로딩 순서를 제어할 수 있음

  • async: <script> 태그를 만나도 html parsing이 중단되지 않음
    • script로드와 html parsing이 함께 이루어지다 script 로드가 끝나면 script가 실행되는 시점에 html parsing이 잠시 중단되고 실행이 끝나면 html parsing이 재개됨
  • defer: <script> 태그를 만나도 script 로드의 시작부터 끝까지 html parsing이 중단되지 않으며 html parsing이 끝나고 난 뒤에야 script가 실행됨

script 내부에서 로딩 순서 제어하는 경우

  • DOMContentLoaded: DOM 생성이 끝난 후 실행
  • onload: 내부의 코드는 문서에 포함된 모든 콘텐츠(images, script, css, ...)가 전부 로드된 후에 실행됨

'CS > 브라우저' 카테고리의 다른 글

크로스 브라우징  (0) 2023.07.16
브라우저 저장소  (0) 2023.06.25
브라우저 렌더링 원리_민희  (0) 2023.06.20
브라우저 렌더링 원리 /edited by.혜경  (0) 2023.06.18
브라우저 렌더링 - 이도영  (0) 2023.06.18