최고의 웹 성능을 구현하기 위해 최고의 조건을 만드는 다양한 노력을 의미한다. 브라우저는 상단부터 차례대로 로드된다. HTML 파일을 읽어온 후, 위에서 부터 한 줄씩 해석한다. 이 과정에서 CSS / JS 파일을 만나면 해당 파일을 해석하는 동안 웹 페이지 렌더링은 일시적으로 차단된다. 이 때 마치 정지한 듯한 화면으로 보이는데, 이런 화면을 사용자가 보게되면 불편해 하거나, 페이지 이탈 할 가능성이 있다. 때문에 좋은 성능의 웹을 만들기 위해서 웹 최적화는 필수로 거쳐야 하는 과정이다.
성능 최적화 = 렌더링 최적화 + 로딩 최적화
HTML | CSS | JS | Image 최적화를 진행한다. 최적화가 잘되어 있는 웹 사이트는 브라우저에서 콘텐츠를 다운로드 | 로딩 렌더링할 때 속도가 빨라진다.
웹 서버웹 애플리케이션 서버데이터베이스 | 로드 밸런싱 | DNS 서버 등을 최적화 한다.
HTTP 프로토콜 자체의 효과를 극대화화면 콘텐츠를 최고 속도와 최저 지연 시간으로 전달 할 수 있다.
블록 리소스(렌더링 차단 리소스)란 HTML 브라우저의 렌더링을 막는 소스들로 일반적으로 css
와 js
파일을 말한다.
웹 페이지 렌더링 최적화의 목표는 리플로우를 최대한 적게 발생시키면서, 빠르게 화면 그리는 것이다.
브라우저의 스타일이 그려지는 순서
이 때 레이아웃의 넓이, 높이, 위치 등에 영향을 주는 CSS 속성을 변경할 경우, Layout 부터 다시 그려지게 되는데 이를 Reflow(Layout)이라고 한다.
반면 레이아웃에 영향을 주지 않는 속성을 변경하면 레이아웃을 건너뛰고 페인터 작업부터 다시 수행하게 되는데, 이를 Repaint라고 한다.
Reflow가 일어나면 브라우저가 전체 픽셀을 다시 계산해야 하기때문에 되도록 Repaint 속성을 사용해 스타일을 작성하는 것이 성능면에서 좋다.
position / width / height / margin / padding / display / top / left / right / bottom /
box-sizing / border-color / text-align / border / border-width /
font-family / float / font-size / font-weight / line-height / vertical-align /
white-space / word-wrap / text-overflow / text-shadow ...
color / border-style / visibility / background / background-color /
background-image / background-position / background-repeat / background-size /
text-decoration / outline / outline-style / outline-color / outline-width /
border-radius / box-shadow ...
opacity / transform / cursor / z-index ...
앞서 말했듯 CSS는 렌더링 차단 리소스이기 때문에 사용하지 않는 CSS는 제거하는 것이 좋다. Unused CSS는 구글 크롬 라이트하우스를 통해 확인할 수 있다.
Lighthouse
)는 2KB 이상 사용되지 않은 css가 있을 시 오류로 표기한다.복잡한 셀렉터 사용은 지양한다. CSS가 복잡하고 방대할수록 레이아웃을 그리는 데에 시간이 많이 소요된다.
선택자를 간결하게 사용하여 특이성을 낮게 유지하는 것이 좋다.
.mypage .mypage_item{...} /* 🔺 */
.mypage_item{...} /* ✅ */
html 요소에 style을 통해 인라인 스타일 작성을 하면 불필요한 코드 중복이 발생하기 쉽다.
인라인 스타일은 웹 페이지가 그려지면서 레이아웃에 영향을 미치면서 추가로 리플로우를 발생시킨다.
DOM 트리가 깊고, 자식 요소가 많을수록 DOM 트리는 커진다. DOM 트리가 커지면 DOM 변경 시 계산해야 하는 것이 많아진다.
transform
은 Reflow 와 Repaint 모두 발생시키지 않고, 합성만 발생시키는 속성이다. 때문에 애니메이션 사용 시 렌더링 속도를 향상시킬 수 있다.absolute
| fixed
로 설정하면 주변 요소에 영향을 주지 않는다.레이아웃 단계가 완료되기 전에 요소의 위치나 크기를 변경 ,후 바로 가져오려고 하면 강제로 레이아웃이 발생하는데, 이것을 강제 동기 레이아웃이라고 한다.
그리고 이 레이아웃을 반복적으로 발생시키는 것이 레이아웃 스레싱이다.
웹 페이지가 로드되면 HTML과 CSS가 동시에 파싱된다. DOM트리는 파싱 중에 요소를 발견 할 때마다 순차적으로 구성할 수 있지만, CSSOM트리는 CSS를 모두 해석해야 구성할 수 있다. 즉, CSSOM 트리가 구성되지 않으면 렌더 트리를 만들지 못하고 렌더링이 차단된다. 이러한 이유로 CSS는 렌더링 차단 리소스(블록 리소스)라고 하며, 렌더링이 차단되지 않도록 CSS는 항상 HTML 문서 최상단 (head)에 배치한다.
웹 페이지는 파싱을 실행하는 도중에 script를 만나면 html 파싱을 멈추고 script 파일을 다운로드 한 뒤, 다시 html을 실행한다. 따라서 html, css Layout들의 로드가 끝나고, js가 실행되는게 좋기 때문에 body 태그를 닫기 직전에 script를 임포트 한다.
media 속성을 사용하면, 조건 별로 css를 불러올 수 있다.
반응형 웹을 제작할 때 유용하게 사용될 수 있다.
구글 크롬 Lighthouse는 media 속성이 없는 요소를 렌더링 블로킹 리소스로 판단한다. media 속성이 없는 스타일시트는 해당 스타일시트를 브라우저가 해석하는 동안 화면에 스타일을 불러오지 않는다.
<!-- 🔺 -->
<link href="style.css" rel="stylesheet">
<!-- 브라우저의 넓이가 320이상 769미만일때 스타일시트 해석 -->
<link href="style.css" rel="stylesheet" media="(min-width:320px) and (max-width:768px)">
<!-- 프린트할때만 스타일시트 해석 -->
<link href="style.css" rel="stylesheet" media="print">
<!-- 세로모드일때만 스타일시트 해석 -->
<link href="portrait.css" rel="stylesheet" media="orientation:portrait" />
async와 defer 속성은 스크립트 파일을 병렬로 다운로드하게 해준다.
로딩 시 웹페이지 해석을 멈추지 않고 스크립트를 다운로드 하는 것이다.
<!-- 반드시 순서대로 실행되어야 할 때 사용 -->
<script src="test.js"></script>
<!-- 병렬 다운로드 & 즉시실행: 빨리 실행되어야 할 때 사용 -->
<script async src="test.js"></script>
<!-- 병렬 다운로드 & 지연실행: 마지막에 파싱해도 상관 없을 때 사용 -->
<script defer src="test.js"></script>
WebP - IE 미지원. jpg | .png 대비 30 ~ 70% 수준의 저용량 파일 형식
avif - 크롬 | 삼성 인터넷 지원. 저용량 + 고품질의 파일 형식
<!-- 브라우저가 avif를 지원하면 avif를 사용하고,
그렇지 않은 경우 webp,
둘 다 지원하지 않을 경우 jpg 이미지를 사용한다. -->
<picture>
<source srcset="aaa.avif" type="image/avif">
<source srcset="aaa.webp" type="image/webp">
<img src="aaa.jpg" alt>
</picture>
media의 조건. 해상도에 따라 출력할 이미지를 지정할 수 있다.
<picture>
<!-- 브라우저의 넓이가 760px 이하일때 mob.webp 이미지 출력-->
<source srcset="mob.webp" media="(max-width: 760px)">
<img src="pc.webp" alt>
</picture>
auto - 디폴트 값. loading 속성을 쓰지 않음
lazy - 화상에 보이는 부분만 먼저 출력하고, 화면 바깥쪽 이미지들은 로딩하지 않는다. 사용자가 화면을 위로 올리면 아래쪽에 있던 이미지가 올라오면서 로딩된다.
eager - 화면 위치와 상관없이 페이지가 로딩 되자마자 이미지를 로딩한다.
<img src="item.jpg" loading="lazy" alt>
웹팩을 사용해서 css | js를 하나의 파일로 몰아서 임포트하는게 좋다.
모듈 번들러 웹팩을 사용해서 css와 js 파일을 번들링해 리소스 요청을 줄일 수 있다.
Gzip을 사용해 텍스트 기반의 리소스로 압축한다.
UglifyJs등을 사용해서 js 파일을 압축한다.
불필요한 공백이나 줄바꿈을 제거해서 파일의 용량이 감소하며, 난독화를 하면 민감한 코드를 알아보기 어렵게 만들 수 있다.
CDN(Content Delivery Network)은 유저에게 많은 콘텐츠를 손실없이 빠르게 전달하는 서비스이다.
캐쉬랑 사용자가 요청하는 html, css, js , image 등을 첫 요청 시에 내려받은 뒤 특정 위치에 복사본을 저장하고, 이후 동일한 URI 리소스 요청이 왔을 때 이전에 저장해둔 파일을 사용해서 더 빠르게 로딩하는 데에 사용된다.