웹 서버가 생성하여, 웹 브라우저로 전송하는 "작은 정보 파일"
웹 브라우저는 수신한 쿠키를 일정 기간동안 저장하고, 향후 사용자가 웹 서버에 요청을 보낼 때, 첨부한다.
사용자 세션
웹 서버에 요청을 보내는 사용자가 누구인지 파악하기 위해.
ex) 웹 사이트에 로그인했을 때, 웹 서버에서는 세션 쿠키를 생성하여 브라우저로 전송한다. 브라우저에 저장된 쿠키는 이후 웹 서버로 보내는 요청에 포함된다. 요청을 받은 웹 서버는 어떤 유저에 대한 요청인지 파악할 수 있게 된다.
트래킹
사용자가 방문한 웹 사이트가 기록되어, 다음에 브라우저가 해당 서버에서 콘텐츠를 로드할 때 기록을 쿠키에 담아 서버로 전송한다.
이를 통해, 어떤 곳들을 방문했었는지를 알 수 있게 된다.
HttpOnly
옵션이 활성화되지 않은 쿠키는 어떻게 가져올 수 있을까?document.cookie
를 통해, 쿠키 정보를 확인할 수 있다.Node.js 프로젝트에서 사용되는 "프로젝트에 대한 설명서" 파일이다.
프로젝트의 이름, 버전, 작성자, 라이센스, 의존성(서드파티 패키지) 정보가 포함되어 있다.
프로젝트 기본 정보 및 의존성 트리에 대한 정보가 포함되어 있다.
package.json
파일 안에 있는 "의존성" 정보에는 해당 패키지에 대한 '대략적인' 버전이 명시된다. 즉, 정확한 패키지 버전에 대한 정보는 없음.
다른 서버에서 프로젝트를 실행할 때, 대략적인 버전으로 설치가 되는 경우에 문제가 생길 "수도" 있기 때문에 특정한 시점을 기준으로 명확한 버전을 명시할 필요가 있기 때문에 package-lock.json
이 필요하다.
브라우저 렌더링은 웹 페이지가 사용자의 화면에 표시되는 과정을 말한다.
브라우저 렌더링은 다음 과정을 거쳐 진행된다.
문서(HTML) 파싱(분석)
브라우저는 HTML Document를 받아서 DOM 트리를 구축한다.
이 트리는 페이지의 구조를 나타내며, 각각의 HTML 태그는 트리의 노드가 된다.
CSS 파싱
CSS 파일과 style
태그 내부의 스타일 정보를 파싱하여, CSSOM 트리를 생성한다. 이 트리는 페이지의 시각적 규칙을 나타낸다.
렌더 트리 구축
DOM 트리와, CSSOM 트리를 결합하여, 렌더 트리를 형성한다.
렌더 트리는 페이지에 실제로 표시되는 요소들만 포함한다.
레이아웃 (리플로우)
렌더 트리의 각 노드에 대해 화면 상의 정확한 위치와 크기를 계산한다.
브라우저 창의 크기 변경이나 요소의 추가 및 삭제 등에 의해 다시 실행될 수 있다.
페인트
렌더 트리의 각 노드를 화면에 그린다. 텍스트 색상, 배경 이미지 등의 시각적 스타일이 적용된다.
레이아웃 단계 이후에 실행된다.
합성
여러 레이어를 합쳐 최종적인 화면을 생성한다.
CSS의 transform
속성을 활용한 애니메이션은 별도의 레이어에서 처리될 수 있는데, 이처럼 복잡한 페이지는 여러 레이어로 구성될 수 있음.
display: none
스타일이 적용된 요소는 렌더 트리에 포함하지 않는다.Reflow와 Repaint는 브라우저 렌더링 과정에서 발생하는 업데이트 유형이다. 웹 페이지 성능과 직접적인 관련이 있다.
(정의)
레이아웃을 다시 계산하고, 변경이 필요한 경우 업데이트하는 과정
(원인)
DOM 요소의 추가(제거), 요소의 크기나 위치 변경, 창 크기 조절, 숨겨진 요소의 표시 등의 원인으로 일어난다.
(영향 범위)
한 요소의 변경은 해당 요소의 자식, 부모 요소등 페이지의 다른 부분에도 영향을 줄 수 있다. (페이지 전체 레이아웃을 다시 계산해야 할 수도 있다는 것)
(성능 영향)
비용이 많이 드는 연산이기에, 웹 페이지 성능에 큰 영향을 미친다. 특히, 복잡한 레이아웃을 가진 페이지에서 영향이 크다.
(정의)
요소의 시각적 변경이 발생했을 때, 변경된 요소를 다시 그리는 과정
(원인)
텍스트 색상 변경, 배경 이미지 변경, 테두리 스타일 변경 등 레이아웃 변경을 수반하지 않는 스타일 변경
(영향 범위)
reflow에 비해 영향 범위가 작다. 해당 요소에 대한 스타일 변경으로 인해 다른 요소에 영향을 주지 않기에 발생한 요소에 대해서만 업데이트가 수행됨.
(성능 영향)
reflow에 비해 성능에 미치는 영향이 적다. 단, 빈번하게 발생하면 렌더링 성능에 부정적인 영향을 줄 수 있다.
일괄적으로 처리하는 방향
스타일 변경 일괄 처리 (클래스를 통한 스타일 변경)
적용 전
DOM 요소의 스타일을 개별적으로 변경
const element = document.getElementById('myElement');
element.style.padding = '10px';
element.style.margin = '20px';
element.style.color = 'blue';
적용 후
단일 DOM 변경 사이클에서 여러 스타일 변경을 수행하기 위해 수정
const element = document.getElementById('myElement');
element.style.cssText = 'padding: 10px; margin: 20px; color: blue;';
// 또는
element.className = 'newStyles';
레이아웃 정보 읽기와 쓰기 분리
적용 전
레이아웃을 읽고 쓰는 작업이 혼재되어 있어, 불필요한 Reflow가 발생할 수 있음
const elements = document.querySelectorAll('.item');
for (let element of elements) {
element.style.height = (element.offsetHeight + 10) + 'px';
}
적용 후
모든 레이아웃 정보를 읽은 후, 일괄적으로 변경을 적용
const elements = document.querySelectorAll('.item');
const heights = Array.from(elements).map(el => el.offsetHeight + 10);
elements.forEach((element, index) => {
element.style.height = heights[index] + 'px';
});
오프스크린 요소 사용
적용 전
화면에 바로 요소를 추가하고, 스타일을 변경합니다.
const element = document.createElement('div');
document.body.appendChild(element);
element.style.width = '100px';
element.style.height = '100px';
// 이러한 방식은 요소가 DOM에 추가될 때마다 Reflow를 유발할 수 있습니다.
적용 후
요소를 브라우저의 화면에 표시되지 않는 영역에서 조작한 후, 최종적으로 DOM에 추가합니다.
const element = document.createElement('div');
element.style.width = '100px';
element.style.height = '100px';
// 요소에 대한 모든 변경을 적용한 후에 DOM에 추가합니다.
document.body.appendChild(element);
// 이 방법은 DOM에 요소를 추가하기 전에 모든 변경을 완료하여 Reflow를 최소화합니다.
공통점
웹 페이지의 시각적 업데이트 과정의 유형이다.
차이점
Reflow는 레이아웃의 변경을 포함하여, 연산 비용이 더 많이 든다.
Repaint는 시각적 스타일 변경에 국한되어, 레이아웃 변경을 수반하지는 않는다.
따라서, Reflow는 Repaint를 수반할 수 있지만 Repaint가 반드시 Reflow를 수반하는 것은 아니다.