brotli로 네트워크 페이로드 축소 및 압축

Michael DiBlasio
Michael DiBlasio

이 Codelab은 네트워크 페이로드 축소 및 압축 Codelab 사용자가 압축의 기본 개념에 익숙하다고 가정합니다. 따라서 gzip와 같은 다른 압축 알고리즘과 비교하여 이 Codelab에서는 Brotli 압축을 사용하면 압축비와 앱 전반적인 속도를 더욱 낮출 수 있습니다. 있습니다.

앱 스크린샷

측정

최적화를 추가하기 전에 항상 먼저 최적화 작업을 현재 상태를 나타냅니다

  1. 수정할 리믹스를 클릭하여 프로젝트를 수정할 수 있도록 합니다.
  2. 사이트를 미리 보려면 앱 보기를 누릅니다. 그런 다음 전체 화면 전체 화면입니다.

이전 네트워크 페이로드 축소 및 압축 Codelab, main.js의 크기를 225KB에서 61.6KB로 줄였습니다. 이 Codelab에서는 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

Content-Encoding를 통해 사용되는 압축 알고리즘을 결정할 수 있습니다. 필드 (Command+Option+I 또는 Ctrl+Alt+I).

Network 패널

Brotli 사용 설정

동적 압축

동적 압축은 애셋을 가져오는 즉시 압축하는 기능입니다. 브라우저에서 요청합니다.

장점

  • 압축된 버전의 애셋을 만들고 업데이트할 필요가 없습니다. 완료되었습니다.
  • 즉석 압축은 생성됩니다.

단점

  • 더 나은 압축률을 얻기 위해 파일을 더 높은 수준에서 압축하려면 더 오래 지속됩니다. 이로 인해 사용자가 애셋이 표시되기를 기다리면서 성능 저하가 발생할 수 있습니다. 압축해야 합니다

Node/Express를 사용한 동적 압축

server.js 파일은 다음을 호스팅하는 노드 서버 설정을 담당합니다. 지정할 수 있습니다

var express = require('express');

var app = express();

app.use(express.static('public'));

var listener = app.listen(process.env.PORT, function() {
  console.log('Your app is listening on port ' + listener.address().port);
});

현재 이 모든 작업은 express를 가져오고 express.static 정적 HTML, JS 및 CSS 파일을 모두 로드하여 public/directory (그리고 이러한 파일은 모든 빌드에서 webpack에 의해 생성됨)

모든 애셋이 생성될 때마다 brotli를 사용하여 압축되도록 하기 위해 shrink-ray 모듈을 사용할 수 있습니다 먼저 package.jsondevDependency로 추가합니다.

"devDependencies": {
  //...
  "shrink-ray": "^0.1.3"
},

그런 다음 서버 파일 server.js로 가져옵니다.

var express = require('express');
var shrinkRay = require('shrink-ray');

express.static가 마운트되기 전에 미들웨어로 추가합니다.

//...
var app = express();

// compress all requests
app.use(shrinkRay());

app.use(express.static('public'));

이제 앱을 새로고침하고 Network 패널에서 번들 크기를 확인합니다.

동적 Brotli 압축을 사용한 번들 크기

이제 Content-Encoding 헤더의 bz에서 brotli가 적용된 것을 확인할 수 있습니다. main.bundle.js225KB에서 53.1KB로 줄었습니다. 약 14% 더 작습니다. (61.6KB) 대비 gzip

정적 압축

정적 압축의 기본 아이디어는 자산을 미리 압축하고 저장하는 것입니다. 할 수 있습니다.

장점

  • 높은 압축 수준으로 인한 지연 시간은 더 이상 문제가 되지 않습니다. 없음 이제 파일을 가져올 수 있으므로 즉시 파일을 압축해야 합니다. 바로 그것입니다.

단점

  • 애셋은 모든 빌드에서 압축되어야 합니다. 빌드 시간이 늘어날 수 있음 높은 압축 수준을 사용하면 크게 높아집니다.

Node/Express 및 webpack을 사용한 정적 압축

정적 압축에는 파일을 미리 압축하는 작업이 포함되므로 webpack 설정은 빌드 단계에서 애셋을 압축하도록 수정될 수 있습니다. 이 이때 brotli-webpack-plugin를 사용할 수 있습니다.

먼저 package.jsondevDependency로 추가합니다.

"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)가 처리됩니다.

예를 들어 main.jsmain.js.br로 이름이 변경됩니다.

앱이 새로고침되고 다시 빌드될 때 기본 번들의 압축된 버전은 되었습니다. Glitch Console을 열고 최종 내용을 확인하세요. 노드 서버에서 제공하는 public/ 디렉터리

  1. 도구 버튼을 클릭합니다.
  2. 콘솔 버튼을 클릭합니다.
  3. 콘솔에서 다음 명령어를 실행하여 public로 변경합니다. 디렉터리의 모든 파일을 확인합니다.
cd public
ls -lh
정적 Brotli 압축을 사용한 번들 크기

이제 번들의 brotli 압축 버전 main.bundle.js.br이 저장됩니다. 크기가 225KB보다 약 76% 더 작습니다 (225KB vs. 53KB). main.bundle.js입니다.

다음으로 이 brotli 압축 파일을 전송할 때마다 전송하도록 원본 JS 버전이 요청되고 있습니다. 이렇게 하려면 파일이 express.static로 제공되기 전에 server.js에서 경로를 지정합니다.

var express = require('express');

var 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 헤더가 application/javascript; charset=UTF-8로 설정됩니다. MIME 유형을 지정합니다.
  • 마지막으로 next()는 시퀀스가 호출될 수 있는 콜백으로 계속 진행되도록 합니다. 있습니다.

일부 브라우저는 brotli 압축을 지원하지 않을 수 있으므로 brotli가 brotli 압축 파일을 반환하기 전에 Accept-Encoding 요청 헤더에 br가 포함됩니다.

var express = require('express');

var 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'));

앱이 새로고침되면 Network 패널을 한 번 더 확인합니다.

번들 크기: 53.1KB (이전 길이: 225KB)

완료되었습니다. 애셋을 추가로 압축하기 위해 Brotli 압축을 사용했습니다.

결론

이 Codelab에서는 brotli를 통해 앱의 전반적인 비용을 더 줄이는 방법을 설명했습니다. 있습니다. 지원되는 경우 brotli는 다음보다 더 강력한 압축 알고리즘입니다. gzip