sungyup's.

Web_Miscellaneous / 브라우저 / 2.1 브라우저 렌더링 원리

2.1브라우저 렌더링 원리

브라우저 렌더링 원리에 관하여

요약

브라우저는 화면에 나타나는 요소를 렌더링 할 때, 렌더링 엔진(Blink, Webkit 등)을 사용함. 렌더링 엔진이 html, css, javascript로 렌더링 할 때 CRP(Critical Rendering Path)라는 프로세스를 사용

  1. html 파싱 후, DOM 트리 구축
  2. css 파싱 후, CSSOM 트리 구축
  3. javascript 실행(html 중간에 script가 있으면 html 파싱 중단)
  4. DOM과 CSSOM 조합하여 렌더 트리 구축
  5. 뷰 포트 기반으로 렌더트리의 각 노드가 가지는 위치/크기 계산(layout 단계)
  6. 계산한 위치/크기를 기반으로 화면에 그림(paint 단계)

1. 브라우저의 주요 기능

  • 브라우저란 ? : (웹) 브라우저는 World Wide Web(인터넷)으로부터 정보 자원을 가져오고 보여주는 등의 활동을 하기 위해 만들어진 클라이언트-사이드 소프트웨어 애플리케이션.
  • 사용자가 선택한 자원을 서버에 요청하고 브라우저에 표시
    • 여기서 자원은 주로 html문서지만 pdf, 이미지 또는 그 외일 수도 있음
    • 자원의 주소는 URI(Uniform Resource Identifier)에 의해 정해짐
  • 브라우저는 html 파일을 해석하는데 있어 html과 css 명세에 따라 표시
    • 이 명세는 W3C(World Wide Web Consortium)에서 정함
  • 대부분의 브라우저는 아래의 기능들 공유
    • URI를 입력할 수 있는 주소표시줄
    • 이전 버튼/다음 버튼
    • 북마크
    • 새로 고침/현재 문서 로드 중단
  • 위 기능들은 표준 명세에 따른게 아니라 수년간 경쟁업체를 서로 모방하며 이른 것.
    • html5 명세는 주소 표시줄, 상태 표시줄, 도구 모음만 명시

2. 브라우저의 기본 구조

  • 사용자 인터페이스 : 주소 표시줄, 이전/다음 버튼, 북마크 메뉴 등 요청한 페이지를 보여주는 창 제외 나머지 모든 부분
  • 브라우저 엔진 : 네트워크 요청, 보안, 네비게이션 관리 등 브라우저 전반 제어(렌더링 엔진을 포함하는 개념)
    • 레이아웃, 렌더링 외에도 문서들 간의 보안 정책을 강제하며 페이지 스크립트에 노출되는 DOM 자료 구조를 구현
  • 렌더링 엔진(=layout engine) : 요청한 콘텐츠를 표시. 파싱, 레이아웃 배치 등 시각적인 부분 만드는 엔진
    • 예를 들어 html을 요청하면 html과 css를 파싱하여 화면에 표시
  • 통신 : http 요청과 같은 네트워크 호출에 사용
  • UI 백엔드 : 콤보 박스와 창 같은 기본적인 장치를 그림
  • 자바스크립트 해석기
  • 자료 저장소 : 쿠키 등 모든 종류의 자원을 하드 디스크에 저장
    브라우저 아키텍처
    브라우저 아키텍처. 브라우저는 렌더링 엔진, 통신, UI 백엔드, 자바스크립트 해석기, 자료 저장소 등 여러 컴포넌트로 구성되어 있음.

cf) 크롬은 대부분의 브라우저들과 달리 각 탭마다 별도의 렌더링 엔진 인스턴스를 유지.(각 탭이 독립된 프로세스로 처리)

3. 렌더링 엔진

  • 요청 받은 내용을 브라우저 화면에 표시
    • Gecko : 파이어폭스에서 사용
    • Webkit : 사파리에서 사용
    • Blink: 크롬, 엣지에서 사용
  • 기본 동작 과정은 아래와 같음
