프론트엔드 개발자라면 알아둬야 할 압축방식, Gzip 에 대해서

홍규진·2025년 4월 27일
24

리액트 개발자로서 사용자에게 빠른 경험을 제공하는 것은 선택이 아닌 필수다. 특히 자바스크립트 번들을 Client 에서 부담해야하는 CSR인 리액트 애플리케이션에서는 더욱 그렇다. 따라서 Gzip이라는 것이 왜 중요한지, 어떻게 리액트 프로젝트에 적용하는지 알아둬야만 한다.

(👨🏻‍🏫 : "안녕하세요! 오늘은 리액트 개발자가 알아두면 좋을 Gzip에 대해 알아볼 거예요. 여러분의 리액트 앱을 야무지게 압축해서 번들 크기를 확 줄여주는 마법 같은 기술이랍니다! 배포 방식에 따라서는 이미 사용중에 있을 수도 있어요 ㅎㅎ 아마도 번들링에 대한 지식이 있고난 뒤에 보면 더 좋을 거예요!")

💡급하신 분들을 위해서 결론 먼저!

  1. Gzip은 리액트 번들링 된 후의 번들 파일 자체를 압축하여 전송시의 속도를 높이는 기술이다.
  2. 리액트 앱의 최종 JS 번들 크기를 최대 70%까지 줄일 수 있으며, 이는 리액트 앱의 초기 로딩 속도를 크게 개선하여 사용자 경험을 향상시킨다.
  3. Create React App, Vite 등 대부분의 리액트 프레임워크는 빌드 시 Gzip 압축을 추가로 할 수 있다. 다만 추가적인 설정을 해줘야 한다.
  4. Gzip으로 압축을 해제하는 것은 브라우저 단에서 진행한다. 단, 이를 수행해주기 위해선 Encoding-Header를 붙여줘야 한다.
  5. Gzip의 압축과 해제로 인한 시간보다, 네트워크 속도로 인해 얻는 이점이 더 크기에 충분히 택할만한 선택지이다.

번들링과 Gzip의 차이점 및 관계

번들링과 Gzip 압축은 웹 개발에서 서로 다른 단계에서 발생하는 최적화 기술이지만, 상호 보완적인 관계를 가지고 있다.

번들링이란?

번들링은 여러 개의 JavaScript 파일과 모듈을 하나 또는 여러 개의 최적화된 파일로 결합하는 과정이다. 이는 주로 Vite, Webpack, Rollup, Parcel과 같은 도구를 사용하여 수행된다.

번들링의 주요 목적:

  • 여러 파일의 HTTP 요청을 줄임 (N 개의 파일을 묶어 한, 두개로 줄인다.)
  • 코드 트랜스파일(ES6 → ES5 등)
  • 코드 최소화(minification)
  • 트리 쉐이킹(사용하지 않는 코드 제거 - ES Module)

Gzip 압축이란?

Gzip은 번들링 이후 단계에서 만들어진 파일을 압축하는 알고리즘이다. 이는 서버에서 클라이언트로 전송되는 데이터의 크기를 줄이는 데 중점을 둔다.

Gzip의 주요 목적:

  • 파일 크기 감소 → 네트워크 전송 시간 단축 → 대역폭 사용량 감소

번들링과 Gzip은 상호 보완적인 관계를 가지고 있으며, 일반적으로 연속적인 과정으로 적용된다:

  1. 번들링 먼저 적용: 여러 파일을 하나로 합치고 최소화(minify)한다.
  2. 그 다음 Gzip 압축: 번들링된 파일을 Gzip으로 압축하여 전송 크기를 더 줄인다.

이 두 기술은 서로 다른 목적을 가지고 있지만, 함께 사용할 때 최상의 결과를 얻을 수 있다. 번들링만 하거나 Gzip만 사용하는 것보다 둘 다 사용하는 것이 훨씬 효과적이다.

