[최적화] 최적화 기법

hzn·2022년 12월 4일
0

etc

목록 보기
7/13
post-thumbnail

HTML, CSS 코드 최적화하기

  • 화면을 렌더링할 때는 HTML 파일CSS 파일이 필요
  • HTML 파일은 DOM 트리를, CSS 파일은 CSSOM 트리를 만들고 두 트리를 결합(렌더 트리)하여 렌더링할 때 사용
  • 이 두 트리 중에서 하나라도 변경되면 리렌더링을 유발하는데, 이때 트리의 크기가 크고 복잡할수록 더 많은 계산이 필요하기 때문에 리렌더링에 소모되는 시간도 길어진다.
  • 따라서 HTML, CSS 코드를 최적화함으로써 렌더링 성능을 향상시킬 수 있다.

1. HTML 최적화 방법

1) DOM 트리 가볍게 만들기

  • DOM 트리가 깊을수록, 자식 요소가 많을수록 DOM 트리의 복잡도가 커진다.
    👉🏽 불필요하게 깊이를 증가시키는 요소가 있다면 삭제
// 수정 전
<div>
	<ol>
		<li> 첫 번째 </li>
		<li> 두 번째 </li>
		<li> 세 번째 </li>
	</ol>
</div>

// 수정 후 : 불필요한 div 요소 제거
<ol>
	<li> 첫 번째 </li>
	<li> 두 번째 </li>
	<li> 세 번째 </li>
</ol>

2) 인라인 스타일 사용하지 않기

  • 인라인 스타일은 개별 요소에 스타일 속성을 작성해주는 것이기 때문에, 클래스로 묶어서 한 번에 작성해도 될 스타일 속성을 중복으로 작성하게 되는 경우가 생긴다.
  • CSS 파일을 따로 작성하면 단 한 번의 리플로우만 발생하지만, 인라인 스타일은 리플로우를 계속해서 발생시켜 렌더링 완료 시점을 늦춘다.
    (<head><link> 요소로 넣은 CSS를 파싱해서 이미 CSSOM 트리를 만들었는데 그 후 계속 인라인 스타일을 만나면 그때마다 CSSOM 트리를 파괴하고 다시 만들어야됨)
//수정 전
<div style="margin: 10px;"> 마진 10px </div>
<div style="margin: 10px;"> 이것도 마진 10px </div>

//수정 후 : class와 CSS로 대체
<div class="margin10"> 마진 10px </div>
<div class="margin10"> 이것도 마진 10px </div>

.margin10 {
	margin: 10px;
}

2. CSS 최적화 방법

1) 사용하지 않는 CSS 제거하기

  • 요소를 삭제하면서 CSS 코드만 남기지 않기

2) 간결한 셀렉터 사용하기

  • 셀렉터가 복잡할 수록 스타일 계산과 레이아웃에 시간을 더 많이 소모하게 된다.
// 복잡한 CSS 셀렉터 예시
.cart_page .cart_item #firstItem { ... }

// 필요한 경우에는 어쩔 수 없지만, 가능한 한 간결하게 작성한다.
.cart_item { ... }

리소스 로딩 최적화하기

  • HTML 파일에서 JavaScript 파일을 불러올 땐 <script> 요소를, CSS 파일을 불러올 땐 <link> 요소를 사용
  • 이때 파일을 불러오는 위치가 어디인가에 따라서 렌더링 완료 시점이 달라질 수 있다.

1. CSS 파일 불러오기 : HTML 최상단

  • 화면을 렌더링할 때는 DOM 트리와 CSSOM 트리가 필요
  • DOM 트리는 HTML 코드를 한 줄 한 줄 읽으면서 순차적으로 구성할 수 있지만, CSSOM 트리는 CSS 코드를 모두 해석해야 구성할 수 있다.
  • CSSOM 트리를 가능한 빠르게 구성할 수 있도록 HTML 문서 최상단(<head> 요소 안)에 배치
// CSS 파일은 HTML 파일 상단의 head 요소 안에서 불러오는 것이 좋다.
<head>
	<link href="style.css" rel="stylesheet" />
</head>

2. JavaScript 파일 불러오기 : HTML 최하단

  • JavaScript는 DOM 트리와 CSSOM 트리를 동적으로 변경할 수 있다.
  • HTML 코드 파싱 중에 <script> 요소를 만나는 순간 해당 스크립트가 실행되며, <script> 요소 이전까지 생성된 DOM까지만 접근할 수 있습니다.
  • <script> 요소를 HTML 코드 중간에 넣는다면, 그 이후에 생성될 DOM을 수정하는 코드가 <script> 요소에 있는 경우에는 화면이 의도한 대로 표시되지 않게 됩니다.
  • 또한 스크립트 실행이 완료되기 전까지 DOM 트리 생성이 중단된다. JavaScript 파일을 다운받아와서 사용하는 경우에는 다운로드 및 스크립트 실행이 완료될 때까지 DOM 트리 생성이 중단된다.
  • DOM 트리 생성이 중단된 시간만큼 렌더링 완료 시간은 늦춰지게 된다.
  • 이러한 이유로 JavaScript 파일은 DOM 트리 생성이 완료되는 시점인 HTML 문서 최하단(<body> 요소가 닫히기 직전)에 배치하는 것이 좋다.