브라우저 렌더링 과정
브라우저 렌더링 과정. 브라우저는 렌더링 엔진, 통신, UI 백엔드, 자바스크립트 해석기, 자료 저장소 등 여러 컴포넌트로 구성되어 있음.
  1. html 문서를 파싱하고 콘텐츠 트리 내부에서 태그를 DOM 노드로 변환.
  2. 외부 CSS파일과 함께 포함된 스타일 요소도 파싱
    1. 이 스타일 정보와 html 표시 규칙은 “렌더 트리”라고 부르는 또다른 트리 생성
    2. 렌더 트리는 색상/면적 등 시각적 속성이 있는 사각형 포함.
    3. 렌더 트리 생성이 끝나면 배치 시작(노드를 화면의 정확한 위치에 표시)
  3. UI 백엔드에서 렌더 트리의 각 노드를 가로지르며 형상을 그림
  • 아래는 webkit 동작 과정
    webkit 렌더링 과정
    webkit 렌더링 과정. 브라우저는 렌더링 엔진, 통신, UI 백엔드, 자바스크립트 해석기, 자료 저장소 등 여러 컴포넌트로 구성되어 있음.

4. 파싱과 DOM 트리 구축

  • 파싱 : 브라우저가 코드를 이해하고 사용할 수 있는 구조로 변환하는 것
    • 파싱한 결과는 보통 문서 구조를 나타내는 노드 트리
      • 이 노드 트리들을 parse tree 또는 syntax tree라고 부름
    • 문맥 자유 문법 : 파싱할 수 있는 모든 형식은 정해진 용어와 구문 규칙(BNF라고 부르는 규칙)에 따라야함(인간의 언어는 BNF에 따르지 않아 기계적 파싱이 불가)
  • 파서-어휘 분석기 조합
    • 파싱은 어휘 분석/구문 분석 2가지로 구분 할 수 있음
      • 어휘 분석(토큰 변환) : 자료를 토큰으로 분해
        • 토큰: 인간으로 따지면 사전에 등장하는 모든 단어. 유효하게 구성된 단위의 집합체.
        • 어휘: 정규 표현식(Regex)으로 보통 표현됨
      • 구문 분석 : 언어의 구문 규칙(BNF라고 부르는 형식)을 적용
  • 파싱 과정은 보통 파서가 어휘 분석기로부터 새 토큰을 받아 구문 규칙과 일치하는지 확인하고,
    • 규칙에 맞으면 노드가 파싱 트리에 추가되고 파서가 또 다른 토큰을 요청하고
    • 규칙에 맞지 않으면 파서는 토큰을 내부적으로 저장하고 토큰과 일치하는 규칙이 발견될 때까지 요청. 맞는 규칙이 없는 경우 예외로 처리
  • 변환 : 파서 트리는 최종 결과물이 아님. 파싱은 문서를 다른 양식으로 변환하는 것인데 소스 코드를 기계 코드로 만드는 컴파일러가 있어 파싱 트리 생성 후 이를 기계 코드 문서로 변환
  • 파서의 종류
    • 하향식 파서: 구문의 상위 구조로부터 일치하는 부분을 찾음
    • 상향식 파서: 낮은 수준에서 점차 높은 수준으로 찾음 ⇒ 이동-감소 파서라고도 부름(점차 이동하며 남는 파싱 대상이 감소하기 때문)
  • 파서 자동 생성
    • 파서 생성기: 파서를 생성해 줄 수 있는 도구. 언어에 어휘/구문규칙 같은 문법을 부여하면 동작하는 파서를 만들어줌
      • webkit은 어휘 생성을 위한 Flex와 파서 생성을 위한 Bison을 사용
        • Flex: 토큰의 정규 표현식 정의를 포함하는 파일을 입력 받음
        • Bison: BNF 형식의 언어 구문 규칙을 입력 받음
  • HTML 파서: html 마크업을 파싱 트리로 변환
    • html 문법은 문맥 자유 문법이 아님 : 모든 전통적인 파서는 html에 적용할 수 없음. html 정의를 위한 공식적 형식으론 DTD(문서 형식 정의)가 있지만 이건 문맥 자유 문법이 아님.
      • html은 암묵적으로 태그에 대한 생략이 가능. (유연한 문법) ⇒ 웹 제작자의 실수를 너그럽게 용서하고 편하게 만들어주지만, 대신 공식적인 문법으로 작성하기 어려움
    • DOM : “파싱 트리”는 DOM 요소와 속성 노드의 트리로서 출력 트리가 됨. DOM은 문서 객체 모델(Document Object Model)의 준말.
      • html 문서의 객체 표현
      • 외부를 향하는 자바스크립트와 같은 html 요소의 연결 지점.
      • 트리의 최상위 객체는 문서
    • DOM은 마크업과 1:1 관계임 예를 들면,
      html
      <html> <body> <p>Hello World</p> <div><img src="example.png" /></div> </body> </html>

위 코드는 아래의 DOM 트리로 변환 가능