(👨🏻‍🏫 : "번들링과 Gzip은 마치 짝꿍 같은 존재예요! 번들링으로 파일 수를 줄이고, Gzip으로 최종적으로 파일 크기를 줄이는 거죠. 둘 다 사용해야 최고의 성능을 얻을 수 있답니다! 그런데 의문이 하나 드는 게 우리는 zip 파일로 보통 압축을 하면 이를 다시 풀어야 하잖아요? 이를 다시 풀어야 하는 것도 고려해야하지 않을까요?")

"No, there is no downside on the decompression side when using the maximum compression level. In fact, there is a slight upside, in that better-compressed data takes less time to transfer over the network."

“최대 압축 수준을 사용할 때에도, 압축 해제 측면에서는 단점이 없습니다. 실제로는 약간의 이점이 있는데, 더 잘 압축된 데이터는 네트워크를 통한 전송 시간이 적게 걸립니다.”

https://stackoverflow.com/questions/28452429/does-gzip-compression-level-have-any-impact-on-decompression

(👨🏻‍🏫 : "실제로, 압축 레벨 9로 압축된 콘텐츠의 압축 해제 속도는, 압축 레벨 6보다 약 0.9% 더 빠르다는 테스트 결과도 있습니다. 이는 다소 놀라운 결과입니다. 즉 압축의 단계에 거의 차이가 없다는 소리죠. 이처럼 압축 해제에 많은 시간이 안 들어서, 압축 해제에 필요한 시간보다 네트워크 전송에서 얻는 이점이 훨씬 더 커요. 따라서 저희는 줄어드는 네트워크 비용에 대해서만 이점을 가져가고, 손해는 안 보는 셈이죠! 보통은 트레이드 오프가 있는데, 이는 그것 또한 없어요 ㅎㅎ 안 쓸 이유가 없겠죠?")

1. Gzip이란 무엇인가?

Gzip은 웹에서 파일을 압축하고 전송하기 위한 파일 형식이자 소프트웨어 애플리케이션이다. 1992년에 처음 공개되었으며, GNU 프로젝트의 일환으로 개발되었다. 리액트와 같은 현대적인 자바스크립트 프레임워크에서는 특히 중요한 역할을 한다.

Gzip의 동작 원리

Gzip은 LZ77 알고리즘Deflate 압축 방식을 사용한다. 이 방식은 무손실 압축(lossless compression)으로, 데이터를 압축하고 해제하는 과정에서 원본 데이터가 완벽하게 보존된다.

LZ77 알고리즘 관련 블로그 해당 알고리즘에 대해선 깊게 다루진 않겠습니다..! (진짜 잘 정리해두셨어요!)

리액트 애플리케이션에서 Gzip이 작동하는 방식을 살펴보면:

  1. npm run build 명령으로 리액트 앱을 빌드하면 JS, CSS 파일이 생성된다
  2. 서버측에서나, 빌드 도구가 이 파일들을 Gzip으로 압축한다
  3. 브라우저가 리액트 앱을 요청하면 서버는 압축된 파일을 전송한다.
  4. 브라우저는 받은 파일을 Gzip 파일을 압축 해제하고 리액트 앱을 실행한다.

실제로 리액트 앱의 번들 파일은 Gzip을 통해 원래 크기의 약 30% 수준으로 압축이 가능하다. 예를 들어, 1MB의 리액트 번들이 300KB로 줄어들 수 있다.

리액트 앱에서의 Gzip의 역할

리액트 애플리케이션에서 Gzip은 특히 중요한 역할을 한다:

  1. 큰 번들 파일 압축: 리액트 앱은 종종 큰 JS 번들을 생성하는데, Gzip은 이를 효과적으로 압축한다.
  2. 초기 로딩 시간 단축: 첫 페이지 로드 시 필요한 데이터 전송량을 줄여 초기 로딩 시간을 단축한다.
  3. 코드 스플리팅과 시너지: 리액트의 코드 스플리팅과 함께 사용하면 필요한 코드만 압축하여 전송할 수 있다.

