이 Codelab은 네트워크 페이로드 축소 및 압축 Codelab의 확장이며 압축의 기본 개념을 잘 알고 있다고 가정합니다. 이 Codelab에서는 gzip
와 같은 다른 압축 알고리즘과 비교하여 Brotli 압축 (br
)이 압축 비율과 앱의 전체 크기를 어떻게 더 줄일 수 있는지 알아봅니다.
측정
최적화를 추가하기 전에 항상 애플리케이션의 현재 상태를 먼저 분석하는 것이 좋습니다.
- 리믹스하여 수정을 클릭하여 프로젝트를 수정할 수 있도록 합니다.
- 사이트를 미리 보려면 앱 보기를 누릅니다. 그런 다음 전체 화면
을 누릅니다.
이전 네트워크 페이로드 축소 및 압축 Codelab에서는 main.js
의 크기를 225KB에서 61.6KB로 줄였습니다. 이 Codelab에서는 Brotli 압축을 통해 이 번들 크기를 더욱 줄이는 방법을 알아봅니다.
Brotli 압축
Brotli는 gzip
보다 더 나은 텍스트 압축 결과를 제공할 수 있는 최신 압축 알고리즘입니다. CertSimple에 따르면 Brotli 성능은 다음과 같습니다.
- JavaScript용
gzip
보다 14% 작음 - HTML의 경우
gzip
보다 21% 작음 - CSS의 경우
gzip
보다 17% 작음
Brotli를 사용하려면 서버에서 HTTPS를 지원해야 합니다. Brotli는 모든 최신 브라우저에서 지원됩니다. Brotli를 지원하는 브라우저는 Accept-Encoding
헤더에 br
를 포함합니다.
Accept-Encoding: gzip, deflate, br
Chrome 개발자 도구 네트워크 탭(Command+Option+I
또는 Ctrl+Alt+I
)의 Content-Encoding
필드를 사용하여 사용된 압축 알고리즘을 확인할 수 있습니다.

Brotli 사용 설정 방법
Brotli로 인코딩된 리소스를 전송하도록 웹 서버를 설정하는 방법은 리소스를 인코딩할 방법에 따라 다릅니다. 요청 시 Brotli로 리소스를 동적으로 압축하거나 (동적) 사용자가 요청할 때 이미 압축되어 있도록 미리 인코딩 (정적)할 수 있습니다.
동적 압축
동적 압축은 브라우저에서 요청할 때 애셋을 즉시 압축하는 것입니다.
장점
- 저장된 압축 버전의 애셋을 만들고 업데이트할 필요가 없습니다.
- 즉석 압축은 특히 동적으로 생성되는 웹페이지에 적합합니다.
단점
- 더 나은 압축률을 위해 높은 수준으로 파일을 압축하는 데 시간이 더 오래 걸립니다. 이로 인해 사용자가 서버에서 전송되기 전에 애셋이 압축될 때까지 기다리므로 성능이 저하될 수 있습니다.
Node 및 Express를 사용한 동적 압축
server.js
파일은 애플리케이션을 호스팅하는 Node 서버를 설정하는 역할을 합니다.
const express = require('express');
const app = express();
app.use(express.static('public'));
const listener = app.listen(process.env.PORT, function() {
console.log(`Your app is listening on port ${listener.address().port}`);
});
이렇게 하면 express
가 가져와지고 express.static
미들웨어가 사용되어 public/directory
에 있는 모든 정적 HTML, JS, CSS 파일이 로드됩니다 (이러한 파일은 빌드할 때마다 webpack에 의해 생성됨).
애셋이 요청될 때마다 brotli를 사용하여 압축되도록 하려면 shrink-ray
모듈을 사용하면 됩니다. 먼저 package.json
에서 devDependency
로 추가합니다.
"devDependencies": {
// ...
"shrink-ray": "^0.1.3"
},
서버 파일 server.js
에 가져옵니다.
const express = require('express');
const shrinkRay = require('shrink-ray');
express.static
가 마운트되기 전에 미들웨어로 추가합니다.
// ...
const app = express();
// Compress all requests
app.use(shrinkRay());
app.use(express.static('public'));
이제 앱을 새로고침하고 네트워크 패널에서 번들 크기를 확인합니다.

