c84b54ce29caa60129f2ac441e1240b6d3b650f1
[html-minifier.git] / README.md
1 # HTMLMinifier
2
3 [![NPM version](https://img.shields.io/npm/v/html-minifier.svg)](https://www.npmjs.com/package/html-minifier)
4 [![Build Status](https://img.shields.io/travis/kangax/html-minifier.svg)](https://travis-ci.org/kangax/html-minifier)
5 [![Dependency Status](https://img.shields.io/david/kangax/html-minifier.svg)](https://david-dm.org/kangax/html-minifier)
6 [![devDependency Status](https://img.shields.io/david/dev/kangax/html-minifier.svg)](https://david-dm.org/kangax/html-minifier?type=dev)
7 [![Gitter](https://img.shields.io/gitter/room/kangax/html-minifier.svg)](https://gitter.im/kangax/html-minifier)
8
9 [HTMLMinifier](http://kangax.github.io/html-minifier/) is a highly **configurable**, **well-tested**, JavaScript-based HTML minifier.
10
11 See [corresponding blog post](http://perfectionkills.com/experimenting-with-html-minifier/) for all the gory details of [how it works](http://perfectionkills.com/experimenting-with-html-minifier/#how_it_works), [description of each option](http://perfectionkills.com/experimenting-with-html-minifier/#options), [testing results](http://perfectionkills.com/experimenting-with-html-minifier/#field_testing) and [conclusions](http://perfectionkills.com/experimenting-with-html-minifier/#cost_and_benefits).
12
13 [Test suite is available online](http://kangax.github.io/html-minifier/tests/).
14
15 Also see corresponding [Ruby wrapper](https://github.com/stereobooster/html_minifier), and for Node.js, [Grunt plugin](https://github.com/gruntjs/grunt-contrib-htmlmin), [Gulp module](https://github.com/jonschlinkert/gulp-htmlmin), [Koa middleware wrapper](https://github.com/koajs/html-minifier) and [Express middleware wrapper](https://github.com/melonmanchan/express-minify-html).
16
17 For lint-like capabilities take a look at [HTMLLint](https://github.com/kangax/html-lint).
18
19 ## Minification comparison
20
21 How does HTMLMinifier compare to other solutions — [HTML Minifier from Will Peavy](http://www.willpeavy.com/minifier/) (1st result in [Google search for "html minifier"](https://www.google.com/#q=html+minifier)) as well as [htmlcompressor.com](http://htmlcompressor.com) and [minimize](https://github.com/Swaagie/minimize)?
22
23 | Site                                                                         | Original size *(KB)* | HTMLMinifier | minimize | Will Peavy | htmlcompressor.com |
24 | ---------------------------------------------------------------------------- |:--------------------:| ------------:| --------:| ----------:| ------------------:|
25 | [Google](https://www.google.com/)                                            | 45                   | **42**       | 45       | 46         | 45                 |
26 | [Twitter](https://twitter.com/)                                              | 126                  | **92**       | 118      | 137        | 118                |
27 | [HTMLMinifier](https://github.com/kangax/html-minifier)                      | 140                  | **109**      | 118      | 122        | 117                |
28 | [New York Times](https://www.nytimes.com/)                                   | 211                  | **144**      | 163      | 159        | 148                |
29 | [Stack Overflow](https://stackoverflow.com/)                                 | 262                  | **207**      | 216      | 224        | 214                |
30 | [Bootstrap CSS](https://getbootstrap.com/docs/3.3/css/)                      | 272                  | **260**      | 269      | 229        | 269                |
31 | [BBC](https://www.bbc.co.uk/)                                                | 286                  | **231**      | 278      | 281        | 265                |
32 | [Amazon](https://www.amazon.co.uk/)                                          | 366                  | **313**      | 353      | 364        | n/a                |
33 | [Wikipedia](https://en.wikipedia.org/wiki/President_of_the_United_States)    | 473                  | **441**      | 457      | 473        | 457                |
34 | [NBC](https://www.nbc.com/)                                                  | 676                  | **636**      | 672      | 675        | n/a                |
35 | [Eloquent Javascript](https://eloquentjavascript.net/1st_edition/print.html) | 870                  | **815**      | 840      | 864        | n/a                |
36 | [ES6 table](https://kangax.github.io/compat-table/es6/)                      | 4808                 | **4095**     | 4548     | n/a        | n/a                |
37 | [ES6 draft](https://tc39.github.io/ecma262/)                                 | 6099                 | **5435**     | 5597     | n/a        | n/a                |
38
39 ## Options Quick Reference
40
41 Most of the options are disabled by default.
42
43 | Option                         | Description     | Default |
44 |--------------------------------|-----------------|---------|
45 | `caseSensitive`                | Treat attributes in case sensitive manner (useful for custom HTML tags) | `false` |
46 | `collapseBooleanAttributes`    | [Omit attribute values from boolean attributes](http://perfectionkills.com/experimenting-with-html-minifier/#collapse_boolean_attributes) | `false` |
47 | `collapseInlineTagWhitespace`  | Don't leave any spaces between `display:inline;` elements when collapsing. Must be used in conjunction with `collapseWhitespace=true` | `false` |
48 | `collapseWhitespace`           | [Collapse white space that contributes to text nodes in a document tree](http://perfectionkills.com/experimenting-with-html-minifier/#collapse_whitespace) | `false` |
49 | `conservativeCollapse`         | Always collapse to 1 space (never remove it entirely). Must be used in conjunction with `collapseWhitespace=true` | `false` |
50 | `customAttrAssign`             | Arrays of regex'es that allow to support custom attribute assign expressions (e.g. `'<div flex?="{{mode != cover}}"></div>'`) | `[ ]` |
51 | `customAttrCollapse`           | Regex that specifies custom attribute to strip newlines from (e.g. `/ng-class/`) | |
52 | `customAttrSurround`           | Arrays of regex'es that allow to support custom attribute surround expressions (e.g. `<input {{#if value}}checked="checked"{{/if}}>`) | `[ ]` |
53 | `customEventAttributes`        | Arrays of regex'es that allow to support custom event attributes for `minifyJS` (e.g. `ng-click`) | `[ /^on[a-z]{3,}$/ ]` |
54 | `decodeEntities`               | Use direct Unicode characters whenever possible | `false` |
55 | `html5`                        | Parse input according to HTML5 specifications | `true` |
56 | `ignoreCustomComments`         | Array of regex'es that allow to ignore certain comments, when matched | `[ /^!/ ]` |
57 | `ignoreCustomFragments`        | Array of regex'es that allow to ignore certain fragments, when matched (e.g. `<?php ... ?>`, `{{ ... }}`, etc.)  | `[ /<%[\s\S]*?%>/, /<\?[\s\S]*?\?>/ ]` |
58 | `includeAutoGeneratedTags`     | Insert tags generated by HTML parser | `true` |
59 | `keepClosingSlash`             | Keep the trailing slash on singleton elements | `false` |
60 | `maxLineLength`                | Specify a maximum line length. Compressed output will be split by newlines at valid HTML split-points |
61 | `minifyCSS`                    | Minify CSS in style elements and style attributes (uses [clean-css](https://github.com/jakubpawlowicz/clean-css)) | `false` (could be `true`, `Object`, `Function(text)`) |
62 | `minifyJS`                     | Minify JavaScript in script elements and event attributes (uses [UglifyJS](https://github.com/mishoo/UglifyJS2)) | `false` (could be `true`, `Object`, `Function(text, inline)`) |
63 | `minifyURLs`                   | Minify URLs in various attributes (uses [relateurl](https://github.com/stevenvachon/relateurl)) | `false` (could be `String`, `Object`, `Function(text)`) |
64 | `preserveLineBreaks`           | Always collapse to 1 line break (never remove it entirely) when whitespace between tags include a line break. Must be used in conjunction with `collapseWhitespace=true` | `false` |
65 | `preventAttributesEscaping`    | Prevents the escaping of the values of attributes | `false` |
66 | `processConditionalComments`   | Process contents of conditional comments through minifier | `false` |
67 | `processScripts`               | Array of strings corresponding to types of script elements to process through minifier (e.g. `text/ng-template`, `text/x-handlebars-template`, etc.) | `[ ]` |
68 | `quoteCharacter`               | Type of quote to use for attribute values (' or ") | |
69 | `removeAttributeQuotes`        | [Remove quotes around attributes when possible](http://perfectionkills.com/experimenting-with-html-minifier/#remove_attribute_quotes) | `false` |
70 | `removeComments`               | [Strip HTML comments](http://perfectionkills.com/experimenting-with-html-minifier/#remove_comments) | `false` |
71 | `removeEmptyAttributes`        | [Remove all attributes with whitespace-only values](http://perfectionkills.com/experimenting-with-html-minifier/#remove_empty_or_blank_attributes) | `false` (could be `true`, `Function(attrName, tag)`) |
72 | `removeEmptyElements`          | [Remove all elements with empty contents](http://perfectionkills.com/experimenting-with-html-minifier/#remove_empty_elements) | `false` |
73 | `removeOptionalTags`           | [Remove optional tags](http://perfectionkills.com/experimenting-with-html-minifier/#remove_optional_tags) | `false` |
74 | `removeRedundantAttributes`    | [Remove attributes when value matches default.](http://perfectionkills.com/experimenting-with-html-minifier/#remove_redundant_attributes) | `false` |
75 | `removeScriptTypeAttributes`   | Remove `type="text/javascript"` from `script` tags. Other `type` attribute values are left intact | `false` |
76 | `removeStyleLinkTypeAttributes`| Remove `type="text/css"` from `style` and `link` tags. Other `type` attribute values are left intact | `false` |
77 | `removeTagWhitespace`          | Remove space between attributes whenever possible. **Note that this will result in invalid HTML!** | `false` |
78 | `sortAttributes`               | [Sort attributes by frequency](#sorting-attributes--style-classes) | `false` |
79 | `sortClassName`                | [Sort style classes by frequency](#sorting-attributes--style-classes) | `false` |
80 | `trimCustomFragments`          | Trim white space around `ignoreCustomFragments`. | `false` |
81 | `useShortDoctype`              | [Replaces the `doctype` with the short (HTML5) doctype](http://perfectionkills.com/experimenting-with-html-minifier/#use_short_doctype) | `false` |
82
83 ### Sorting attributes / style classes
84
85 Minifier options like `sortAttributes` and `sortClassName` won't impact the plain-text size of the output. However, they form long repetitive chains of characters that should improve compression ratio of gzip used in HTTP compression.
86
87 ## Special cases
88
89 ### Ignoring chunks of markup
90
91 If you have chunks of markup you would like preserved, you can wrap them `<!-- htmlmin:ignore -->`.
92
93 ### Preserving SVG tags
94
95 SVG tags are automatically recognized, and when they are minified, both case-sensitivity and closing-slashes are preserved, regardless of the minification settings used for the rest of the file.
96
97 ### Working with invalid markup
98
99 HTMLMinifier **can't work with invalid or partial chunks of markup**. This is because it parses markup into a tree structure, then modifies it (removing anything that was specified for removal, ignoring anything that was specified to be ignored, etc.), then it creates a markup out of that tree and returns it.
100
101 Input markup (e.g. `<p id="">foo`)
102
103
104
105 Internal representation of markup in a form of tree (e.g. `{ tag: "p", attr: "id", children: ["foo"] }`)
106
107
108
109 Transformation of internal representation (e.g. removal of `id` attribute)
110
111
112
113 Output of resulting markup (e.g. `<p>foo</p>`)
114
115 HTMLMinifier can't know that original markup was only half of the tree; it does its best to try to parse it as a full tree and it loses information about tree being malformed or partial in the beginning. As a result, it can't create a partial/malformed tree at the time of the output.
116
117 ## Installation Instructions
118
119 From NPM for use as a command line app:
120
121 ```shell
122 npm install html-minifier -g
123 ```
124
125 From NPM for programmatic use:
126
127 ```shell
128 npm install html-minifier
129 ```
130
131 From Git:
132
133 ```shell
134 git clone git://github.com/kangax/html-minifier.git
135 cd html-minifier
136 npm link .
137 ```
138
139 ## Usage
140
141 For command line usage please see `html-minifier --help`
142
143 ### Node.js
144
145 ```js
146 var minify = require('html-minifier').minify;
147 var result = minify('<p title="blah" id="moo">foo</p>', {
148   removeAttributeQuotes: true
149 });
150 result; // '<p title=blah id=moo>foo</p>'
151 ```
152
153 ## Running benchmarks
154
155 Benchmarks for minified HTML:
156
157 ```shell
158 node benchmark.js
159 ```