(👨🏻‍🏫 : "리액트 앱에서는 node_modules의 수많은 패키지들이 번들링 후에 번들에 포함되죠. 이런 코드들은 반복되는 패턴이 많아서 Gzip 압축 효율이 정말 좋답니다! 위에서 본 L277 알고리즘을 조금 보시면, 같은 문자열에 한해서 몇 개 존재하는지, 어디 존재하는지 정도로 압축한답니다! 즉 다른 라이브러리라도 그 양식에 한해서는 겹치는 부분이 많으니 효율이 더 좋아져요! ")

2. Gzip이 리액트 성능에 미치는 영향

Gzip은 리액트 애플리케이션의 성능에 직접적이고 긍정적인 영향을 미친다. 구체적으로 살펴보자.

리액트 앱 로딩 속도 향상

리액트 앱에서 가장 큰 병목 중 하나는 초기 번들 로딩 시간이다. Gzip 압축은 이 문제를 해결하는 데 큰 도움이 된다:

  • 번들 크기 감소: 리액트 앱의 JS 번들은 Gzip을 통해 평균 60-70% 압축된다.
  • Time to Interactive(TTI) 개선: 더 작은 번들은 더 빠르게 다운로드되고 파싱되므로 사용자가 앱과 상호작용할 수 있는 시간이 단축된다.
  • First Contentful Paint(FCP) 개선: 마찬가지로 더 작아진 번들을 받아오기에, 그리는 데에 있어서의 시간이 더 줄어들게 된다.
  • Largest Contentful Paint(LCP): 주요 콘텐츠가 로드되는 시간이 단축된다.
  • Total Blocking Time(TBT): JS 실행 시간이 줄어들어 메인 스레드 차단 시간이 감소한다.
  • Cumulative Layout Shift(CLS): 리소스가 빠르게 로드되어 레이아웃 변경이 줄어든다.

이러한 지표들은 Google의 Core Web Vitals의 일부로, 웹사이트의 SEO에 직접적인 영향을 미친다.

(👨🏻‍🏫 : "Lighthouse 점수를 높이고 싶으신가요? Gzip은 거의 모든 성능 지표를 개선해주는 필수 요소예요! 우선 Gzip을 통해 한 차례 높이고, 이후에 개별적으로 점수를 신경쓰면 좋지 않을까요?")

3. 리액트 프로젝트에 Gzip 적용 방법

리액트 프로젝트에 Gzip을 적용하는 방법은 여러 가지가 있다. 보통은 빌드 도구에 따라서 방법이 달라진다. 가장 일반적인 방법들을 살펴보자.

Create React App(CRA)에서 Gzip 적용

Create React App으로 만든 프로젝트는 빌드 시 자동으로 Gzip 압축을 지원하지 않는다. 다음과 같은 방법으로 적용할 수 있다:

compression-webpack-plugin 사용하기

  1. 먼저 CRA를 eject하거나 react-app-rewired를 설치한다:
npm install --save-dev react-app-rewired
  1. compression-webpack-plugin을 설치한다:
npm install --save-dev compression-webpack-plugin
  1. config-overrides.js 파일을 생성하고 다음 코드를 추가한다:
const CompressionPlugin = require('compression-webpack-plugin');

module.exports = function override(config, env) {
  config.plugins.push(
    new CompressionPlugin({
      algorithm: 'gzip',
      test: /\.(js|css|html|svg)$/,
      threshold: 10240,
      minRatio: 0.8,
    })
  );
  return config;
}
  1. CLI로 간편하게 하기 위해서 package.json의 스크립트를 수정한다:
"scripts": {
  "start": "react-app-rewired start",
  "build": "react-app-rewired build",
  "test": "react-app-rewired test"}

CRACO 사용하기

CRA를 eject하지 않고 webpack 설정을 변경하는 또 다른 방법은 CRACO(@craco/craco)를 사용하는 것이다:

*# 프로젝트 루트 디렉토리에서
# 설정 파일 생성*
touch craco.config.js