DOM 트리
DOM 트리. 브라우저는 렌더링 엔진, 통신, UI 백엔드, 자바스크립트 해석기, 자료 저장소 등 여러 컴포넌트로 구성되어 있음.
  • 파싱 알고리즘 : html은 일반적인 하향식/상향식 파서로 파싱이 안되는데, 이유는
    • 언어의 너그러운 속성
    • html 오류에 대한 브라우저의 관용
    • 변경에 의한 재파싱. 일반적으로 소스는 파싱하는 동안 변하지 않지만 html에서는 스크립트 태그가 토큰 추가가 가능해서 입력 과정에서 파싱 수정.
  • 따라서 일반적인 파싱 기술을 사용할 수 없기에 html은 파싱을 위한 별도의 파서를 필요로 함. 이는 브라우저 엔진들(Blink, Gecko, Webkit)등에 있음
    • 토큰화 / 트리 구축 이렇게 2단계
      • 토큰화 : 어휘 분석. 입력값을 토큰으로 파싱(html에선 시작 태그, 종료 태그, 속성 이름과 속성 값) ⇒ 토큰을 인지하면 트리 생성자로 넘김
        토큰화
        토큰화 과정
  • 트리 구축 알고리즘
    • 파서가 생성되면 문서 객체가 생성됨
    • 트리 구축이 진행되는 동안 문서 최상단 객체에서는 DOM 트리가 수정되고 요소가 추가됨
    • 토큰화에 의해 발행된 각 노드는 트리 생성자에 의해 처리됨
    • DOM트리에 요소를 추가하는 것이 아니라면 열린 요소는 스택(임시 버퍼 저장소)에 추가됨
      • 스택에서 부정확한 중첩과 종료되지 않은 태그를 교정
  • 파싱이 긑나면, 브라우저는 문서와 상호작용 가능
    • 문서 파싱 이후에 실행되어야 하는 ‘지연’모드 스크립트 파싱 시작
    • 문서 상태 ‘완료’, ‘로드’이벤트 발생

5. CSS 파싱

css는 html과 달리 문맥 자유 문법이기에 일반적인 파서로 파싱이 가능

  • 스크립트와 스타일 시트의 진행 순서
    • 스크립트 : 웹은 파싱과 실행이 동시에 수행되는 동기화(synchronous) 모델
      • 제작자는 파서가 <script>태그를 만나면 즉시 파싱하고 실행하기를 기대
      • 스크립트가 실행되는 동안 문서의 파싱은 중단(스크립트가 외부에 있는 경우에도 네트워크로부터 자원을 가져오는 동안 파싱 중단)
        • 스크립트를 defer로 표시할 수 있는데 이러면 문서 파싱이 중단되지 않고 문서 파싱부터 완료한 후 스크립트를 실행
      • html5에서는 스크립트를 asynchronous로 처리하는 속성을 추가했기 때문에 별도의 맥락에 의해 파싱되고 실행
    • 예측 파싱 : 브라우저가 지원하는 최적화 기능 중 하나로, 스크립트를 실행하는 동안 다른 스레드가 네트워크로부터 다른 자원을 찾아 내려받고 문서의 나머지 부분 파싱
      • DOM 트리를 수정하진 않음.(이건 메인 파서의 일) 외부 스크립트, 외부 스타일 시트, 외부 이미지 등 참조된 외부 자원을 파싱
    • 스타일 시트: DOM 트리를 변경하지 않기에 문서 파싱을 기다리거나 중단할 이유가 없음.
      • 단, 스크립트가 문서를 파싱하는 동안 스타일 정보를 요청한다면 스크립트 실행을 중단하는 등의 조치를 브라우저가 취함
    • 렌더 트리 구축
      • DOM 트리가 구축되는 동안 브라우저는 렌더 트리를 구축
        • 표시해야 할 순서와 문서의 시각적인 구성 요소를 올바른 순서로 그리기 위함
    • DOM 트리와 렌더 트리의 관계
      • 렌더 트리의 구성 요소인 렌더러는 DOM 요소에 부합하지만 1:1 대응은 아님(ex. head 요소 같은 비시각적 DOM 요소는 렌더 트리에 들어가지 않으며, display 속성이 none이면 트리에 나오지 않음)
    • 스타일 계산
      • 렌더 트리 구축을 위해선 렌더 객체들 각각의 시각적 속성에 대한 계산이 필요
        • 인라인 스타일 요소 + html의 시각적 속성(css 스타일로 변환되어 적용)
      • 스타일 규칙을 적용하는 것은 계층 구조를 파악해야하는 꽤 복잡한 다단계 규칙을 지켜야함(div div div 이런 식으로 중첩되었을 경우 등)