웹 성능 최적화 기본 개념 정리

JACKJACK·2025년 8월 5일
post-thumbnail

웹 성능 최적화의 이유

사용자를 유지하여 = 수익 증대, 또한 웹 페이지의 경쟁력을 갖추기 위함이다.

성능 최적화를 위해서는 훈련이다. 여러 직접 사이트를 분석하고 뜯어보고 최적화 하며 실력을 쌓아야 한다.

성능의 최적화의 중요한 두 요소는 결국 로딩 성능렌더링 성능에 있다.
더 빠르게 로딩하고 더 빠르게 렌더링하는 것을 하기 위해서는 브라우저의 서버 통신, 브라우저는 화면을 어떻게 그리는지 명확히 알 필요가 있다.

로딩 성능 최적화

이미지 사이즈 최적화(이미지의 사이즈가 너무 크면 서비스가 무거워짐)
Code Split (코드를 효율적으로 분할하는 방법, 언제 분할해야하는가?)
텍스트 압축(리소스들을 다운받을 때 서버에서 압축하여 작은 사이즈로 다운을 받는 기법)

렌더링 성능 최적화

Bottleneck 코드 최적화(특정 JS가 병목현상을 일으켜 서비스 부하를 유발 -> 분석 및 해결이 필요함)

  • 최적화에 앞서 사이트의 성능 분석을 위한 툴 소개
    크롬 Network 탭 - 네트워크 리소스의 상세정보를 알 수 있다.
    크롬 Performance 탭 - 웹페이지상에 실행되는 모든 작업들을 볼 수 있다.
    크롬 Lighthouse 탭 - 성능 및 웹 서비스의 수준을 파악할 수 있음(웹 품질 개선을위해 성능을 분석해주는 오픈소스 라이브러리였는데 17.05에 크롬 devtools로 병합됨)
    Webpack bundle anlyzer - 서비스가 어떤 코드들을 사용하고 있는지 확인이 가능

  • 우선 성능 Lighthouse로 성능을 분석한다. Lighthouse에서는 Oppertunities(로딩 성능 최적화 관련)와 Digonostics(렌더링 성능 최적화 관련)가 있는데 페이지 성능의 문제점과 그 문제를 해결하기 위한 가이드를 제시한다.
    뿐만 아니라 통과한 감사 항목을 보면 이미 잘 적용하고 있는 항목들을 확인할 수 있다. 이렇게 분석한 내용을 가이드 삼아 최적화를 진행해 나가면 된다.

  • Lighthouse 분석에 앞서 가장 흔한 최적화로는 이미지 사이즈 최적화가 있다.
    만약 120x120 pixels의 이미지가 필요할 때 1200x1200 pixels의 이미지를 사용한다면 줄여줄 필요가 있다. (120x120 pixels가 적절해 보이지만, 요즘 디스플레이는 같은 공간에 더 많은 픽셀을 집어넣기 때문에 두 배 정도의 픽셀이 적절하다고 한다.)
    줄일 때 스태틱한 이미지라면 직접 줄이면 되지만 만약 API를 통해 이미지를 받아온다면 CDN을 통해 받아와주면 해결된다.
    이미지 CDN은 다른 데이터를 물리적으로 가까이 기법과는 살짝 다르다 {IMAGE_URL}?src=[imge src]&width=200&height=200 가공하여 이미지를 받아올 수 있음(대표적으로 카카오의 Brunch 서비스). 이미지 CDN 솔루션을 사용하여 최적화 하면 된다.

  • Lighthouse>진단 항목을 살펴보면 보통 많이 나오는 항목으로는 자바스크립트 최적화와 CSS최적화일 것이다. 과도한 자바스크립트(Javascript)와 CSS는 웹사이트의 성능을 저하시키므로 파일 크기를 줄여야 한다.
    1차원적으로는 파일 크기를 줄이고, 비동기 로딩

  • Lighthouse진단 항목으로는 명확한 원인까지 알기 어려운 경우 Performance 탭으로 들어가 성능을 확인할 수 있다. 페이지 전체의 타임라인에서 영역을 선택해 네트워크 타임라인과 자바스크립트 실행 내역을 볼 수 있다. chunck의 로드가 오래걸릴 경우 해당 청크를 분석하는것이 가능하다. JS 실행(페이지, 컴포넌트 코드) 후 DCL(Dom Contents Load event),FP(First Paint),FCP(First Contentsful Paint),L(Onload event) 페이지 로드와 같은 부분과 API 요청 시기도 확인이 가능하다. 이렇게 퍼포먼스 탭을 자세히 들여다보면 어디서 병목이 일어나는지 확인할 수 있다. 병목현상 부분을 해결하여 퍼포먼스 탭의 프레임차트를 줄여나가야 한다.

  • 번들 파일 분석 및 코드 스플리팅을 통해서도 성능 최적화가 가능하다. 리소스 다운로드 시간이 오래걸리면 다운 후 코드가 실행되기 때문에 화면 로딩이 지연된다. cra-bundle analyzer를 통해 번들 파일 분석이 가능한데. npx cra-bundle-anlyzer를 실행하면 번들 파일이 해석되어 이미지로 표시된다. 확인 후 가장 큰 번들을 쪼개고 각 페이지에서 필요한 부분마 호출, 사용하지 않는 부분을 줄여 나가는 작업을 통해 리소스 다운 시간을 줄여나갈 수 있는것이다.
    Code Splitting - Bundle.js(LOGIN, DASHBORD, SETTING 각각의 페이지에서 사용하는 코드들만 다운로드, 중복 코드 제거를 통해 로딩시간을 줄일 수 있다. (페이지별 뿐만 아니라 모듈별로 분할하여 사용하는것도 가능)

Nuxt3에서의 렌더링 성능 최적화

Nuxt3에서는 프레임워크 레벨에서 코드 스플리팅이 자동으로 처리되기 때문에 개발자가 별도로 설정을 조정하지 않아도, Nuxt가 자동으로 페이지 및 컴포넌트 단위로 JavaScript 파일을 분할하여 필요할 때만 로드한다. 그 외에도 Nuxt는 SSR기능을 제공해 최적화 작업을 수행해주어 개발자는 컴포넌트, 페이지 개발에 집중할 수 있는 것이다. 그렇다면 최적화 할 것이 없는가? 그것은 아니다 Vue3의 Composition API와 함께 사용하여 코드분할을 더 효과적으로 사용할 수 있다고 한다. defineAsyncComponent를 사용하면 비동기로 컴포넌트를 정의해 "입력을 위한 대형 폼","모달 혹은 다이얼로그","차트와 그래프"같이 클릭하거나 데이터를 요청했을 때만 컴포넌트를 로드하도록 설정해 성능 개선이 가능하다.
비동기 컴포넌트 사용예시)