*# craco와 webpack 플러그인 설치*
npm install -D @craco/craco compression-webpack-plugin
*// craco.config.js*
const CompressionPlugin = require('compression-webpack-plugin');

module.exports = {
  webpack: {
    plugins: [
      new CompressionPlugin({ algorithm: 'gzip' }),
    ],
  },
};

그리고 마찬가지로 CLI로 편하게 쓰기 위해서 package.json의 스크립트를 수정한다:

"scripts": {
  "start": "react-scripts start",
  "build": "craco build",
  "build-cra": "react-scripts build",
  "test": "react-scripts test",
  "eject": "react-scripts eject"
}

Vite에서 Gzip 적용 방법

Vite는 최신 프론트엔드 빌드 도구로, React 프로젝트에서도 널리 사용된다. Vite에서 Gzip 압축을 적용하는 방법을 알아보자. ( CRA는 이제 React 에서 당분간 업데이트 하지 않는다고 했으니, Vite를 선호하는 경향이 있다.)

vite-plugin-compression 사용하기

Vite는 기본적으로 빌드된 파일을 압축하지 않는다. 이를 위해 vite-plugin-compression 플러그인을 사용하여 Gzip 압축을 활성화할 수 있다. 이 플러그인은 빌드 과정에서 자동으로 파일을 압축해준다.

  1. 먼저 플러그인을 설치한다:
npm install vite-plugin-compression --save-dev
  1. vite.config.js 또는 vite.config.ts 파일에 플러그인을 추가한다:
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import viteCompression from 'vite-plugin-compression';

export default defineConfig({
  plugins: [
    react(),
    viteCompression({
      verbose: true,
      disable: false,
      threshold: 10240,
      algorithm: 'gzip',
      ext: '.gz',
    }),
  ],
});

(👨🏻‍🏫 : "Vite에서는 플러그인 설정이 정말 간단해요! vite.config.js를 통해서 관리를 해요! 몇 줄의 코드만으로 Gzip 압축을 적용할 수 있답니다. 게다가 빌드 속도도 CRA보다 훨씬 빠르죠! CRA는 이제 당분간 업데이트를 안 한다고 리엑트 팀에서 발표했으니, Vite 로 넘어와서 이참에 Gzip도 같이 써보는 게 어떨까요? ")

설정 옵션 설명

vite-plugin-compression 플러그인은 다양한 옵션을 제공한다:

  • verbose: true로 설정하면 압축 결과를 콘솔에 출력한다.
  • disable: true로 설정하면 플러그인을 비활성화한다.
  • threshold: 이 크기(바이트)보다 큰 파일만 압축한다. 기본값은 1025이다.
  • algorithm: 압축 알고리즘을 지정한다. 'gzip', 'brotliCompress', 'deflate', 'deflateRaw' 중 선택할 수 있다.
  • ext: 생성된 압축 파일의 확장자를 지정한다. 기본값은 .gz이다.
  • deleteOriginFile: true로 설정하면 압축 후 원본 파일을 삭제한다.

Gzip과 Brotli 동시 적용하기

더 나은 압축률을 위해 Gzip과 뒤에서 다룰 내용인 Brotli(구글에서 만든 압축 방식)를 동시에 적용할 수도 있다:

import { defineConfig } from "vite";
import react from '@vitejs/plugin-react';
import compression from "vite-plugin-compression";

export default defineConfig({
  plugins: [
    react(),
    compression({ algorithm: "gzip" }),
    compression({ algorithm: "brotliCompress" })
  ],
});

압축 효과 확인하기

압축 적용 전후의 파일 크기 차이를 확인해보면 그 효과를 실감할 수 있다:

적용 전:
dist/assets/index.1234.js → 450 KB (원본 크기)

적용 후:
dist/assets/index.1234.js → 120 KB (Gzip 적용 후)
dist/assets/index.1234.js → 95 KB (Brotli 적용 후)

이는 Gzip으로 약 70%, Brotli로 약 80%의 크기 감소를 의미한다. 네트워크 요청에서 전송해야 할 데이터가 크게 줄어들어 로딩 속도가 훨씬 빨라진다!

