사용자 인터페이스와 렌더링 엔진 사이의 동작을 제어합니다. 브라우저 엔진의 주된 역할은 HTML 문서와 기타 자원의 웹페이지를 사용자의 장치에 시각 표현으로 변환시키며, 문서 객체 모델(DOM) 자료 구조를 구현합니다.
레이아웃 엔진(Layout Engine)라고도 부르며, 렌더링 엔진(Rendering Engine)과 밀접한 연관이 있어 보통은 브라우저 엔진과 렌더링 엔진을 묶어 브라우저 엔진으로 부르나 여기서는 구분해서 표현합니다.
이러한 브라우저 엔진은 웹 브라우저 마다 전용 엔진을 사용하고 있습니다. 대표적인 엔진은 다음과 같습니다.
요청한 콘텐츠를 화면에 출력하는 역할을 합니다. HTML, CSS 등을 파싱해 최종적으로 화면에 그려주며, 렌더링 엔진은 HTML 및 XML 문서와 이미지를 표시할 수 있습니다. (물론 플러그인이나 브라우저 확장 기능을 이용해 PDF와 같은 다른 유형도 표시할 수 있습니다.)
위에서 기술한 브라우저 엔진과 밀접하게 결합되어 있으므로 보통은 하나의 엔진으로 보는 시각이 많습니다. 렌더링 엔진 또한 웹 브라우저 마다 전용 엔진을 사용하고 있으나 엔진의 동작 원리는 공통된 부분이 많습니다. 렌더링 엔진의 동작 원리는 이후 브라우저 렌더링 챕터에서 상세히 다룰 것입니다.
JavaScript는 코드를 위에서 아래로 한 줄씩 읽어내려가는 방식으로 파싱(parsing)하는 언어(Interpreted Language)입니다. 따라서 JavaScript 코드를 해석하고 실행하는 자바스크립트 해석기(JavaScript Interpreter)가 필요에 의해 등장하게 되었습니다.
자바스크립트 엔진(JavaScript Engine)이라고도 부르는 자바스크립트 해석기는 여러 목적으로 사용이 되지만 대체적으로 웹 브라우저에서 이용이 되며, 브라우저마다 전용 엔진이 탑재되어 있습니다. 대표적인 자바스크립트 엔진은 다음과 같습니다.
가장 많이 사용되고 있는 크롬의 V8엔진에 대해서 알아보겠습니다.
힙(heap)은 동적 메모리 할당에 사용되는 자료구조입니다. 이 힙을 이용하여 V8은 객체 또는 동적 데이터를 저장합니다. 여기에 저장되는 메모리는 V8 엔진 내부에서 가장 큰 공간을 차지하고 있습니다.
JavaScript는 기본적으로 싱글 스레드 기반의 언어입니다. 콜 스택이 하나라는 의미이며, 한 번에 한 작업만 사용할 수 있습니다. 콜 스택은 프로그램 상에서 우리가 어디에 있는지 기록하는 자료구조입니다. 만약 함수를 실행한다면, 해당 함수는 콜 스택의 가장 상단에 위치합니다. 이는 스택이 후입선출(LIFO)이라는 구조를 가지고 있기 때문에 일어나는 일입니다. 만약 함수의 실행이 끝난다면, 해당하는 함수는 콜 스택의 가장 상단에 위치하고 있기 때문에 바로 제거할 수 있습니다.
콜 스택에 쌓이는 데이터 하나 하나를 스택 프레임(Stack Frame)이라고 부릅니다. 스택 내에 쌓이는 printSquare(4) 하나가 프레임 하나임을 의미합니다. 이 스택 프레임들은 동작 방식에서도 알 수 있듯 쌓이는 순서가 있기 때문에 콜 스택이 동작하는 방식을 안다면 스택의 추적 (Stack trace) 또한 가능해지게 됩니다.
콜 스택은 힙과는 달리 자료구조 자체가 크기에 제한이 있습니다. 스택 오버플로는 콜 스택 내부의 동일한 스택 프레임이 예상치 못한 수로 쌓일 때 일어납니다. 함수를 계속해서 호출하게 되면 스택 내부에 어떤 일이 일어날지 살펴보겠습니다
함수 oops()를 계속해서 호출하게 되면 스택 내부에 함수 oops() 가 계속해서 쌓이게 됩니다. 스택 내부에 동일한 스택 프레임이 계속 쌓이고 있고, 그림에서처럼 프레임이 어느 순간 스택의 크기(용량)을 넘어버리게 됩니다. 콜 스택의 제한된 크기를 스택 프레임이 넘어버리게 되면 웹 브라우저는 멈춰버리게 됩니다. 이는 유저 경험(UX)에도 좋지 못하므로, 개발하면서 해당 에러가 발생하지 않도록 주의를 기울여야 할 것입니다.
JavaScript를 다루다보면 종종 웹 브라우저의 콘솔에 출력되는 에러 로그를 본 적이 있을 것입니다. 해당 에러 로그를 자세히 살펴본다면 어디서 에러가 발생하고 있고, 에러의 결과가 무엇인지 아는 데에 매우 도움이 됩니다.
렌더링 엔진이 분석한 Render Tree를 브라우저에 그리는 역할을 담당합니다. Select, Input 창과 같은 기본적인 위젯을 그려줍니다. 플랫폼에서 명시하지 않은 일반적인 인터페이스로, OS 사용자 인터페이스 체계를 사용합니다.
말 그대로 자료를 저장하는 계층입니다. 쿠키를 저장하는 것과 같이 모든 자원을 하드 디스크에 저장할 필요가 있기 때문에 존재하고 있습니다. HTML5 명세에는 브라우저가 지원하는 웹 저장소(Web Storage, 이하 웹 스토리지라고 지칭합니다.) 스펙이 정의되어 있습니다. 영구적인 저장소인 로컬스토리지(localStorage)와 임시적인 저장소인 세션스토리지(sesseionStorage)를 따로 두어 데이터의 지속성을 구분할 수 있어 응용 환경에 맞는 선택이 가능해집니다.
HTML5 이전에는 응용 프로그램이 데이터에 서버를 요청할 때마다 매번 쿠키(Cookie)라는 곳에 그 정보를 저장해왔습니다. 그러나 쿠키 자체의 보안상 취약과 더불어 저장소의 절대적인 허용 용량의 적음으로 다른 대안을 찾게 되었고, 이윽고 웹 스토리지(Web Storage)가 나오게 되었습니다.
웹 스토리지는 웹 브라우저가 직접 데이터를 저장할 수 있게 해줍니다. 또한 웹 스토리지는 사용자 측에서 좀 더 많은 양의 정보를 안전하게 저장할 수 있게 해줍니다. 이런 모든 정보는 절대 서버로 전송되지 않으므로 저장된 데이터가 클라이언트에만 존재하기 때문에 네트워크 트래픽 비용 또한 줄여준다는 특징 또한 가지고 있습니다.
이러한 웹 스토리지는 오리진(origin)마다 단 하나씩만 존재합니다. 오리진(origin)은 도메인(domain)과 프로토콜(protocol) 한 쌍으로 이루어진 식별자로, 하나의 오리진에 속하는 모든 웹 페이지는 같은 데이터를 저장하기 때문에 같은 데이터에 접근할 수 있게 됩니다.
로컬스토리지 객체는 보관 기한이 없는 데이터를 저장합니다. 따라서 브라우저 탭이 닫히거나, 컴퓨터를 재부팅해도 이 저장소에 저장된 데이터는 사라지지 않습니다. Windows 전역 객체의 localStorage라는 컬렉션을 통해 저장과 조회가 가능하며, 도메인 마다 별도의 localStorage가 생성됩니다. 따라서 도메인만 같으면 전역으로 데이터의 공유가 가능해집니다.
세션 스토리지 객체는 하나의 세션만을 위한 데이터를 저장합니다. 데이터를 지속적으로 보관하지 않고 브라우징되고 있는 브라우저 컨텍스트 내에서만 데이터가 유지되기 때문에, 사용자가 브라우저 탭이나 창을 닫으면 이 객체에 저장된 데이터는 사라집니다. 브라우징이란 브라우저 프로그램을 실행해서 인터넷에 들어가 필요한 정보를 찾는 행위를 말하며, 브라우저 컨텍스트란 브라우저가 문서를 표시하는 환경을 말합니다. 각 브라우징 컨텍스트는 특정 출처 및 활성화되고 있는 문서의 출처, 표시했던 모든 문서의 방문기록을 가지고 있습니다.
저장과 조회는 Windows 전역 객체의 sessionStorage라는 컬렉션을 통해 이루어지며, 도메인 별로 별도로 생성됩니다. 여기서 알아둬야 할 점은 브라우저 컨텍스트가 다르면 서로 다른 영역이 된다는 특징이 있습니다. 즉, 브라우저 두 개를 실행해 같은 페이지를 열었을 때, 브라우저의 컨텍스트가 서로 다르므로 이 두 페이지의 sessionStorage는 각 별개의 영역으로 인지되어 서로 데이터의 공유가 불가능해집니다.
이번에는 웹 스토리지를 사용하기 위한 문법을 알아봅시다. 웹 스토리지는 클라이언트에 데이터를 저장하기 위한 두 가지 객체를 제공합니다.
웹 스토리지를 활용한 대표적인 기능은 다양하게 존재합니다. 먼저, 브라우저 컨텍스트 내에서 저장한 데이터를 가지고 활용할 수 있기 때문에 복구 및 백업에 관련된 기능에 주로 사용이 됩니다.