🚄

Nginxにgzipより性能の良さそうなBrotli圧縮を導入してみた

2024/11/21に公開

概要

  • Nginxで今までデータをgzip圧縮形式で配信していた。
  • Brotliという高速圧縮術を用いた圧縮があったのでそれを設定してみた。

Brotliとは

Brotliは、Webサイトのファイルサイズを縮小するためにGoogleが開発したオープンソースの圧縮アルゴリズムです。Gzipと比較して、平均20%高い圧縮率を誇り、大きなファイル圧縮に最適化されています。

Brotliは、HTMLやJavaScriptで頻出されるフレーズが含まれる静的辞書を用いて圧縮しています。
圧縮レベルは0から11まで12段階が用意されており、数字が大きくなるほど圧縮率が高くなります。
ただし、圧縮率が高くなるほどより多くの計算リソースを消費するため、ブラウザのレンダリングやCDN側の負荷が高くなる可能性があります。

  • BrotliはGzipに比べて15%ほど圧縮できていることがわかりました。
  • BrotliはGzipと比較して、同じ速度でより小さなファイルに圧縮し、同じ速度で解凍します。
  • 元ファイルが大きければ大きいほどBrotliの効果が高くでています。
  • Brotliをレベル11で圧縮することで、ユーザーはファイルサイズを最高のGzip圧縮レベルと比較して19%小さくすることができます。
  • gzipはほとんどの場合Brotliに速度で勝るものの、圧縮するレベルによって結果が異なります。

導入方法

DockerFile

# ベースイメージを指定
FROM ubuntu:22.04 as builder

# 必要なパッケージをインストール
RUN apt update && apt install -y \
    libpcre3 libpcre3-dev zlib1g zlib1g-dev openssl libssl-dev wget git gcc make libbrotli-dev \
    && rm -rf /var/lib/apt/lists/*

# Nginxとngx_brotliモジュールのビルド
WORKDIR /app
RUN wget https://nginx.org/download/nginx-1.25.3.tar.gz \
    && tar -zxf nginx-1.25.3.tar.gz \
    && git clone --recurse-submodules https://github.com/google/ngx_brotli \
    && cd nginx-1.25.3 \
    && ./configure --with-compat --add-dynamic-module=../ngx_brotli \
    && make modules

# Nginxのベースイメージを使用
FROM nginx:1.25.3

# ビルドしたモジュールをコピー
COPY --from=builder /app/nginx-1.25.3/objs/ngx_http_brotli_static_module.so /etc/nginx/modules/
COPY --from=builder /app/nginx-1.25.3/objs/ngx_http_brotli_filter_module.so /etc/nginx/modules/

# Brotliの設定を追加
RUN { \
    echo 'brotli on;'; \
    echo 'brotli_comp_level 6;'; \
    echo 'brotli_static on;'; \
    echo 'brotli_types application/atom+xml application/javascript application/json application/rss+xml'; \
    echo '          application/vnd.ms-fontobject application/x-font-opentype application/x-font-truetype'; \
    echo '          application/x-font-ttf application/x-javascript application/xhtml+xml application/xml'; \
    echo '          font/eot font/opentype font/otf font/truetype image/svg+xml image/vnd.microsoft.icon'; \
    echo '          image/x-icon image/x-win-bitmap text/css text/javascript text/plain text/xml;'; \
    } > /etc/nginx/conf.d/brotli.conf

1. 準備

  • 必要な依存関係のインストール: Brotli圧縮をサポートするために、Nginxをビルドする前に、libbrotli-devを含む依存パッケージをインストールする必要があります。
RUN apt update && apt install -y \
    libpcre3 libpcre3-dev zlib1g zlib1g-dev openssl libssl-dev wget git gcc make libbrotli-dev \
    && rm -rf /var/lib/apt/lists/*

2. Nginxのソースコードのダウンロード

  • Nginxの公式サイトから最新バージョン(または必要なバージョン)のソースコードをダウンロードします。
RUN wget https://nginx.org/download/nginx-1.25.3.tar.gz \
    && tar -zxf nginx-1.25.3.tar.gz \

3. ngx_brotliモジュールのクローン

  • Brotli圧縮機能を提供するngx_brotlモジュールのソースコードをGitHubからクローンします。このモジュールは、Brotli圧縮と展開の両方をNginxで実現します。
 git clone --recurse-submodules https://github.com/google/ngx_brotli \

4. ビルド設定の実行

  • Nginxのソースディレクトリに移動し、./configurスクリプトを実行してビルドを設定します。
    この際に、--add-dynamic-moduleオプションを使用して、ngx_brotliモジュールのパスを指定します。
cd nginx-1.25.3 \
 ./configure --with-compat --add-dynamic-module=../ngx_brotli \

5. Nginxのビルドとモジュールのコンパイル

  • 設定に基づき、makコマンドを実行してNginxとngx_brotlモジュールをビルドしますmake moduleコマンドにより、指定したモジュールのみをコンパイルすることもできます。
make modules

Nginx

user  nginx;
worker_processes auto;

pid        /var/run/nginx.pid;

load_module modules/ngx_http_brotli_filter_module.so;
load_module modules/ngx_http_brotli_static_module.so;

http {
       ~~ 省略 ~~ 

        brotli on;
        brotli_types text/css application/javascript application/json application/font-woff application/font-tff image/gif image/png image/jpeg application/octet-stream;
    }
}

実際の挙動

Content-Encodingがbrになっている。
速度的にはちょっと速くなっているかも(微妙)

まとめ

  • どのアルゴリズムが最強というより、いずれも一長一短ある。
  • ファイルのサイズが大きくなるほど、Brotliの効果が出そう

※画像は以下より引用

https://hidekatsu-izuno.hatenablog.com/entry/2016/07/06/003803

Discussion