HTMLミニファイとは?
HTMLミニファイとは、ブラウザのレンダリング結果を変えることなく、HTMLドキュメントのサイズを削減するプロセスです。HTMLミニファイアーは、開発者の可読性のためだけに存在する文字を除去します。タグ間の空白、コメント、省略可能な閉じタグ、冗長な属性値などがその対象です。出力はソースと機能的に同一でありながら、バイトサイズが小さくなるため、ダウンロードが速くなり、ユーザーの初回描画までの時間が短縮されます。
ブラウザはHTMLをDOMツリーに解析する際に、ほとんどの空白を破棄します。2つのdivタグの間にある連続したスペースや改行は、レンダリングされたページにまったく視覚的な影響を与えません。コメントもパーサーによって無視されます。ミニファイはこれらのルールを活用し、パーサーがいずれ破棄するものを事前に除去することで、ネットワーク経由で転送されることなく済むようにします。
HTMLミニファイによる削減効果はドキュメントによって異なります。コメントが多いテンプレート、深いインデントを持つサーバーレンダリングページ、インラインスタイルが含まれるCMS出力では、ミニファイだけで15〜30%のサイズ削減が見込めます。小さなドキュメントでは絶対的な削減量は控えめですが、高トラフィックなサイトでは数キロバイトのページ削減が何百万リクエストにわたって積み重なり、実際の帯域節約になります。
このHTMLミニファイアーを使う理由
HTMLを貼り付けるだけで、即座に圧縮済みの出力が得られます。ビルドツールのインストールも、設定ファイルも、アカウント登録も不要です。
HTMLミニファイアーの使用例
HTMLミニファイが除去するもの
本格的なHTMLミニファイアーは、空白除去以外にもいくつかの変換を適用します。下の表は一般的な手法を、最も安全(常にロスレス)から最も積極的(闇雲に適用するとエッジケースで問題が生じる可能性)の順に示しています。
| 手法 | 変換前 | 変換後 |
|---|---|---|
| Whitespace between tags | <div> <p> text </p> </div> | <div><p>text</p></div> |
| HTML comments | <!-- TODO: fix later --> | (removed entirely) |
| Redundant attribute quotes | class="main" | class=main |
| Boolean attribute values | disabled="disabled" | disabled |
| Empty attribute values | id="" | (attribute removed) |
| Optional closing tags | </li>, </td>, </p> | (removed when safe) |
| Type on script/style | type="text/javascript" | (removed — default) |
| Protocol in URLs | https://cdn.example.com | //cdn.example.com |
ミニファイ vs Gzip圧縮
サーバーがすでにGzipまたはBrotli圧縮を適用しているのにミニファイが必要かどうか、開発者から尋ねられることがあります。簡単な答え:はい、両方を組み合わせると最も効果的です。
ミニファイはGzipが処理する入力を削減するため、圧縮後の出力もより小さくなります。GoogleのPageSpeedガイドラインでは両方を適用することを推奨しています。一般的なページでは、ミニファイで生のサイズの15〜25%が削減され、さらにGzipで結果が60〜80%圧縮されます。組み合わせることで、総転送サイズは元のミニファイなし・圧縮なしのドキュメントの10〜20%程度まで削減できます。
コード例
以下は4つの環境でHTMLミニファイを行う実用的な例です。各例ではコメントの削除と空白の圧縮を行います。
import { minify } from 'html-minifier-terser'
const html = `
<div class="card">
<!-- user profile -->
<p> Hello, world! </p>
</div>
`
const result = await minify(html, {
collapseWhitespace: true,
removeComments: true,
removeRedundantAttributes: true,
removeEmptyAttributes: true,
})
// → '<div class="card"><p>Hello, world!</p></div>'import htmlmin html = """ <div class="card"> <!-- user profile --> <p> Hello, world! </p> </div> """ result = htmlmin.minify(html, remove_comments=True, remove_empty_space=True) # → '<div class="card"><p>Hello, world!</p></div>'
package main
import (
"fmt"
"github.com/tdewolff/minify/v2"
"github.com/tdewolff/minify/v2/html"
)
func main() {
m := minify.New()
m.AddFunc("text/html", html.Minify)
input := `<div class="card">
<!-- user profile -->
<p> Hello, world! </p>
</div>`
result, _ := m.String("text/html", input)
fmt.Println(result)
// → <div class=card><p>Hello, world!</div>
}# Install globally npm install -g html-minifier-terser # Minify a file html-minifier-terser --collapse-whitespace --remove-comments input.html -o output.html # Pipe from stdin cat index.html | html-minifier-terser --collapse-whitespace --remove-comments # With all common optimizations html-minifier-terser \ --collapse-whitespace \ --remove-comments \ --remove-redundant-attributes \ --remove-empty-attributes \ --minify-css true \ --minify-js true \ input.html -o output.min.html