💡 이번에 배운 내용
- Section4. 사람과 기계가 모두 쉽고 빠르게 접근 가능한 Web App을 만들 수 있다.
- Unit2. HTML/CSS 심화: 브라우저의 동작방식에 대해서 학습하고, 반응형 웹, CSS 애니메이션, Canvas에 대해 학습한다.
CSS 애니메이션과 canvas 실습은 재미있었다. 그런데 브라우저의 렌더링 방식과 각 구성요소들에 대한 설명은 이해하기 쉽지 않고 양도 많아서 블로깅 하는데 애를 먹었다. 아무리 정리해도 정리가 안돼! 결국 다음날이 되서야 이렇게 정리를 완료한다.
이번에는 실습과 개념 둘 다 잡은 단원이라 어느 하나 소홀히 할 수 없었다.
이렇게 정리해놓은 것이 나중 복습 때 큰 도움 되길 바라며!
브라우저 엔진, 렌더링 엔진, 자바스크립트 해석기, 콜 스택 call stack, 웹 저장소 web storage, 로컬스토리지 localStorage, 세션스토리지 sessionStorage, UI 백엔드, DOM, 파싱 parsing, 파서 parser, CSSOM, render, 레이아웃, Paint, 리플로우, 리페인트, 최적화, 반응형 웹, 미디어 쿼리, CSS animation, keyframe, canvas
브라우저는 사용자가 요청한 자원(Resource)을 서버에 요청(Request)하고,
서버는 URI로 된 자원의 주소를 참고하여 응답(Response)을 보낸다.
브라우저는 이 전달받은 응답으로 브라우저에 렌더링(Rendering)한다.
그 과정을 정리하자면 다음과 같다.
그림을 보면 브라우저의 구조는 다음과 같다.
이 각 요소에 대해 자세히 살펴본다.
UI이라고도 부르며, 렌더링된 화면을 제외한 주소 표시줄, 이전/다음 버튼, 북마크 메뉴 등의 GUI 부분을 의미한다.
다른 말로 레이아웃 엔진이라고도 하며 사용자 인터페이스와 렌더링 엔진 사이의 동작을 제어한다.
주로 HTML 문서와 기타 자원의 웹페이지를 사용자의 장치에 시각적으로 표현하며,
DOM 자료 구조를 구현한다.
이 브라우저 엔진은 웹 브라우저 마다 다른 전용 엔진을 사용하기 때문에 그 종류가 아래와 같이 다양하다.
이름 | 대표 브라우저 | 설명 |
---|---|---|
게코(Gecko) | 파이어폭스 | 모질라 재단에서 만듦 |
웹킷(Webkit) | 사파리 | KHTML에서 파생됨 |
블링크(Blink) | 크롬, 오페라 | 웹킷(Webkit)에서 파생됨 |
트라이던트(Trident) | 인터넷 익스플로러, 아웃룩 익스프레스, 마이크로소프트 아웃룩 | 마이크로소프트에서 만듦 |
엣지HTML(EdgeHTML) | 마이크로소프트 엣지 스파르탄 버전(~2019) (현재는 블링크로 교체.) | 트라이던트(Trident)에서 파생됨 |
요청한 콘텐츠를 화면에 출력한다.
HTML, CSS 등을 파싱해 최종적으로 화면에 렌더링하며,HTML 및 XML 문서와 이미지를 표시할 수 있다.
렌더링 엔진의 동작 원리는 이후 브라우저 렌더링 챕터에서 상세히 다룰 예정이다.
HTTP 요청과 같은 네트워크 호출에 사용되며 보통 플랫폼의 독립적인 인터페이스이다.
각 플랫폼의 하부에서 실행된다.
자바스크립트 엔진(JavaScript Engine)이라고도 한다.
JavaScript는 코드를 위에서 아래로 한 줄씩 읽으면서 파싱(parsing)하는 인터프리터 언어(Interpreted Language)이다. 때문에 JavaScript 코드를 해석하고 실행하는 자바스크립트 해석기(JavaScript Interpreter)가 등장하게 되었다.
아래는 다양한 자바스크립트 해석기이다.
이름 | 설명 |
---|---|
Rhino | 모질라 재단이 운영하는 오픈소스 엔진 자바(Java)로 개발되었음. |
SpiderMonkey | 최초의 Javascript 엔진. 넷스케이프 내비게이터를 지원. 현재는 파이어폭스를 지원 |
V8 | 구글이 개발한 오픈 소스 엔진. 구글 크롬의 Javascript 엔진 |
JavascriptCore | WebKit 프레임워크를 위해 애플에서 개발. 현재는 사파리와 React Native App을 지원 |
Chakra | 마이크로소프트가 개발한 엔진. Edge 브라우저를 지원 |
자바스크립트 해석기의 구조를 크롬의 V8 엔진을 예를 들어 간단히 설명하자면, 크게 힙 메모리와 콜스택으로 구성되어 있다.
힙 메모리(Heap Memory): 동적 메모리 할당에 사용되는 자료구조로 객체 또는 동적 데이터를 저장한다. 여기에 저장되는 메모리는 V8 엔진 내부에서 가장 큰 공간을 차지하고 있으며, 가비지 컬렉션이 발생하기도 한다.
콜 스택(Call Stack)
JavaScript는 콜 스택이 하나인 싱글 스레드 언어다. 콜 스택은 프로그램 상 현재 위치가 어디인지 기록하며 스택 구조인 만큼 한 번에 한 작업만 가능하다.
함수 실행시 해당 함수는 콜 스택의 가장 상단에 위치하게 되고, 함수의 실행이 끝나면 콜 스택의 가장 상단에 위치하고 있는 자료는 바로 제거할 수 있다.
자바스크립트는 한 줄씩 처리하다가 함수 실행구문을 만났을 해당 함수를 콜 스택의 가장 상단에 저장한다.
function a(n){
return b(n);
}
function b(n){
return c(n);
}
function c(n){
return n;
}
a(2);
위와 같은 경우 자바스크립트는 한 줄씩 처리하다가
a(2);
를 만나 함수를 실행하여 콜 스택에 저장한다.여기서 콜 스택에 쌓이는 개별 데이터를 스택 프레임(Stack Frame)라고 한다. 만약 쌓인 스택 프레임의 수가 콜 스택의 용량을 초과할 때는 에러가 발생하며 이를 스택 오버플로우(Stack Overflow)라고 한다.
그리고 콜 스택은 위와 같이 쌓이는 순서가 명확하므로 스택을 추적(trace)할 수도 있다. 이 스택 추적을 활용해 에러가 발생했을 때 어디서 에러가 발생했는지 알 수 있다.
UI 백엔드는 렌더링 엔진이 분석한 Render Tree, 기본 input 등을 브라우저에 렌더링한다. OS 사용자 인터페이스 체계를 사용한다.
자료 저장소는 쿠키 등의 자료를 저장하는 곳으로 웹 저장소(Web Storage, 웹 스토리지)라고도 한다. 이 웹 저장소를 사용하기 전에 웹 브라우저 버전에 따라 지원여부를 확인해야 한다.
이 웹 저장소에는 영구적인 저장소인 로컬스토리지(localStorage)와 임시적인 저장소인 세션스토리지(sesseionStorage)가 있다.
로컬스토리지(localStorage)
세션스토리지(sessionStorage)
웹 저장소 지원 확인 여부
//window 객체에 있는 Storage 객체를 통해 확인할 수 있습니다.
//해당 객체가 존재하지 않는 브라우저라면 undefined를 반환하고, 존재한다면 function을 반환합니다.
if (typeof(Storage) !== "undefined") {
// web storage를 위한 코드 부분
} else {
// web storage를 지원하지 않는 브라우저를 위한 안내 부분
}
여기서 렌더링(rendering)은 HTML, CSS, JavaScript 등의 문서가 브라우저에서 출력되는 과정을 의미한다. 브라우저는 기본적으로 렌더링을 수행하는 렌더링 엔진을 가지고 있다.
사용자가 브라우저로 웹 사이트에 접속했을 때 브라우저 렌더링 과정은 다음과 같다.
이 과정을 그림으로 나타내면 다음과 같다.
여기서 좀 더 중요한 개념들(굵게 처리한 개념들)에 대해 아래와 같이 설명한다.
파싱(Parsing)
파싱은 파서(parser)가 작성된 파일을 실행시키기 위해 구문을 분석(syntax analysis)하는 것을 의미한다.
파서는 HTML 파일의 코드를 토큰(token. 문법적 의미를 갖는 최소 단위)으로 분해하고,
이 토큰들을 노드(node)로 바꾼다.
노드들은 상하 관계에 따라 파스 트리(parse tree), 혹은 문법 트리(syntax tree)라는 트리를 생성한다.
문서 파싱(document parsing)
브라우저가 코드를 이해하고 사용할 수 있는 구조로 변환하는 것을 의미한다. 렌더링 과정에서는 HTML -> DOM 트리, CSS 파일 -> CSSOM 트리 이렇게 생성하는 과정을 의미한다.
파싱은 문서에 작성된 언어, 형식의 규칙을 따르므로 형식을 잘 갖춘 문서라면 파싱 과정이 직관적이고 빠르게 진행된다.
DOM(Document Object Model) Tree
DOM은 HTML문서의 요소의 노드들을 트리 구조로 구성한 것을 의미한다.
JavaScript 언어만 알아듣는 브라우저가 이해할 수 있도록 HTML의 태그나 속성, 텍스트를 객체로 바꾼 것이 DOM 트리이다.
CSSOM(CSS Object Model) Tree
CSS 파일, 스타일 요소를 파싱하여 만든 트리를 CSSOM이라고 한다.
브라우저가 DOM 트리를 파싱하는 과정에서 <link>, <style> 태그를 만나면 파싱을 잠시 멈추고 해당 리소스 파일을 서버로 요청한다. 이렇게 요청한 파일로 CSSOM 트리를 생성하고, 이후 브라우저는 다시 DOM 트리를 파싱했던 과정으로 돌아가 마저 DOM 트리를 구축한다.
Render Tree
브라우저 위에 웹을 렌더링하기 위해 DOM 트리와 CSSOM을 합쳐 만들어진 독립적인 트리를 의미한다. 이 과정에서 display:none;
처럼 보이지 않을 요소들은 이 트리에 포함시키지 않는다.
레이아웃
렌더트리를 기반으로 HTML 요소의 레이아웃(위치, 크기 등)을 계산하여 브라우저 화면의 어느 곳에 배치할 지 결정하는 과정이다.
브라우저는 각 요소들이 전체 화면에서 어떻게 배치가 되어야 하는지 파악하기 위해 렌더트리를 위에서 아래로 읽어 내려간다. 그리고 모든 값은 px 값으로 변환된다.
Paint
브라우저가 레이아웃에서 결정된 대로 화면에 렌더링하는 것을 의미한다. 페인팅은 픽셀에 대한 정보들을 바탕으로 픽셀을 채워나가며, 페인팅 후 HTML 파일의 내용들이 이미지화된 모습으로 브라우저 화면에 띄워진다.
브라우저가 사용자의 눈에 끊김없이 이미지를 보여주기 위해서는 초당 60 프레임은 반드시 유지해야 한다.
그런데 만약 DOM이 변경되면 렌더 트리를 다시 구축하므로 이 때 리플로우(리렌더링)와 리페인트를 해야한다. 리플로우는 CPU를 많이 차지하고, 리페인트는 GPU를 많이 차지하므로 이 과정이 잦을 경우 프레임 드랍(Frame Drop) 을 야기하게 된다.
프레임 드랍은 프레임의 수가 브라우저의 과부하로 인해 줄어드는 것으로 없어진 프레임은 렌더링 엔진이 인식할 수 없게 된다. 이렇게 되면 사용자 입장에서는 화면이 멈추거나 버벅이거나 이미지가 잘려 보이거나 없는 등의 현상을 경험하게 된다.
이는 당연히 좋지않은 UX이므로 최적화를 해야 한다.
모던 웹 브라우저는 성능이 뛰어나기에 대부분의 경우 크게 성능 개선을 고려할 필요는 없다. 그러나 프론트엔드 개발자라면 필수로 알아야 하고, 여러 요구 사항에 대응하기 위해서 최적화에 대해 알아두는 것이 좋다.
최적화에 고려해야할 요소들은 다음과 같다.
불필요한 레이아웃을 줄인다.
불필요한 레이아웃 하나만 줄여도 렌더링 퍼포먼스를 최적화할 수 있으므로 CSSOM 트리의 CSS 속성 중에 레이아웃을 발생시키는 속성들을 줄일 수 있다면 줄이는 것이 좋다.
(물론 브라우저의 기능이 향상되고 기술이 발달하므로 극도로 줄일 필요는 없으나, 어떤 요소가 리플로우, 리페인트를 발생시키는 지는 알아두는 것이 좋다.)
CSS에서 레이아웃, 페인트를 발생시키는 속성들을 알아둔다.
리페인트만 발생하는 속성이 있고, 리플로우와 리페인트 모두 발생시키는 속성이 있다. 위의 렌더링 과정에서 살펴봤듯이 리플로우시 리페인트는 반드시 일어나게 된다.
따라서 가능하다면 리페인트만 발생시키는 속성들을 사용하는 것이 좋다.
리플로우가 일어나는 대표적인 속성들은 다음과 같다.
보통 위치, 너비, 크기, 텍스트 등과 관련된 속성들이다.
position,
left, right, top, bottom
width, height, margin, padding, min-height
border, border-width,
display, float, clear, overflow
line-height, text-align, vertical-align
font-family, font-size, font-weight
만약 이 속성들을 최대할 덜 사용하기 위한 대안이 있다면 transform을 사용할 수도 있다. transform 속성값 중 translate를 사용하면 위치를 이동하지만, 리페인트만 발생하므로 좀 더 나은 퍼포먼스를 기대할 수 있을 것이다.
아래는 리페인트가 일어나는 대표적인 속성들이다.
background, background-image,
background-position, background-repeat, background-size, border-radius,
border-style, box-shadow, color, line-style, outline, clear,
,display, float, font-family, font-size, font-weight, outline-color,
visibility
이외에 리페인트도 야기하지 않는 속성으로 opacitiy가 있다.
position:absolute
또는 position:fixed
를 사용하는 게 하나의 대안이 될 수도 있다.반응형 웹 디자인이란 브라우저의 크기(스크린의 크기, 디바이스의 종류)에 실시간으로 반응하여 그 크기에 따라 레이아웃이 변하는 웹 사이트를 의미한다. 하나의 소스 코드로 pc, 태블릿, 모바일 등 모든 스크린에 최적화된 웹 사이트를 구축할 수 있는 방법론이다.
반응형 웹의 가장 큰 특징은 하나의 URL을 기반으로 화면이 바뀐다는 것이다.
만약 모바일을 별도의 url이나 path등을 사용해야 한다면 반응형 웹이라고 하지 않는다.
그리고 '모바일 퍼스트'라는 개념이 중요해지면서 반응형 웹도 중요한 개념이 되었다.
반응형 웹의 장점은 다음과 같다.
아래와 같은 단점도 있다.
미디어 쿼리는 CSS에서 뷰포트(브라우저 크기. 주로 너비)에 따라 서로 다른 스타일을 적용할 수 있도록 하는 방법이다. 이를 활용해 반응형 웹을 제작할 수 있다.
미디어 쿼리 이전에 작성한 CSS가 먼저 반영되고, 미디어 쿼리 조건에 따라 기존 CSS에서 수정되길 원하는 부분을 작성한다.
이 미디어 쿼리를 적용하는 방법에는 여러 가지가 있다.
예를 들어 브라우저 너비가 768~1140px에 해당될 때만 다른 css를 파일을 적용하고 싶다면,
아래처럼 media 속성을 사용할 수 있다.
<link href="css파일이름.css" media="screen and (min-width: 768px) and (max-width: 1140px)" rel="stylesheet">
<style type="text/css" media="screen and (min-width: 768px) and (max-width: 1140px)">
/* 여기 css를 작성*/
</style>
@media screen and (min-width: 768px) and (max-width: 1140px) {
body {
color: red;
}
}
위의 적용 법에 살펴본 것을 토대로 미디어 쿼리의 구조에 대해 살펴본다.
/* 이 방법으로 작성하면 된다. */
@media 미디어 타입 (조건(너비 및 높이)) {
(CSS 입력하는 부분)
}
이외에도 다음과 같은 기능을 사용할 수 있다.
@media (orientation: landscape) {
body {
color: rebeccapurple;
}
}
@media screen and (min-width: 540px) and (orientation: landscape) {
body {
color: red;
}
}
@media screen and (min-width: 540px), screen and (orientation: landscape) {
body {
color: red;
}
}
@media not all and (orientation: landscape) {
body {
color: red;
}
}
CSS 애니메이션은 CSS만을 사용해 애니메이션을 만들 수 있는 css 기능을 의미한다.
이 CSS를 사용하기 위해서는 @keyframes
키워드를 활용하며, 시간 단위로 지정한 스타일을 애니메이션으로 연결하여 만들어낸다.
@keyframes
을 사용하는 방법은 아래와 같다.
/* '%' 단위로 시간 진행에 따른 상태를 작성한다. */
/* 0%는 from ,100%는 to로 작성해도 된다. */
@keyframes 애니메이션이름 {
0% { /* from 이라고 작성해도 됩니다.*/
CSS속성 : 속성값;
}
50% { /* 애니메이션 진행도에 따른 스타일을 설정합니다. */
/* 필요하다면 1부터 99까지도, 소수점까지도 모두 작성해도 됩니다.*/
CSS속성 : 속성값;
}
100% { /* to 라고 작성해도 됩니다.*/
CSS속성 : 속성값;
}
}
CSS animation은 찬찬히 해보면 어렵지 않으며, 원하는 결과가 어떻게 나오는지는 작성하는 사람에게 달려있다. 때문에 설명과 예시, 직접 여러 속성을 입력하며 해볼 수 있는 아래의 사이트를 추천한다.
🔗 https://www.w3schools.com/css/css3_animations.asp
애니메이션을 적용하기 위해서는 위와 같이 @keyframes
키워드를 사용해 임의의 이름으로 애니메이션을 만들고, 그 애니메이션을 적용하고자 하는 요소에 적용하면 된다.
#element {
animation : myAnimation 3s 1s alternate infinite;
}
#element {
animation-name : myAnimation;
animation-duration : 3s;
animation-delay : 1s;
animation-direction : alternate;
animation-iteration-count: infinite;
}
HTML의 <canvas> 태그와 Javascript를 사용하면 다양한 그래픽 요소를 만들 수 있다.
canvas는 html에 canvas태그로 작성하여 DOM으로 엘리먼트를 조작하여 만든다.
만드는 방법은 다음과 같다.
html에서 canvas태그를 작성하고 너비와 높이를 설정해야 한다. 단위는 px이며 그 외의 단위는 자바스크립트로 작성해야 한다.
<canvas id="canvas" width="800" height="600">
캔버스를 지원하지 않는 브라우저는 이곳의 내용이 표시된다.
</canvas>
작성한 태그를 자바스크립트 DOM으로 할당하여 사용한다.
만약 다른 단위로 너비와 높이를 할당하고 싶으면 자바스크립트로 설정한다.
const canvas = document.querySelector("#canvas");
canvas.width = 50vw;
canvas.height = 40vh;
//또는
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
나머지 속성과 메소드는 Mozlia의 Canvas API에서 확인하실 수 있다.
🔗https://developer.mozilla.org/ko/docs/Web/API/Canvas_API
1. chart.js
chart.js는 canvas를 활용한 라이브러리로, 데이터를 입력하면 html에 원하는 차트를 입력하여 넣을 수 있다.
아래는 일반 html, js를 사용했을 때 활용가능한 라이브러리며,
react의 경우 DOM조작을 하지 않는 버전이 따로 있다.