적용 확인 방법

  1. Vite 빌드를 실행한다:
npm run build
  1. 빌드된 파일을 서버로 실행하여 테스트한다:
npx serve dist
  1. Chrome 개발자 도구의 Network 탭에서 content-encoding: br 또는 content-encoding: gzip이 표시되면 정상적으로 적용된 것이다.

(👨🏻‍🏫 : "실제로 압축 적용 후에는 개발자 도구에서 파일 크기가 확 줄어든 것을 볼 수 있어요! 특히 큰 JS 번들의 경우 그 차이가 더 극적이랍니다! br 은 브로틀리를, gzip은 gzip 방식으로 압축된 것을 의미해요! 번들링을 끝냈으면, 해당 번들 파일을 이용해서 배포를 해야겠죠? 근데, “ 빌드 당시에 Gzip을 통해 압축하고나면 이 압축을 언젠간 풀어야 하는 거 아닌가?” 싶은 생각이 들어야 합니다! 그러나 S3에는 Gzip을 해제하는 기능이 없어요. 단순히 이를 브라우저에 제공할 뿐이죠. 그럼 어떻게 이를 해제할까요? 순서는 다음과 같답니다!")

S3 정적 배포와 Gzip 압축 파일 처리 방식

S3 자체는 파일을 압축하거나 압축을 해제하는 기능이 없다. 대신, 다음과 같은 방식으로 Gzip 압축 파일을 처리한다:

  1. 빌드 시 파일 압축: 먼저 로컬에서 파일을 Gzip으로 압축합니다.
  2. 압축된 상태로 S3에 업로드: 압축된 파일을 그대로 S3에 업로드합니다.
  3. Content-Encoding 헤더 설정: 업로드 시 Content-Encoding: gzip 메타데이터를 설정합니다.
  4. 브라우저의 자동 압축 해제: 브라우저는 Content-Encoding: gzip 헤더를 보고 자동으로 압축을 해제합니다.

이 방식에서 S3는 단순히 압축된 파일을 저장하고 제공하는 역할만 하며, 실제 압축 해제는 클라이언트(브라우저)에서 이루어집니다.

(👨🏻‍🏫 : "잠시만 그러면 굳이 내가 압축을 해서 넘기는 게 아니라, AWS 에서 이를 해주는 기능이 있으면 엄청 좋지 않을까??”라고 생각했었는데, 찾아보니까 정말 있습니다… ㅎㅎ 심지어는 제가 썼었던 CloudFront 에서 설정을 통해서 적용할 수 있더라구요!! 결국엔 브라우저에서 gzip 이나 br 양식해제를 하니 저희는 그 전 단계에서 AWS에게 위임할 건지, 직접 Gzip 압축을 할 건지에 대해서 정하면 되겠죠?")

AWS S3에 정적 배포 시 Gzip 적용 방법

AWS S3에 리액트 앱을 정적 배포할 때 Gzip을 적용하는 방법은 다음과 같다:

빌드 시 파일 압축하기

먼저 위에서 설명한 방법(compression-webpack-plugin, Vite 플러그인, CRACO)을 사용하여 빌드 시 .gz 파일을 생성한다.

S3에 업로드 시 Content-Encoding 헤더 설정

S3는 자동으로 Gzip 압축을 지원하지 않기 때문에, 파일을 업로드할 때 Content-Encoding 헤더를 설정해야 한다. AWS CLI를 사용하는 경우:

*# 압축된 JS 파일 업로드*
aws s3 cp ./build/static/js/main.chunk.js.gz s3://your-bucket-name/static/js/main.chunk.js --content-encoding gzip --content-type application/javascript

*# 압축된 CSS 파일 업로드*
aws s3 cp ./build/static/css/main.chunk.css.gz s3://your-bucket-name/static/css/main.chunk.css --content-encoding gzip --content-type text/css