src/components/AsyncComponentLoader.vue
// src/components/AsyncComponentLoader.vue
 
 <script setup>
import { defineAsyncComponent, ref } from 'vue';

const LargeForm = defineAsyncComponent(() =>
 import('./LargeForm.vue')
);

const isLoaded = ref(false);
const loadComponent = () => {
 isLoaded.value = true;
};
</script>

<template>
 <button v-if="!isLoaded" @click="loadComponent">Load Form</button>
 <LargeForm v-if="isLoaded" />
</template>

그 외 최적화

웹 사이트 리소스가 매번 서버로부터 새로 로드되지 않도록 캐싱을 통해 최적화가 가능하다. HTTP 캐시 헤더를 설정해 번경하지 않는 리소스 이미지,JS,CSS파일을 브라우저에 저장되게 하거나 CDN을 사용해 로딩시간을 단축시키는것이 가능하다.

성능 측정은 실제 서비스 환경인 프로덕션 빌드 환경에서 실행해보아야 한다. 보통은 개발 환경보다 빌드 환경이 웹 성능이 더 좋은데 그 이유는 JS,CSS,HTML 파일들이 최소화되고 압축되어 크기가 줄어들어 로딩시간이 단축되고, 디버깅을 용이하게 해주는 소스 맵이 비활성화 되며, 코드분할과 지연로딩이 더 잘 적용되기 때문이다. 그렇다면 압축은 어떻게 할까?

대표적으로 텍스트 압축이 있는데 JS,CSS,HTML 파일문서의 사이즈를 줄이기 위해 압축을 사용한다. Response header에 "content-encoding"을 통해 어떤 방식으로 압축하는지 확인이 가능하다. 웹 상에서는 주로 GZIP, Deflate를 사용해 텍스트 압축을 하며 통상 2KB를 넘어가면 압축을 한다고 한다.

profile
러닝커브를 빠르게 극복하자🎢

0개의 댓글