imagemin、imagemin-webp、sharp、webp-converterはすべてNode.js環境で画像(特にWebP形式)を処理するためのnpmパッケージですが、その設計と用途は大きく異なります。imageminはプラグインベースの画像最適化フレームワークであり、imagemin-webpはそのWebP変換用プラグインです。sharpは高性能なネイティブ画像処理ライブラリで、WebPを含む多様なフォーマットをサポートします。webp-converterはGoogleのcwebpコマンドをラップしたシンプルな変換ツールですが、現在はメンテナンスが停滞しており、新規プロジェクトでの使用は推奨されません。
Webアプリケーションで画像を効率的に扱う際、特にモダンなフォーマットであるWebPへの変換はパフォーマンス向上に大きく貢献します。しかし、Node.jsエコシステムには複数の選択肢があり、それぞれ設計思想や利用シーンが異なります。ここでは、imagemin、imagemin-webp、sharp、webp-converterの4つのパッケージを、実際の開発者の視点から深く比較します。
imagemin は、画像最適化のためのプラグインベースのフレームワークです。単体では画像処理を行わず、imagemin-webpのような外部プラグインに処理を委ねます。
// imagemin + imagemin-webp
const imagemin = require('imagemin');
const imageminWebp = require('imagemin-webp');
(async () => {
await imagemin(['images/*.{jpg,png}'], {
destination: 'build/images',
plugins: [imageminWebp({ quality: 80 })]
});
})();
imagemin-webp は、imagemin用のプラグインであり、内部で cwebp コマンド(Googleが提供するWebPエンコーダ)を呼び出します。つまり、Node.jsプロセス外のバイナリに依存しています。
sharp は、ネイティブC++拡張(libvipsライブラリ)を直接使用する高性能画像処理ライブラリです。WebPだけでなく、JPEG、PNG、AVIFなど幅広いフォーマットに対応しており、変換だけでなくリサイズ、クロップ、フィルタ適用なども可能です。
// sharp
const sharp = require('sharp');
(async () => {
await sharp('input.jpg')
.webp({ quality: 80 })
.toFile('output.webp');
})();
webp-converter は、cwebpおよびdwebpコマンドラインツールをラップしたシンプルなインターフェースを提供します。内部で子プロセスを起動して外部ツールを実行するため、Node.jsとは独立した実行環境に依存します。
// webp-converter
const webp = require('webp-converter');
(async () => {
const result = await webp.cwebp('input.jpg', 'output.webp', '-q 80');
console.log(result); // 'converted'
})();
⚠️ 注意:
webp-converterは2023年時点でメンテナンスが停滞しており、npmページにも「このパッケージは非推奨(deprecated)ではありませんが、新しいプロジェクトではsharpの使用を検討してください」と記載されています。ただし、公式に「deprecated」と明記されているわけではありません。
imagemin / imagemin-webp: 純粋なフォーマット変換と圧縮に特化。リサイズやトリミングなどの操作はできません。sharp: リサイズ、回転、色調整、合成、メタデータ操作など、画像処理全般に対応。webp-converter: WebP変換専用。他の操作は一切サポートしていません。sharp は最も柔軟で、ファイルパスだけでなく、BufferやStreamを直接扱えます。
// sharp with Buffer
const inputBuffer = fs.readFileSync('input.jpg');
const outputBuffer = await sharp(inputBuffer).webp().toBuffer();
一方、imagemin や webp-converter は基本的にファイルパスを前提としており、メモリ上のデータを直接処理するには一時ファイルを経由する必要があります。
sharp: libvipsはマルチスレッド対応で、大規模な画像処理でも高速。メモリ効率も良好。imagemin-webp / webp-converter: 各変換ごとに cwebp プロセスを起動するため、オーバーヘッドが大きく、大量の画像処理には不向き。例:100枚の画像を変換する場合、sharpは1つのNode.jsプロセス内で並列処理可能ですが、webp-converterは100回の子プロセス起動が必要です。
sharp: ネイティブモジュールのため、node-gypによるビルドが必要。ただし、事前ビルド済みバイナリ(prebuilds)が提供されており、多くの環境で問題なく動作します。imagemin-webp / webp-converter: システムに cwebp コマンドがインストールされている必要があります。DockerコンテナやCI環境では追加のセットアップ(例:apt-get install webp)が必須です。# webp-converterを使用する場合のDockerfile例
RUN apt-get update && apt-get install -y webp
一方、sharpは依存関係をすべて含むため、追加のOSパッケージ不要でデプロイ可能です。
imagemin + imagemin-webp// next.config.jsでの例(next-optimized-imagesなどと組み合わせて)
module.exports = {
images: {
loader: 'custom',
// imageminプラグインを内部で使用
}
};
sharp// Express.jsでの例
app.post('/upload', async (req, res) => {
const buffer = req.file.buffer;
const webpBuffer = await sharp(buffer)
.resize(800)
.webp({ quality: 75 })
.toBuffer();
// DBまたはストレージに保存
});
webp-converter(ただし新規プロジェクトでは非推奨)sharpsharpが優れているため。| パッケージ | 最適な利用シーン | 主な制約 |
|---|---|---|
imagemin | ビルドパイプラインでの静的アセット最適化 | 動的処理やBuffer操作には不向き |
imagemin-webp | imageminと組み合わせたWebP変換 | cwebpのインストールが必要 |
sharp | 動的画像処理、高パフォーマンス要件、多機能処理 | ネイティブモジュールのビルドが必要(ただしprebuildsあり) |
webp-converter | レガシー環境での簡易変換(新規プロジェクトでは避ける) | パフォーマンス劣化、外部依存、メンテナンス不安定 |
sharp を選ぶべきです。機能、パフォーマンス、柔軟性の面で圧倒的に優れています。imagemin + imagemin-webp も有効です。ただし、cwebpのインストールという追加コストがあります。webp-converter は、既存のレガシーコードを維持する場合を除き、新しいコードで使うべきではありません。最終的には、「画像処理をどこで行うか(ビルド時 vs 実行時)」と「どの程度の機能が必要か」の2点で判断するのが確実です。
imageminは、ビルドプロセス(例:Webpack、Gulp)の中で静的アセットを最適化したい場合に最適です。プラグインアーキテクチャにより、WebP変換だけでなくPNG圧縮など複数の処理をチェーンできます。ただし、動的な画像処理やメモリ上のBuffer操作には向いておらず、ファイルベースの処理に限定されます。
imagemin-webpは、imageminと組み合わせてWebP変換を行う必要がある場合にのみ使用します。単体では機能せず、システムにcwebpコマンドがインストールされている必要があります。DockerやCI環境では追加のセットアップが必要になる点に注意してください。
sharpは、動的にアップロードされた画像をリアルタイムで処理する必要がある場合や、リサイズ・トリミングなどの高度な操作を伴うWebP変換が必要な場合に最適です。ネイティブモジュールですが、事前ビルド済みバイナリのおかげでほとんどの環境で簡単に導入でき、パフォーマンスと機能面で他の選択肢を上回ります。
webp-converterは、既存のレガシーシステムを維持する場合を除き、新規プロジェクトでの使用は避けてください。内部で子プロセスを頻繁に起動するためパフォーマンスが悪く、cwebpへの依存も運用負荷になります。同様の要件があれば、代わりにsharpを検討すべきです。
Minify images seamlessly
npm install imagemin
import imagemin from 'imagemin';
import imageminJpegtran from 'imagemin-jpegtran';
import imageminPngquant from 'imagemin-pngquant';
const files = await imagemin(['images/*.{jpg,png}'], {
destination: 'build/images',
plugins: [
imageminJpegtran(),
imageminPngquant({
quality: [0.6, 0.8]
})
]
});
console.log(files);
//=> [{data: <Uint8Array 89 50 4e …>, destinationPath: 'build/images/foo.jpg'}, …]
Returns Promise<object[]> in the format {data: Uint8Array, sourcePath: string, destinationPath: string}.
Type: string[]
File paths or glob patterns.
Type: object
Type: string
Set the destination folder to where your files will be written. If no destination is specified, no files will be written.
Type: Array
The plugins to use.
Type: boolean
Default: true
Enable globbing when matching file paths.
Returns Promise<Uint8Array>.
Type: Uint8Array
The image data to optimize.
Type: object
Type: Array
Plugins to use.