CloudFront와 함께 사용하기 (⚠️ 위의 설명한 방식과 같이 사용하면 이중 압축입니다 ⚠️)

S3와 CloudFront를 함께 사용하면 더 효과적인 배포가 가능하다:

  1. S3 버킷을 CloudFront의 오리진으로 설정한다.
  2. CloudFront 배포 설정에서 압축을 활성화한다.

CloudFront는 자동으로 특정 파일 유형(HTML, CSS, JS 등)을 Gzip으로 압축할 수 있다. 이 경우에는 S3에 미리 압축된 파일을 업로드할 필요가 없다. 즉 앞선 빌드 단계에서 Gzip 압축할 필요 없이 그냥 올리면 된다.

//설정이 영어일 때,
CloudFront 설정 > Behaviors > Edit > Compress Objects Automatically: Yes

// 한국어일때
CloudFront 설정 > 동작 > 편집 > 자동으로 객체 압축: Yes

(default로는 Yes로 설정이 되어있습니다...!)

라이브러리에서의 Gzip 사용

리액트 라이브러리를 개발하고 배포할 때도 Gzip 압축을 고려해야 한다:

라이브러리 번들 크기 최적화

라이브러리 개발 시 번들 크기를 최소화하기 위한 방법:

  • 트리 쉐이킹 지원: ES 모듈 형식으로 라이브러리를 배포하여 사용자가 필요한 부분만 가져갈 수 있도록 한다.
  • 외부 의존성 최소화: 불필요한 의존성을 줄이고, 필요한 경우 peerDependencies로 설정한다.
  • 코드 스플리팅: 큰 기능은 별도의 청크로 분리하여 필요할 때만 로드되도록 한다.

라이브러리 배포 시 Gzip 정보 제공

라이브러리 문서나 README에 Gzip 압축 후 크기 정보를 제공하는 것이 좋다:

## 번들 크기

- 원본: 120KB
- Minified: 45KB
- Gzipped: 15KB

이를 자동화하기 위해 bundlesize 또는 size-limit와 같은 도구를 사용할 수 있다:

npm install --save-dev size-limit @size-limit/preset-small-lib

package.json에 설정:

{
  "size-limit": [
    {
      "path": "dist/index.js",
      "limit": "10 KB",
      "gzip": true
    }
  ]
}

(👨🏻‍🏫 : "라이브러리 개발자라면 번들 크기에 더 신경 써야 해요! 동일한 기능을 하는 라이브러리가 있다고 하더라도, 이 방식이 해당 라이브러리를 택하는 이유 중에 하나가 될 수도 있고, 그게 아니더라도, 여러분의 라이브러리가 사용자 앱의 번들 크기에 직접적인 영향을 미치니까요. Gzip 압축 후 크기를 항상 체크하는 습관을 들이세요!")

4. 리액트 앱의 Gzip 적용 여부 확인 및 테스트 방법

리액트 앱에 Gzip이 제대로 적용되었는지 확인하는 방법을 알아보자.

개발자 도구를 활용한 리액트 앱 Gzip 확인

  1. 웹사이트를 열고 F12 또는 Ctrl+Shift+I(Windows) / Cmd+Option+I(Mac)를 눌러 개발자 도구를 연다.
  2. Network 탭을 선택한다.
  3. 페이지를 새로고침한다.
  4. 리소스 목록에서 HTML, CSS, JS 파일을 확인한다.
  5. 응답 헤더에서 `Content-Encoding: gzip 혹은 br(브로틀리)` 이 있는지 확인한다.
  6. Content-Encoding 헤더가 없거나 identity 값을 가지고 있다면, 해당 리소스는 압축되지 않은 상태로 전송된 것입니다

  1. Size/Content 열을 확인하여 압축 전후의 크기 차이를 확인한다.
  2. 구글에서도 자기들이 만든 br 만을 쓰는 게 아니라, Gzip도 사용한다는 것을 알 수 있다 ㅎㅎ

온라인 도구 활용