이제 Content-Encoding
헤더에서 brotli
이 bz
에서 적용된 것을 확인할 수 있습니다.
main.bundle.js
이 225KB에서 53.1KB로 줄어들었습니다. 이는 gzip
(61.6KB)에 비해 약 14% 더 작습니다.
정적 압축
정적 압축의 개념은 애셋을 미리 압축하고 저장하는 것입니다.
장점
- 높은 압축 수준으로 인한 지연 시간은 더 이상 문제가 되지 않습니다. 이제 파일을 직접 가져올 수 있으므로 파일을 압축하기 위해 즉시 실행해야 하는 작업이 없습니다.
단점
- 애셋은 빌드할 때마다 압축해야 합니다. 높은 압축 수준을 사용하면 빌드 시간이 크게 늘어날 수 있습니다.
webpack을 사용한 Node 및 Express의 정적 압축
정적 압축은 파일을 미리 압축하는 것이므로 빌드 단계의 일부로 애셋을 압축하도록 webpack 설정을 수정할 수 있습니다. 이를 위해 brotli-webpack-plugin
을 사용할 수 있습니다.
먼저 package.json
에서 devDependency
로 추가합니다.
"devDependencies": {
// ...
"brotli-webpack-plugin": "^1.1.0"
},
다른 webpack 플러그인과 마찬가지로 구성 파일 webpack.config.js
에서 가져옵니다.
var path = require("path");
//...
var BrotliPlugin = require('brotli-webpack-plugin');
플러그인 배열에 포함합니다.
module.exports = {
// ...
plugins: [
// ...
new BrotliPlugin({
asset: '[file].br',
test: /\.(js)$/
})
]
},
플러그인 배열은 다음 인수를 사용합니다.
asset
: 대상 애셋 이름입니다.[file]
이 원본 애셋 파일 이름으로 대체됩니다.test
: 이 정규식과 일치하는 모든 애셋 (즉,.js
로 끝나는 JavaScript 애셋)이 처리됩니다.
예를 들어 main.js
은 main.js.br
로 이름이 바뀝니다.
앱이 다시 로드되고 다시 빌드되면 이제 기본 번들의 압축 버전이 생성됩니다. Glitch 콘솔을 열어 Node 서버에서 제공하는 최종 public/
디렉터리 내의 내용을 확인합니다.
- 도구 버튼을 클릭합니다.
- 콘솔 버튼을 클릭합니다.
- 콘솔에서 다음 명령어를 실행하여
public
디렉터리로 변경하고 모든 파일을 확인합니다.
cd public
ls -lh

번들의 brotli 압축 버전인 main.bundle.js.br
도 이제 여기에 저장되며 main.bundle.js
보다 크기가 약 76% 더 작습니다 (225KB 대 53KB).
그런 다음 원래 JS 버전이 요청될 때마다 서버에서 이러한 brotli 압축 파일을 전송하도록 지시합니다. 이렇게 하려면 express.static
로 파일을 제공하기 전에 server.js
에서 새 경로를 정의하면 됩니다.
const express = require('express');
const app = express();
app.get('*.js', (req, res, next) => {
req.url = req.url + '.br';
res.set('Content-Encoding', 'br');
res.set('Content-Type', 'application/javascript; charset=UTF-8');
next();
});
app.use(express.static('public'));
app.get
은 특정 엔드포인트에 대한 GET
요청에 서버가 응답하는 방법을 알려주는 데 사용됩니다. 그런 다음 콜백 함수를 사용하여 이 요청을 처리하는 방법을 정의합니다. 경로는 다음과 같이 작동합니다.
'*.js'
를 첫 번째 인수로 지정하면 JS 파일을 가져오기 위해 실행되는 모든 엔드포인트에서 작동합니다.- 콜백 내에서
.br
이 요청의 URL에 연결되고Content-Encoding
응답 헤더가br
로 설정됩니다. Content-Type
헤더는 MIME 유형을 지정하기 위해application/javascript; charset=UTF-8
로 설정됩니다.- 마지막으로
next()
는 시퀀스가 다음 콜백으로 계속되도록 합니다.
일부 브라우저에서는 brotli 압축을 지원하지 않을 수 있으므로 Accept-Encoding
요청 헤더에 br
가 포함되어 있는지 확인하여 brotli가 지원되는지 확인한 후 brotli 압축 파일을 반환하세요.
const express = require('express');
const app = express();
app.get('*.js', (req, res, next) => {
if (req.header('Accept-Encoding').includes('br')) {
req.url = req.url + '.br';
console.log(req.header('Accept-Encoding'));
res.set('Content-Encoding', 'br');
res.set('Content-Type', 'application/javascript; charset=UTF-8');
}
next();
});
app.use(express.static('public'));
앱이 새로고침되면 네트워크 패널을 다시 살펴보세요.

완료되었습니다. Brotli 압축을 사용하여 애셋을 더 압축했습니다.
결론
이 Codelab에서는 brotli
를 사용하여 앱의 전체 크기를 추가로 줄이는 방법을 설명했습니다. 지원되는 경우 brotli
는 gzip
보다 강력한 압축 알고리즘입니다.