제목 날짜 내용 발행일 23.03.16
해당 포스트는 브라우저에 대해 학습한 내용을 정리하며 기록한 내용입니다.
프론트엔드 개발자라면 단순히 코드 개발을 하는 것을 뛰어넘어 브라우저가 어떻게 동작하는지, 어떻게 렌더링을 수행하는 지 아는 것이 굉장히 중요하다고 생각한다. 결국 코드는 브라우저라는 소프트웨어 프로그램상에서 수행되기 때문이다. 아무리 잘 짜인 코드라도 그 코드가 수행될 프로그램의 동작 방식에 대해 이해하지 못한다면, 코드가 의도한 대로 퍼포먼스를 내기란 어려울 것이다.
따라서 이번 시간에는 브라우저가 무엇인지, 웹이 어떻게 동작하는지 알아보자.
브라우저는 웹 서버에서 양방향으로 통신
HTML 문서 및 그림, 멀티미디어(ex. 동영상) 등의 컨텐츠를 열람할 수 있게 해주는 GUI 기반의 소프트웨어 프로그램
브라우저는 페이지를 다운로드 하기 위해 응용 계층의 대표적인 프로토콜인 HTTP를 통해 송수신
브라우저상에서 제공되는 웹(Web)은 월드 와이드 웹(World Wide Web)이 풀 네임
인터넷상에서 텍스트나 그림, 소리, 영상 등과 같은 멀티미디어 정보를 하이퍼텍스트(hypertext) 방식으로 연결해 제공
HTML 언어를 사용하여 작성된 문서 형태로 제공
-서로 관련된 내용으로 작성된 웹 페이지들의 집합을 웹 사이트(Web Site)라고 부릅니다.
모자이크(Mosaic)
, 넷스케이프(Netscape)
, 크롬(Chrome)
브라우저최초의 웹 브라우저는 1993년 미국 일리노이 대학에 다니던 마크 안드레센과 에릭 비나가 개발한 모자이크(Mosaic)
이며, 시간이 지나 1994년에 상업용 브라우저인 넷스케이프 내비게이터
가 등장
이를 기점으로 하여 웹 브라우저의 편리한 사용성을 인식한 인터넷 사용자가 폭발적으로 증가했고 웹의 대중화가 시작했다.
현재에 이르러 웹 브라우저는 다양하게 존재하며, 가장 많은 지분을 차지하는 것은 구글에서 개발한 크롬 브라우저
다.
브라우저는 현존하는 브라우저끼리 조금씩 그 특징이 다르지만, 공통점이 하나 있다. 그것은 바로 동작 방식
이다.
Resource
)를 서버에 요청(Request
)Response
)을 브라우저에 띄우는(Rendering
) 방식으로 동작여기서 자원은 대개 HTML 문서이지만 가끔 PDF, 멀티미디어 등 다른 형태일 수 있다.
자원의 주소는 URI(Uniform Resource Identifier)로 되어 있다.
밑에는 웹 브라우저가 웹 사이트에 접속하여 웹 페이지를 가져오는 과정을 도식화한 그림
- 사용자가 웹 브라우저를 통해 찾고 싶은 웹 페이지의 URL 주소를 입력
- DNS 서버에서 사용자가 입력한 URL 주소 중 도메인 네임을 검색
- 해당 도메인 네임에 해당하는 IP 주소를 찾아 사용자가 입력한 URL 정보와 함께 전달
이렇게 웹 페이지 URL 정보와 전달받은 IP 주소는
- HTTP 프로토콜을 사용해 HTTP 요청 메시지를 생성
- TCP 프로토콜을 사용해 인터넷을 거쳐 해당 IP 컴퓨터로 전송
- 이 요청 메시지는 다시 HTTP 프로토콜을 통해 웹 페이지 URL 정보로 변환
- 웹 서버는 이 변환이 된 정보에 해당하는 데이터를 검색하여 찾아냄
- HTTP 프로토콜을 통해 HTTP 응답 메시지를 생성
- 이 메시지는 다시 TCP 프로토콜을 이용해 인터넷을 거쳐 사용자의 컴퓨터로 전송
- 사용자의 컴퓨터에 도착한 HTTP 응답 메시지는 HTTP 프로토콜을 사용해 웹 페이지 데이터로 변환
- 변환된 데이터는 웹 브라우저 상에 출력되어 사용자가 볼 수 있게 된다.
브라우저는 각기 그 모양이 조금씩 다르지만 모두 기본적인 구조를 가지고 있다.
아래는 브라우저의 구조를 간단하게 도식화한 그림.
UI
라고도 부르며, 가장 유저와 밀접하게 맞닿아있는 부분
주소 표시줄, 이전/다음 버튼, 북마크 메뉴 등에 관련된 GUI 부분을 통칭
사용자 인터페이스와 렌더링 엔진 사이의 동작을 제어
브라우저 엔진의 주된 역할은
HTML 문서와 기타 자원의 웹페이지를 사용자의 장치에 시각 표현으로 변환
문서 객체 모델(DOM) 자료 구조를 구현
레이아웃 엔진(Layout Engine)라고도 부름
렌더링 엔진(Rendering Engine)과 밀접한 연관이 있어 보통은 브라우저 엔진과 렌더링 엔진을 묶어 브라우저 엔진으로 부르나 여기서는 구분해서 표현
브라우저 엔진은 웹 브라우저 마다 전용 엔진을 사용하고 있다. 밑의 표에서 설명한 브라우저 엔진 외에도 다양한 엔진이 있다.
이름 | 설명 |
---|---|
게코(Gecko) | 모질라 재단에서 만든 브라우저 엔진. 파이어폭스가 해당 엔진을 탑재하고 있는 유명한 웹 브라우저 |
웹킷(Webkit) | KHTML에서 파생된 브라우저 엔진. 사파리가 해당 엔진을 탑재하고 있는 가장 유명한 웹 브라우저 |
블링크(Blink) | 웹킷(Webkit)에서 파생된 브라우저 엔진. 크롬, 오페라가 해당 엔진을 탑재하고 있는 유명한 웹 브라우저 |
트라이던트(Trident) | 마이크로소프트의 브라우저 엔진. 인터넷 익스플로러, 아웃룩 익스프레스, 마이크로소프트 아웃룩 등이 이를 탑재하고 있다. |
엣지HTML(EdgeHTML) | 트라이던트(Trident)에서 파생된 브라우저 엔진. 마이크로소프트 엣지 스파르탄 버전(~2019)까지 탑재되었다. (현재는 블링크로 교체.) |
[표] 유명한 브라우저 엔진. 이 외에도 많은 브라우저 엔진이 존재하고 있습니다.
요청한 콘텐츠를 화면에 출력하는 역할
HTML, CSS 등을 파싱해 최종적으로 화면에 그려줌
렌더링 엔진은 HTML 및 XML 문서와 이미지를 표시
위에서 기술한 브라우저 엔진과 밀접하게 결합되어 있으므로 보통은 하나의 엔진으로 보는 시각이 많다.
렌더링 엔진 또한 웹 브라우저마다 전용 엔진을 사용하고 있으나 엔진의 동작 원리는 공통된 부분이 많다.
HTTP 요청과 같은 네트워크 호출에 사용
보통 플랫폼의 독립적인 인터페이스이고 각 플랫폼의 하부에서 실행
현대의 웹 페이지는 이제 JavaScript와 떼려고 해도 뗄 수 없게 되었다.
JavaScript
는 코드를 위에서 아래로 한 줄씩 읽어 내려가는 방식으로 파싱(parsing
)하는 언어(Interpreted Language
)
JavaScript 코드를 해석하고 실행하는 자바스크립트 해석기(JavaScript Interpreter)가 필요에 의해 등장하게 되었다.
자바스크립트 엔진(JavaScript Engine)이라고도 부르는 자바스크립트 해석기는 여러 목적으로 사용이 되지만 대체로 웹 브라우저에서 이용이 되며, 브라우저마다 전용 엔진이 탑재되어 있다.
밑의 표에서 설명한 엔진 외에도 다양한 엔진이 있습니다.
이름 | 설명 |
---|---|
Rhino | 모질라 재단이 운영하는 오픈소스 엔진으로, 자바(Java)로 개발되었다는 특징 |
SpiderMonkey | 최초의 Javascript 엔진으로 넷스케이프 내비게이터를 지원하였으며, 현재는 파이어폭스를 지원 |
V8 | 구글이 개발한 오픈 소스 엔진으로 구글 크롬의 Javascript 엔진 |
JavascriptCore | 애플에서 개발하였으며 처음에 WebKit 프레임워크를 위해 개발되었지만 현재는 사파리와 React Native App를 지원 |
Chakra | 마이크로소프트가 개발한 엔진이며, Edge 브라우저를 지원 |
[표] 유명한 JavaScript 엔진. 이 외에에도 많은 JavaScript 엔진이 존재하고 있습니다.
이제부터 자바스크립트 엔진의 구조 중 메모리 구조를 가장 유명한 자바스크립트 엔진인 구글 크롬의 V8 엔진을 알아보자.
이 그림은 V8 엔진의 메모리 구조를 간단히 나타낸 그림
V8 엔진의 메모리 구조는 크게 Heap Memory
와 Call Stack
으로 구성
Heap Memory
와 Call Stack
에 대해 알아보도록 하자.
힙 메모리 내부에는 다양한 공간이 있다
복잡하기 때문에 여기서는 커다랗게 하나의 공간으로 되어있다고 생각
힙(heap)은 동적 메모리 할당에 사용되는 자료구조
힙을 이용하여 V8은 객체
또는 동적 데이터
를 저장
여기에 저장되는 메모리는 V8 엔진 내부에서 가장 큰 공간
을 차지
가비지 컬렉션
이 발생하는 곳
JavaScript는 기본적으로 싱글 스레드
기반의 언어
콜 스택이 하나라는 의미
콜 스택은 프로그램상에서 우리가 어디에 있는지 기록하는 자료구조
만약 함수를 실행한다면, 해당 함수는 콜 스택의 가장 상단
에 위치
이는 스택이 후입선출(LIFO)
이라는 구조로 되어 있기 때문
만약 함수의 실행이 끝난다면, 해당하는 함수는 콜 스택의 가장 상단에 있기 때문에 바로 제거할 수 있다.
콜 스택이 동작하는 방식을 가장 잘 볼 수 있는 예를 보면서 콜 스택을 이해해보도록 하자.
제일 먼저 printSquare(4)
가 호출
호출되는 순간 해당하는 함수가 스택으로 “push
”
함수 printSquare
내부에서는 다시 square(n)
을 호출
함수 square
를 이어 스택 안으로 push
그 뒤, 함수 square
내부에서도 multiply(n, n)
을 호출
함수 multiply
를 뒤이어 스택 안으로 push
이 과정에서는 return
문으로 함수 호출만 되고 return
되는 특정 값이 없어 쌓이기만 한다.
함수 multiply
까지 도착해서야 드디어 return
되는 특정한 값을 얻는다.
reuturn a * b;
이제 스택 안에서 return 되는 순서대로 stack을 제거해보자.
함수 multiply
와 함수 square
에서 차례대로 return
문의 결과를 얻는다.
스택 내부에서 차례대로 제거
여기까지가 printSquare(4)
를 호출하고함수 printSquare
, 함수 square
, 함수 multiply
까지 성공적으로 실행시킨 과정이다.
함수 printSquare
로 돌아오면, 함수 내부에서 실행시켜야 하는 메소드가 있다.
console.log(squared);
해당 메소드를 실행시킨 뒤, 함수가 완전히 종료되는 순간까지 보도록 하자.
함수 printSquare
내부에 console.log(sqaured)
가 있으므로, 해당 메소드를 실행하는 순간 스택 안에 console.log
스택이 쌓인다.
이어 console.log
의 실행이 끝나면 스택에서 제거
함수 printSquare
또한 실행이 완료되었으므로 스택에서 제거
이렇게 다시 스택이 완전히 비어있게 됩니다.
여기서 콜 스택에 쌓이는 데이터 하나하나를 스택 프레임(Stack Frame)이라고 부른다.
스택 내에 쌓이는 printSquare(4)
하나가 프레임 하나임을 의미
이 스택 프레임들은 동작 방식에서도 알 수 있듯 쌓이는 순서가 있기 때문에 콜 스택이 동작하는 방식을 안다면 스택의 추적 (Stack trace)
또한 가능해지게 된다.
그리고 콜 스택은 힙과는 달리 자료구조 자체가 크기에 제한이 있다.
따라서 한정된 메모리 공간을 넘어버리게 되면 어떠한 에러를 발생시키게 되는데 그것을 바로 스택 오버플로(Stack Overflow)라고 부른다.
개발하다 어떤 문제가 생겨 구글링하는 과정에서 익히 접했을 스택 오버플로라는 사이트의 이름도 여기서 유래된 것이라고 한다.
스택 오버플로는 콜 스택 내부의 동일한 스택 프레임이 예상치 못한 수로 쌓일 때 일어난다.
함수를 계속해서 호출하게 되면 스택 내부에 어떤 일이 일어날지 살펴보자.
함수 oops()
를 계속해서 호출하게 되면 스택 내부에 함수 oops()
가 계속해서 쌓이게 된다.
스택 내부에 동일한 스택 프레임이 계속 쌓이고 있고, 그림에서처럼 프레임이 어느 순간 스택의 크기(용량)을 넘어버리게 된다.
콜 스택의 제한된 크기를 스택 프레임이 넘어버리게 되면 웹 브라우저는 멈춰버리게 된다.
이는 유저 경험(UX)에도 좋지 못하므로, 개발하면서 해당 에러가 발생하지 않도록 주의를 기울여야 한다.
JavaScript를 다루다 보면 종종 웹 브라우저의 콘솔에 출력되는 에러 로그를 본 적이 있을 것이다.
해당 에러 로그를 자세히 살펴본다면 어디서 에러가 발생하고 있고, 에러의 결과가 무엇인지 아는 데에 매우 도움이 된다.
위의 그림에서 함수 baz()
는 함수 bar()
를 호출하고
bar()
는 foo()
함수를 호출하고 foo()
는 마지막으로 에러 메시지를 출력
이렇게 브라우저의 콘솔 로그를 살펴보면 에러의 발생과 발생한 이유를 훌륭하게 추적해낼 수 있다. 이것이 바로 스택 추적(Stack trace)라고 부른다.
Render Tree
를 브라우저에 그리는 역할을 담당Select
, Input
창과 같은 기본적인 위젯을 그려줌.
플랫폼에서 명시하지 않은 일반적인 인터페이스로, OS
사용자 인터페이스 체계를 사용
여기서 OS 사용자 인터페이스(user interface
)란 이전에 작성했던 UI/UX
의 UI
와 조금 다르다.
사용자 인터페이스, 또는 유저 인터페이스(user interface, UI)는
그렇기 때문에 거의 모든 운영체제는 사용자 인터페이스를 가지고 있으며, 이 인터페이스는 여러 형태를 가지고 있다.
이러한 종류의 인터페이스를 다룰 때는 특정한 명령 체계를 사용
명령어 라인 인터페이스(Command Line Interface, CLI)
일괄 처리 인터페이스(Batch Interface)
가장 일반적으로 사용되는 것은 그래픽 사용자 인터페이스 (Graphic User Interface, GUI)
자료를 저장하는 계층
쿠키를 저장하는 것과 같이 모든 자원을 하드 디스크에 저장할 필요가 있기 때문에 존재
HTML5 명세에는 브라우저가 지원하는 웹 저장소(Web Storage, 이하 웹 스토리지라고 지칭합니다.) 스펙이 정의되어 있다.
영구적인 저장소인 로컬 스토리지(localStorage)
와 임시적인 저장소인 세션 스토리지(sesseionStorage)
를 따로 두어 데이터의 지속성을 구분할 수 있다
HTML5 이전에는 응용 프로그램이 데이터에 서버를 요청할 때마다 매번 쿠키(Cookie)라는 곳에 그 정보를 저장
쿠키 자체의 보안상 취약과 더불어 저장소의 절대적인 허용 용량의 적음으로 다른 대안을 찾게 되었고, 이윽고 웹 스토리지(Web Storage)가 나오게 되었다.
웹 스토리지는
웹 브라우저가 직접 데이터를 저장
사용자 측에서 좀 더 많은 양의 정보를 안전하게 저장
서버로 전송되지 않으므로 저장된 데이터가 클라이언트에만 존재하기 때문에 네트워크 트래픽 비용 또한 줄여준다는 특징 또한 가지고 있다.
웹 스토리지는 오리진(origin)마다 단 하나씩만 존재
웹 스토리지는 사용하기 전에 사용자의 웹 브라우저 버전이 이를 지원하는지 먼저 확인을 해봐야 한다.
웹 스토리지는 데이터의 지속성과 관련해 두 가지 용도의 저장소 객체를 제공
로컬 스토리지 객체는 보관 기한이 없는 데이터를 저장
브라우저 탭이 닫히거나, 컴퓨터를 재부팅해도 이 저장소에 저장된 데이터는 사라지지 않는다.
Windows 전역 객체의 localStorage라는 컬렉션을 통해 저장과 조회가 가능
도메인 마다 별도의 localStorage가 생성
도메인만 같으면 전역으로 데이터의 공유가 가능
세션 스토리지 객체는 하나의 세션만을 위한 데이터를 저장
데이터를 지속적으로 보관하지 않고 브라우징되고 있는 브라우저 컨텍스트 내에서만 데이터가 유지
브라우징이란 브라우저 프로그램을 실행해서 인터넷에 들어가 필요한 정보를 찾는 행위
브라우저 컨텍스트란 브라우저가 문서를 표시하는 환경을 말함
저장과 조회는 Windows 전역 객체의 sessionStorage라는 컬렉션을 통해 이루어짐
도메인별로 별도로 생성
여기서 알아둬야 할 점은 브라우저 컨텍스트가 다르면 서로 다른 영역이 된다는 특징이 있다.
버전이 다르면 웹 스토리지를 사용할 수 없기 때문에 반드시 꼭 확인해야 한다.
웹 스토리지를 사용하기 위한 문법
객체
를 제공합니다.window.localStorage
:
window.sessionStorage
:
//window 객체에 있는 Storage 객체를 통해 확인할 수 있다.
//해당 객체가 존재하지 않는 브라우저라면 `undefined`를 반환하고, 존재한다면 객체를 반환
if (typeof(Storage) !== "undefined") {
// web storage를 위한 코드 부분
} else {
// web storage를 지원하지 않는 브라우저를 위한 안내 부분
}
해당 코드는 웹 스토리지를 사용하기 이전에 해당 브라우저의 버전이 웹 스토리지를 지원하는지 확인하고자 할 때 쓰이는 코드
웹 스토리지가 존재하는지 확인을 한 다음
웹 스토리지에 무엇을 저장할지 결정하여 조건문 안에 작성합니다.
웹 스토리지를 활용한 대표적인 기능은 다양하게 존재
브라우저 컨텍스트 내에서 저장한 데이터를 가지고 활용할 수 있기 때문에
복구 및 백업에 관련된 기능에 주로 사용
블로그 글을 작성하다가 사용자가 창을 벗어난 경우 관련 작성 내용을 복구하거나 백업해주는 기능
사용자가 입력 form을 통해 정보를 입력하다 페이지에서 벗어난 경우 복구 및 백업해주는 기능
현재 읽은 글의 히스토리 저장(카운팅, 혹은 읽은 글 표시 등으로 활용)