<body>
	<div>...</div>
	...

	// JavsScript 파일은 body 요소가 닫히기 직전에 작성하는 것이 가장 좋다. 
	<script src="script.js" type="text/javascript"></script>
</body>

참고 : <script> 요소를 body의 마지막에 넣는 경우와 defer 속성을 주고 head에 넣는 경우 비교

  • <script> 요소를 body의 마지막에 넣고 웹팩으로 번들링을 진행하면 웹팩이 자동으로<script> 요소에 defer 속성을 추가해 head에 넣어준다.
  • defer 속성이 있는 <script> 요소는 HTML 파싱 과정에서 Fetching만 하고 실행은 파싱이 다 끝난 후에 한다. 시간을 훨씬 줄여줌!

브라우저 이미지 최적화하기

  • 페이지의 대부분의 용량은 HTML/CSS/JS와 같은 코드 데이터가 아닌 이미지 파일과 같은 미디어 파일이 차지
  • 이미지의 용량을 줄이거나 요청의 수를 줄이는 것을 우선적으로 고려할 시, 사용자 경험을 빠르게 개선할 수 있다.

1. 이미지 스프라이트

  • 여러 개의 이미지를 모아 하나의 스프라이트 이미지로 만들고 CSS의 background-position 속성을 사용해 이미지의 일정 부분만 클래스 등으로 구분하여 사용하는 방법
  • 한번의 이미지 요청으로 대부분의 개별 이미지를 사용할 수 있기 때문에 네트워크 로딩 시간을 줄일 수 있다.
  • 또한, 많은 이미지 파일을 개별로 관리할 필요없이 특정 스프라이트 이미지 파일만을 관리하면 되므로 관리가 용이하다.

  • 하나의 이미지를 배경 이미지로 사용하되, 표시하고 싶은 부분에 맞춰 width, height, background-position 속성을 주어 아이콘을 만든다.

2. 아이콘 폰트 사용하기

  • 아이콘 사용이 많을 때에는, 모든 아이콘을 이미지로 사용하는 것이 아니라 아이콘 폰트를 사용하여 용량을 줄일 수 있다.

Font Awesome

1) CDN으로 사용하기

  1. Font Awesome에 가입하면 키트를 발급해주는데, 이 키트를 HTML 파일에서 <head> 요소에 넣어준다. (CDN으로 Font Awesome을 사용할 준비 완료)
  1. 사용하고 싶은 아이콘을 찾아서 사용할 환경(HTML, React, Vue)에 맞는 코드를 복사하고 붙여넣기만 하면 사용할 수 있다.

2) Font Awesome 모듈 설치하기

  • 라이브러리처럼 설치해서 사용하는 방법
  1. 아래 패키지들을 설치
// 핵심 패키지 설치
npm i --save @fortawesome/fontawesome-svg-core

// 아이콘 패키지 설치 (해당 코드는 무료 아이콘들입니다. 유료 아이콘을 사용할 경우 추가로 설치가 필요합니다.)
npm i --save @fortawesome/free-solid-svg-icons
npm i --save @fortawesome/free-regular-svg-icons
npm i --save @fortawesome/free-brands-svg-icons

// Font Awesome React 구성 요소 설치
npm i --save @fortawesome/react-fontawesome@latest
  1. 사용하고 싶은 아이콘의 정보를 확인한 후에, 알맞게 불러와서 사용한다.
    이때 아이콘 이름은 camelCase로 작성해야 한다.
    이렇게 불러온 아이콘은 클래스명을 직접 붙이거나 Font Awesome이 정해준 방법을 사용하여 스타일링해줄 수 있다.

3. WebP 또는 AVIF 이미지 포맷 사용하기

  • 새롭게 등장한 이미지 포맷인 WebP 또는 AVIF를 사용하여 전통적으로 사용하는 JPEG 또는 PNG 형식보다 용량을 더욱 감소시킬 수 있다.
  • WebP와 AVIF 모두 비교적 최근에 등장한 이미지 포맷이기 때문에 JPEG 포맷처럼 모든 브라우저에서 호환되지 않는다는 단점.
  • HTML의 <picture> 태그를 이용하면 각 브라우저의 호환에 맞도록 분기를 대체할 수 있다.
  • <picture> : img 요소의 다중 이미지 리소스(multiple image resources)를 위한 컨테이너를 정의할 때 사용.
<picture>
  <source srcset="logo.webp" type="image/webp">
  <img src="logo.png" alt="logo">
</picture>
  • 접속한 브라우저에서 <source> 태그 내의 srcset에 정의한 WebP 포맷을 지원하지 않는다면 해당 <source> 태그는 무시된다.

CDN 사용하기

  • Content Delivery Network
  • 콘텐츠를 좀 더 빠르고 효율적으로 제공하기 위해 설계됨
  • 네트워크 지연(latency)은 유저와 호스팅 서버간의 물리적 거리의 한계가 존재하기 때문에 발생
  • CDN은 이를 해결하고자 세계 곳곳에 분포한 분산된 서버에 콘텐츠를 저장
  • CDN은 유저가 가까운 곳에 위치한 데이터 센터(서버)의 데이터를 가져온다.
  • 데이터가 전달되기 위해 거쳐야하는 서버의 갯수가 크게 줄기 때문에 로딩 속도가 빨라진다.
  • CloudFront, Cloudflare 등의 CDN 서비스

0개의 댓글