여러 온라인 도구를 사용하여 웹사이트의 Gzip 상태를 확인할 수 있다:

  • PageSpeed Insights: 페이지 속도와 함께 텍스트 압축 상태를 분석한다.
  • GTmetrix: 웹사이트 성능을 분석하고 Gzip 압축 상태를 확인한다.

(👨🏻‍🏫 : "시간이 많다면 꼭 새 웹사이트를 배포하기 전에 이런 도구들로 체크해요. 특히 GTmetrix는 정말 좋은 도구예요. Gzip뿐만 아니라 다양한 성능 지표를 한눈에 볼 수 있거든요! 허허")

리액트 앱 성능 테스트 도구

리액트 앱의 Gzip 압축 효과를 포함한 전체 성능을 테스트할 수 있는 도구들:

  1. Lighthouse: Chrome 개발자 도구에 내장된 Lighthouse를 사용하여 리액트 앱의 성능을 종합적으로 분석할 수 있다.
  2. WebPageTest: 다양한 조건에서 리액트 앱의 로딩 성능을 테스트할 수 있으며, 압축 상태도 확인할 수 있다.
  3. React Developer Tools: 성능 탭을 사용하여 리액트 컴포넌트 렌더링 성능을 분석할 수 있다. Gzip 자체를 확인하지는 않지만 전체 앱 성능을 평가하는 데 유용하다.

리액트 앱 번들 분석

리액트 앱의 번들 크기와 Gzip 압축 후 크기를 분석하는 도구:

  1. webpack-bundle-analyzer: 리액트 앱의 번들 구성을 시각화하고 각 모듈의 크기를 확인할 수 있다.
npm install --save-dev webpack-bundle-analyzer

CRA에서 사용하려면 react-app-rewired와 함께 설정:

*// config-overrides.js*
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');

module.exports = function override(config, env) {
  if (process.env.ANALYZE) {
    config.plugins.push(
      new BundleAnalyzerPlugin()
    );
  }
  
  return config;
}

그리고 package.json에 스크립트 추가:

"scripts": {
  "analyze": "ANALYZE=true react-app-rewired build"
}

이 도구들을 사용하면 리액트 앱의 어떤 부분이 가장 큰 공간을 차지하는지, Gzip 압축 후 얼마나 줄어드는지 확인할 수 있다.

(👨🏻‍🏫 : "webpack-bundle-analyzer는 리액트 앱을 최적화할 때 정말 유용한 도구예요! 어떤 라이브러리가 번들 크기를 많이 차지하는지 한눈에 볼 수 있고, Gzip 압축 후 크기도 확인할 수 있어요. 이를 통해 불필요한 의존성을 제거하거나 대체할 수 있죠!")

5. Gzip의 라이벌 브로틀리(Brotli)

브로틀리(Brotli)는 Google이 개발한 새로운 압축 알고리즘으로, Gzip보다 더 나은 압축률을 제공한다. 주요 특징은 다음과 같다:

  • Gzip보다 14-26% 더 나은 압축률을 제공한다.
  • 압축 및 압축 해제 속도가 합리적이다.
  • 대부분의 최신 브라우저에서 지원된다.

브로틀리와 Gzip을 비교하면:

특성Gzip브로틀리
압축률좋음매우 좋음
압축 속도빠름대체로 빠르되, 높은 압축 수준에서는 낮음
압축 해제 속도빠름빠름
브라우저 지원거의 모든 브라우저대부분의 최신 브라우저
서버 지원광범위함증가 중

브로틀리는 Gzip을 완전히 대체하기보다는 보완하는 역할을 한다. 최신 브라우저를 사용하는 사용자에게는 브로틀리를, 오래된 브라우저를 사용하는 사용자에게는 Gzip을 제공하는 방식으로 함께 사용할 수 있다.

(👨🏻‍🏫 : "브로틀리는 정말 좋은 기술이에요! 하지만 아직 Gzip만큼 널리 지원되지는 않아요. 가능하다면 두 가지를 모두 제공하는 것이 가장 좋은 전략이랍니다. 브라우저가 지원하면 브로틀리를, 아니면 Gzip을 사용하도록요!")

