브라우저의 구성 요소를 알아보고, 각 요소가 사용자가 주소를 입력하고 화면을 렌더링하기까지 어떤 역할을 하는지 알아봅니다.
브라우저의 구성 요소
- 사용자 인터페이스
- 브라우저 엔진
- 렌더링 엔진
- 통신 ex)HTTP
- UI 백엔드
- 자바스크립트 해석기
- 자료 저장소(client side storage)
브라우저 구성 요소 프로세스
브라우저 각각의 구성 요소별로 별도의 프로세스에서 제어된다. 크롬에서 렌더러 프로세스를 여러 개 사용하는 이유는 탭마다 렌더러 프로세스를 사용함으로서 한 탭이 응답하지 않을 때 다른 탭을 사용할 수 있기 때문이다.
- 브라우저 프로세스
- 주소 표시줄, 북마크 막대기, 뒤로 가기 버튼, 앞으로 가기 버튼 등 브라우저 UI 부분을 제어 힌다.
- UI 스레드, 네트워크 스레드, 스토리지 스레드등이 있다.
- UI 스레드는 브라우저의 버튼과 입력란을 그린다.
- 네트워크 스레드는 인터넷에서 데이터를 가져오기 위해 네트워크 스택을 다룬다.
- 스토리지 스레드는 파일에 대한 접근을 제어한다.
- 렌더러 프로세스
- 탭 안에서 웹 사이트가 표시되는 부분의 모든 것을 제어힌다.
- 플러그인 프로세스
- 웹 사이트에서 사용하는 플러그인을 제어한다.
- GPU 프로세스
- GPU 작업을 다른 프로세스와 격리해서 처리한다. GPU는 여러 애플리케이션의 요청을 처리하고 같은 화면에 요청받은 내용을 그리기 때문에 GPU는 별도 프로세스로 분리되어 있다.
주소 입력에서 렌더링까지
사용자가 주소를 입력하고 화면을 렌더링하기까지의 과정을 통해서 브라우저가 어떻게 동작하는지 알아본다.
내비게이션
1. 입력 처리
- 주소 표시줄에 사용자가 URL을 입력하면, 브라우저 프로세스의 UI 스레드가 입력을 처리한다.
- UI 스레드에서 사용자가 입력한 문자열이 URL인지 판별한다.
- 사용자가 엔터키를 입력하면, 사이트 콘텐츠를 가져오기 위해서 UI 스레드가 네트워크 호출을 시작한다.
2. 내비게이션 시작
- 네트워크 스레드는 DNS Lookup 및 TLS(Transport Layer Security) 연결 설정과 같은 적절한 프로토콜을 거쳐 (3way handshake 같은) 요청을 처리한다.
- 만약 네트워크 스레드가 301 응답을 받으면, 다시 새로운 URL 요청이 시작된다.
3. 응답 읽기
- 응답 본문인 페이로드가 들어오기 시작하면 네트워크 스레드는 필요에 따라 스트림의 처음 몇 바이트를 확인한다.
- Content-Type 응답 헤더로는 콘텐츠 형식을 파악할 수 없는 경우가 있으므로, 확인 후 어떤 데이터 타입(HTML, Text, Image...)인지 확인한다.
- 이 단계에서 safe-brwosing의 검사가 실행된다. 도메인과 응답 데이터가 악성 사이트로 알려진 사이트와 일치한다면 네트워크 스레드는 경고 페이지를 표시하라고 알린다.
- 모든 검사가 끝나고 브라우저가 요청된 사이트로 이동해야 한다고 네트워크 스레드가 확신하게 되면 네트워크 스레드는 UI 스레드에 데이터가 준비되었음을 알린다.
4. 렌더러 프로세스 찾기
- 그러면 UI 스레드는 웹 페이지의 렌더링을 수행할 렌더러 프로세스를 찾는다.
- 브라우저 프로세스에서 렌더러 프로세스로 IPC(Inter Process Communication) 메시지를 전송한다.
- 또한 렌더러 프로세스가 데이터를 계속 수신할 수 있도록 브라우저 프로세스는 데이터 스트림을 전달한다.
렌더러 프로세스는 웹 콘텐츠를 처리한다. 렌더러 프로세스는 탭 내부에서 발생하는 모든 작업을 담당한다.
HTML, CSS, Javascript를 사용자와 상호작용할 수 있는 웹페이지로 변환하는 것이다.
렌더러 프로세스 작업은 크게 파싱과 합성으로 나눌 수 있다.
파싱
1. DOM 구축
- HTML 데이터를 수신하기 시작하면 렌더러 프로세스의 메인 스레드는 문자열을 파싱해서 DOM으로 변환한다.
- Javascript, CSS, Image 같은 리소스들은 네트워크나 캐시에서 로딩해야 한다. 속도를 높이기 위해 프리로드 스캐너가 메인 스레드와 동시에 실행된다. <img> <link> 같은 태그가 있으면 프리로드 스캐너는 HTML 파서가 생성한 토큰을 확인하고 브라우저 프로세스의 네트워크 스레드에 요청을 보낸다.
- HTML 파서는 <script> 태그를 만나면 HTML 문서의 파싱을 일시 중지한 다음 Javascript 코드를 로딩하고 파싱해 실행한다.
2. 스타일 계산
- 메인 스레드에서 CSS를 파싱하고 각 DOM 노드에 해당되는 계산된 스타일을 확정한다.
3. 레이아웃
- 레이아웃은 요소의 가하학적 속성을 찾는 과정으로, 메인 스레드는 DOM과 게산된 스타일을 훑어가며 레이아웃 트리를 만든다.
- 레이아웃 트리는 x, y, 박스 영역의 크기와 같은 정보를 가지고 있다. 레이아웃은 웹 페이지에 보이는 요소에 관련된 정보만 가지고 있다.
4. 페인트
- DOM, 스타일, 레이아웃을 가지고도 여전히 페이지를 렌더링할 수 없다. 그림을 하나 따라 그리려고 한다고 생각해 보자. 요소의 크기, 모양, 위치를 알더라도 어떤 순서로 그려야 할지 판단해야 한다.
- z-index와 같은 속성이 있을 때 HTML 순서대로 그리게 되면 안되므로 이러한 조정을 해주는 것이 페인트 작업이다.
합성
브라우저에서 문서의 구조와 각 요소의 스타일, 요소의 기하학적 속성, 페인트 순서 정보를 화면의 픽셀로 변환하는 작업을 '래스터화'라고 한다.
합성은 웹 페이지의 각 부분을 레이어로 분리해 별도로 래스터화하고 컴포짙너 스레드라고 하는 별도의 스레드에서 웹 페이지로 합성하는 기술이다.
어떤 요소가 어떤 레이어에 있어야 하는지 확인하기 위해 메인 스레드는 레이아웃 트리를 순회하며 레이어 트리를 만든다.
레이어 트리가 생성되고 순서가 결정되면 메인 스레드가 해당 정보를 컴포지터 스레드에 넘긴다. 그러면 컴포지터 스레드는 각 레이어를 래스터화한다.
그래서 컴포지터 스레드는 레이어를 타일 형태로 나눠 각 타일을 래스터 스레드로 보낸다. 레스트 스레드는 각 타일을 래스터화해 GPU 메모리에 저장한다.
참고 자료
https://www.html5rocks.com/en/tutorials/internals/howbrowserswork/
https://developers.google.com/web/resources/contributors/kosamari
더 알아보기
'CS' 카테고리의 다른 글
컴퓨터 내부의 언어 체계 (0) | 2021.07.06 |
---|