Today I Learned
- 브라우저
- 반응형 웹
웹 서버에서 양방향으로 통신하며 HTML 문서, 그림 등의 컨텐츠를 열람할 수 있게 해주는 GUI 기반의 소프트웨어 프로그램이다. 크롬, 파이어폭스, 사파리 등 다양한 웹 브라우저가 존재한다.
사용자가 선택한 자원
을 서버에 요청
하고, 서버의 응답
을 브라우저에 띄우는 방식
IP 주소
를 찾아 사용자가 입력한 URL 정보와 함께 전달한다.HTTP 요청 메시지
를 생성한다.HTTP 응답 메시지
를 생성한다.사용자 인터페이스와 렌더링 엔진 사이의 동작을 제어하는 역할로, HTML 문서와 기타 자원의 웹 페이지를 사용자의 장치에 시각 표현으로 변환
시키고, 문서 객체 모델(DOM) 자료 구조를 구현
한다.
브라우저 엔진은 렌더링 엔진과 묶어 브라우저 엔진이라고 부르기도 한다. 웹 브라우저마다 전용 브라우저 엔진을 사용하고 있다.
요청한 콘텐츠를 화면에 출력하는 역할로, HTML, CSS 등을 파싱해 최종적으로 화면에 그린다
. 렌더링 엔진 역시 웹 브라우저마다 전용 렌더링 엔진을 사용한다.
HTTP 요청과 같은 네트워크 호출에 사용된다.
자바스크립트 코드를 해석하고 실행한다. 자바스크립트 엔진(JavaScript Engine)
이라고도 하며, 브라우저마다 전용 엔진이 있다. 그 중 가장 유명한 것이 크롬의 V8 엔진이다.
V8 엔진을 통해 자바스크립트 엔진의 메모리 구조를 알아보자. V8 엔진의 메모리 구조는 크게 힙 메모리
와 콜 스택
으로 구성돼있다.
힙 메모리 (Heap Memory)
힙(heap)은 동적 메모리 할당에 사용되는 자료구조이다. V8 엔진은 힙을 이용해 객체 또는 동적 데이터를 저장한다.
콜 스택 (Call Stack)
콜 스택은 프로그램상에서 우리가 어디에 있는지 기록하는 자료구조이다. 함수를 실행하면 콜 스택의 최상단에 쌓이고 실행 완료 후엔 콜스택에서 제거되는, 후입선출(LIFO)의 구조이다.
콜 스택은 힙과는 달리 자료구조 자체가 크기에 제한이 있어서 한정된 메모리 공간을 넘기면 에러를 일으키는데, 이 경우를 스택 오버플로(Stack Overflow)
라고 한다.
렌더링 엔진이 분석한 Render Tree를 브라우저에 그리는(paint) 역할로, Select, Input 창과 같은 기본적인 위젯을 그려준다.
자료를 저장하는 계층으로, 브라우저는 웹 스토리지(Web Storage)
를 지원한다. HTML5 이전에는 서버에 데이터를 요청할 때마다 매번 쿠키(Cookie)
에 정보를 저장했지만 쿠키에는 보안상 취약점과 용량적인 한계가 있어 웹 스토리지(Web Storage)가 그 대안으로 등장했다.
클라이언트에서 웹 스토리지에 직접 데이터를 저장할 수 있고, 웹 스토리지에 저장된 데이터는 서버로 전송되지 않고 클라이언트에만 존재한다. 이런 웹 스토리지는 오리진(origin)마다 하나씩만 존재한다.
웹 스토리지는 브라우저 컨텍스트 내에서 저장한 데이터를 활용할 수 있기 때문에 복구 또는 백업 관련 기능에 주로 활용된다. 사용자가 글이나 폼을 작성하다 실수로 페이지에서 벗어난 경우에 내용을 복구/백업해주거나 현재 읽은 글을 표시해주는 기능 등으로 활용할 수 있다.
웹 스토리지는 영구적인 저장소인 로컬 스토리지(Local Storage)
와 임시적인 저장소인 세션 스토리지(Session Storage)
로 나뉘어 데이터의 지속성을 구분한다.
로컬 스토리지 (Local Storage)
보관 기한이 없는 데이터를 저장한다. 브라우저 탭을 닫거나 컴퓨터를 재부팅 해도 로컬 스토리지에 저장된 데이터는 사라지지 않는다. 도메인 마다 별도의 로컬 스토리지가 생성돼, 도메인이 같으면 전역으로 데이터를 공유할 수 있다.
세션 스토리지 (Session Storage)
로컬 스토리지와 달리, 데이터를 영구적으로 보관하지 않으므로 브라우저 탭을 닫으면 세션 스토리지에 저장된 데이터는 사라진다. 세션 스토리지도 도메인 마다 별도의 세션 스토리지가 생성되지만, 브라우저 컨텍스트가 다르면 서로 다른 영역이 된다. 브라우저 두 개를 실행해 같은 페이지를 열었을 때, 브라우저의 컨텍스트가 서로 다르므로 이 두 페이지의 세션 스토리지는 각각 별개의 영역으로 인지돼 서로 데이터 공유를 할 수 없다.
로컬 스토리지와 세션 스토리지는 각각
window.localStorage
,window.sessionStorage
로 접근할 수 있다. 하지만 버전이 다르면 웹 스토리지를 사용할 수 없기 때문에 꼭 확인해야 한다. 예를 들어 아래와 같이 웹 스토리지를 쓰기 전에 해당 브라우저의 버전이 웹 스토리지를 지원하는지 확인할 수 있다.if(typeof(window.Storage) !== "undefined") { // 웹 스토리지를 지원하는 브라우저의 코드 } else { // 웹 스토리지를 지원하지 않는 브라우저를 위한 안내 코드 }
브라우저의 렌더링 엔진이 렌더링을 수행하며, 렌더링은 HTML, CSS, JavaScript 등이 브라우저에서 출력되는 과정을 뜻한다. 렌더링이 이루어지는 과정을 알아보자.
레이아웃은 Render Tree를 기반으로 HTML 요소의 위치 및 크기 등을 계산해 어떻게 화면에 배치할지를 결정하는 과정이다. 렌더링 엔진이 Render Tree를 위에서 아래로 읽으며 이를 계산 및 파악하며, 모든 값은 절대적인 단위인 px 값으로 변환된다.
레이아웃에서 결정된 대로 브라우저가 실제 화면에 그림을 그리는 과정을 페인팅이라고 한다.
사용자가 웹 페이지 이동을 하거나 화면을 조정하는 등의 인터렉션을 유발했을 때, 화면에 있는 요소들은 추가 및 삭제되거나 스타일이 변경 되는데 이렇게 화면에 변경되는 모습을 반영해 보여주기 위해서는 모든 요소의 위치와 크기를 다시 계산하고, 다시 그려서 보여줘야 한다.
이렇게 웹 인터렉션으로 인해 레이아웃을 반복해 수행하는 것을 리플로우
, 페인트 과정을 반복해 수행하는 것을 리페인트
라고 한다.
DOM 조작은 리플로우, 리페인트가 일어나는 대표적인 예시이다. DOM은 변경되면 Render Tree를 다시 만들기 때문에 변경될 때마다 리플로우와 리페인트가 발생한다. 리플로우는 배치를 위한 연산을 다시 하는데 이는 CPU를 많이 차지하는 작업이 리페인트 또한 다시 화면을 그리는 작업으로 GPU를 많이 차지한다. 그러므로 과도한 리플로우와 리페인트가 발생하면 프레임 드랍(Frame Drop), 즉 사용자가 화면이 버벅인다거나 멈춘다고 느끼는 경험을 할 수 있다. 때문에 최적화를 고려해야 한다.
CSSOM Tree의 CSS 속성 중 레이아웃을 발생시키는 속성들이 있다. 해당 속성을 사용하면 그때마다 변경이 돼 Render Tree를 만들고, 레이아웃, 페인트를 하는 과정이 연속적으로 발생한다. 이런 속성을 피하면 해당 과정이 발생하는 횟수를 줄일 수 있다.
리플로우가 일어나는 대표적인 CSS 속성
position, width, height, left, top, right, bottom,
margin, padding, border, border-width, clear,
display, float, font-family, font-size, font-weight, line-height,
min-height, overflow, text-align, vertival-align 등등
애니메이션을 만들 때, 위치 이동을 위해 위의 속성 대신 transform
의 translate
을 사용하면 레이아웃을 발생시키지 않고 페인트만 발생시켜 최적화에 도움이 된다.
리페인트가 일어나는 대표적인 CSS 속성
background, background-image, background-position, background-repeat, background-size,
border-radius, border-style, box-shadow, color, line-style, outline, outline-color, clear,
display, float, font-family, font-size, font-weihgt, visibility 등등
visibility
나 display
보다 리페인트가 일어나지 않게 해주는 opacity
를 사용하면 성능 개선에 도움이 된다.
JavaScript와 CSS를 조합한 애니메이션이 많거나 레이아웃 변화가 많은 경우 position
을 absolute
나 fixed
로 사용하면 영향을 받는 주변 노드들을 줄여줄 수 있다. fixed
같이 영향을 받는 노드가 전혀 없는 경우 리플로우 과정을 거치지 않고 리페인트만 발생하여 최적화에 도움이 된다.
스크린 크기 및 디바이스의 종류에 따른 브라우저 크기에 맞춰 유동적으로 웹 사이트의 레이아웃이 변하도록 하는 것을 반응형 웹 디자인이라고 한다.
1. 효율적인 유지보수
하나의 소스 코드로 만들어진 어플리케이션이기 때문에, 하나의 소스만 수정하면 모든 스크린 사이즈에 맞춰 컨텐츠가 최적화 되기 때문에 유지보수에 효율적이다.
2. 검색엔진 최적화(SEO)에 유리
PC용, 모바일용 URL을 따로 갖지 않고 하나의 URL을 가지기 때문에 SEO에 유리하다.
1. 사이트 속도 저하
여러 브라우저 크기에 대응해야하는 만큼 그에 따라 읽어 들어야 할 소스가 많아지기 때문에 불필요하게 많은 데이터를 소비해 반응형 웹이 아닌 사이트에 비해 성능이 저하될 수 있다.
2. 호환성 문제
웹 브라우저의 스펙, 사양이 각기 다르기 때문에 특정 브라우저에서 사용이 불가능하다던가(익스플로러 8버전 이하...) 웹 브라우저마다 화면이 다르게 반영되는 등 100% 맞춤 디자인이 어렵다는 단점이 있다.
<link>
태그에 media
속성을 사용해 조건을 지정하면 media
속성 내 해당 조건을 만족할 때에만 해당 CSS 파일을 불러온다.<link href="style.css" media="screen and (min-width: 400px) and (max-width: 1000px)" rel="stylesheet">
<styles>
태그에 media
속성을 사용해 조건을 지정하면 media
속성 내 해당 조건을 만족할 때에만 해당 스타일을 적용하게 된다.<style type="text/css" media="screen and (min-width: 400px) and (max-width: 1000px)">
/* css를 작성 */
</style>
@media 미디어 타입 (조건) {
해당 조건에서 적용할 css
}
@media screen (max-width: 400px) {
body {
color: black;
}
}
- 미디어 타입
all
(모든 미디어 타입), print
(프린터), screen
(컴퓨터 화면), speech
(스크린 리더)
이 외에도 다양한 타입이 있지만 실무에서 자주 쓰는 타입은 all, print, screen, 그 중에서도 screen이 대부분이다.
- 조건
min-width
, max-width
, width
: 뷰포트가 특정 너비 이상 또는 이하인 경우 CSS 적용
/* width가 400px보다 좁은 경우, body color를 blue로 변경 */
@media screen and (max-width: 400px) {
body {
color: blue;
}
}
orientation
: 세로 모드인지 가로 모드인지 검사하여 CSS 스타일을 주고싶은 경우
/* 장치가 가로 방향인 경우, body color를 black으로 변경 */
@media (orientation: landscape) {
body {
color: black;
}
}
논리곱(and)
, 논리합(or)
, 부정(not)
을 결합해 복합적인 조건의 미디어 쿼리를 사용할 수도 있다.
/* width가 400px 이상이고 장치가 가로 방향인 경우 */
@media screen and (min-width: 400px) and (orientation: landscape) {
body {
color: blue;
}
}
/* width가 400px 이상이거나 장치가 가로 방향인 경우 */
@media screen and (min-width: 600px), screen and (orientation: landscape) {
body {
color: blue;
}
}
/* 장치가 세로인 경우 */
@media not all and (orientation: landscape) {
body {
color: blue;
}
}