브로틀리(Brotli)와 리액트 앱

브로틀리(Brotli)는 Google이 개발한 새로운 압축 알고리즘으로, Gzip보다 더 나은 압축률을 제공한다. 리액트 앱에 적용했을 때의 장점:

  • 리액트 JS 번들을 Gzip보다 15-25% 더 작게 압축할 수 있다.
  • 압축 해제 속도가 빨라 클라이언트 측 성능에 부담이 적다.
  • 특히 텍스트 기반 파일(JS, CSS)에서 효과적이다.

리액트 앱에 브로틀리 적용하기:

  1. CRA에서 브로틀리 적용:
*// config-overrides.js*
const CompressionPlugin = require('compression-webpack-plugin');
const zlib = require('zlib');

module.exports = function override(config, env) {
  config.plugins.push(
    new CompressionPlugin({
      filename: '[path].br[query]',
      algorithm: 'brotliCompress',
      test: /\.(js|css|html|svg)$/,
      compressionOptions: {
        level: 11,
      },
      threshold: 10240,
      minRatio: 0.8,
    })
  );
  return config;
}

리액트 앱의 미래와 Gzip

리액트 생태계와 웹 기술은 계속 발전하고 있으며, 이에 따라 Gzip의 역할도 변화하고 있다:

  • 리액트 서버 컴포넌트: React 18에서 도입된 서버 컴포넌트는 클라이언트로 전송되는 JS의 양을 줄여준다. 이는 Next.js 와 같은 제로 번들링이 있긴 하지만, 프레임 워크 자체라는 특성 때문에, React 를 결국 택하게 되는데, 이 때는 Gzip과 함께 사용하면 더욱 효과적이다.
  • Vite와 같은 빌드 도구: ESM을 활용한 새로운 빌드 도구들은 더 작고 효율적인 번들을 생성한다. 이러한 번들은 Gzip으로 압축했을 때 더 좋은 결과를 보인다.
  • WebAssembly: 리액트 앱의 일부를 WebAssembly로 구현하는 경우가 늘고 있다. WebAssembly 모듈은 이미 바이너리 형식이지만, 여전히 Gzip 압축의 이점을 얻을 수 있다.

(👨🏻‍🏫 : "리액트 생태계는 계속 발전하고 있어요! 서버 컴포넌트, Suspense for Data Fetching 등의 새로운 기능들이 번들 크기를 줄이는 데 도움을 주고 있죠. 하지만 Gzip과 같은 압축 기술은 결국엔 파일 크기를 줄여야 하기에, 여전히 중요한 역할을 할 거예요. 이는 리액트 앱의 성능 최적화는 사용자 경험을 향상시키는 핵심 요소이며, Gzip은 이를 위한 필수 도구입니다!! 번들 크기 감소, 로딩 시간 단축, 대역폭 절감 등 다양한 이점을 제공하는 Gzip을 리액트 프로젝트에 적극 활용해보는 게 어떨까요?")

🙇🏻 글 내에 틀린 점, 오탈자, 비판, 공감 등 모두 적어주셔도 됩니다. 감사합니다..! 🙇🏻

profile
읽는 사람이 가장 이해하기 쉽게끔 적으려 노력합니다. 그 과정에서 스스로가 완전한 이해를 할 수 있다고 생각합니다. 그렇게 Taker 보다는 Giver이 되려 노력합니다.

2개의 댓글

comment-user-thumbnail
2025년 5월 2일

단순히 자바스크립트 번들 파일을 줄여야 한다고만 아는 것을 넘어서서, 구체적으로 어떻게 줄일 수 있는지 해결책을 제공해주신 포스팅 감사합니다!
저도 직접 적용해봐야겠네요 (˘︶˘).:*

답글 달기
comment-user-thumbnail
2025년 9월 29일

You can play block blast anytime anywhere as long as you have free time.

답글 달기