2 个版本
0.0.2 | 2023 年 12 月 24 日 |
---|---|
0.0.1 | 2023 年 12 月 22 日 |
#552 in 文本处理
11,491 每月下载量
用于 23 个 Crates (2 个直接使用)
60KB
1.5K SLoC
minify-html
一个精心优化以提高速度和效率的 Rust HTML 压缩器,同时提供了其他语言的绑定。
- 高级压缩策略在效率上优于其他压缩器,同时速度更快。
- 处理 无效 HTML 和 模板语法。
- 使用 minify-js 和 lightningcss 进行超快的 JS 和 CSS 压缩。
查看 变更日志 了解最新更新。
性能
与html-minifier和minimize在顶级网页上的比较。详情请见这里。
onepass变体在速度优化方面更加出色。更多详情请见其README。
兼容性和使用
CLI
CLI名为minhtml。预编译的二进制文件适用于Linux(ARM64和x64)、macOS(ARM64和x64)和Windows(x64)。您可以在GitHub发行版中下载它们。
如果您已安装Cargo,也可以从源代码构建和安装: cargo install minhtml
。
使用
使用--help
参数获取更多详细信息。
minhtml --output /path/to/output.min.html --keep-closing-tags --minify-css /path/to/src.html
快速并行处理一批文件
minhtml --keep-closing-tags --minify-css /path/to/**/*.html
Deno
使用
import init, {minify} from "https://wilsonl.in/minify-html/deno/0.15.0/index.js";
const encoder = new TextEncoder();
const decoder = new TextDecoder();
await init();
const minified = decoder.decode(minify(encoder.encode("<p> Hello, world! </p>"), { keep_spaces_between_attributes: true, keep_comments: true }));
所有Cfg
字段都作为对象提供的第二个参数的snake_case属性可用;如果未设置,则默认为false
。
Node.js
- 包:@minify-html/node
- 绑定:Neon
- 平台:Linux(ARM64和x64)、macOS(ARM64和x64)、Windows(x64);Node.js 8.6.0及以上
获取
使用npm
npm i @minify-html/node
使用Yarn
yarn add @minify-html/node
使用
提供TypeScript定义。
import { Buffer } from "node:buffer";
import minifyHtml from "@minify-html/node";
// Or `const minifyHtml = require("@minify-html/node")` if not using TS/ESM.
const minified = minifyHtml.minify(Buffer.from("<p> Hello, world! </p>"), { keep_spaces_between_attributes: true, keep_comments: true });
所有Cfg
字段都作为对象提供的第二个参数的snake_case属性可用;如果未设置,则默认为false
。
Java
- 包:in.wilsonl.minifyhtml
- 绑定:JNI
- 平台:Linux(ARM64和x64)、macOS(ARM64和x64)、Windows(x64);Java 7及以上
获取
作为Maven依赖项添加
<dependency>
<groupId>in.wilsonl.minifyhtml</groupId>
<artifactId>minify-html</artifactId>
<version>0.15.0</version>
</dependency>
使用
import in.wilsonl.minifyhtml.Configuration;
import in.wilsonl.minifyhtml.MinifyHtml;
Configuration cfg = new Configuration.Builder()
.setKeepHtmlAndHeadOpeningTags(true)
.setMinifyCss(true)
.build();
String minified = MinifyHtml.minify("<p> Hello, world! </p>", cfg);
所有Cfg
字段都作为Builder
上的camelCase设置方法可用;如果未设置,则默认为false
。
Python
- 包:minify-html
- 绑定:PyO3
- 平台:Linux(ARM64和x64)、macOS(ARM64和x64)、Windows(x64);Python 3.8到3.12
获取
将PyPI项目作为依赖项添加,并使用pip
或pipenv
安装。
使用
import minify_html
minified = minify_html.minify("<p> Hello, world! </p>", minify_js=True, remove_processing_instructions=True)
所有 Cfg
字段 都可以作为 Python 关键字参数使用;如果省略任何字段,它们将默认为 False
。
Ruby
- 包: minify_html
- 绑定: rb-sys 和 magnus
- 平台:Linux(ARM64和x64)、macOS(ARM64和x64)、Windows(x64);Ruby 2.7 到 3.2
获取
将库作为依赖项添加到 Gemfile
或 *.gemspec
。
使用
require 'minify_html'
print minify_html("<p> Hello, world! </p>", { :keep_spaces_between_attributes => true, :minify_js => true })
所有 Cfg
字段 都可用;如果省略任何字段,它们将默认为 false
。
WASM
- 包: @minify-html/wasm
- 绑定:WASM
- 平台:所有
可能需要 bundler 来使用 WebAssembly 模块,更多详情请参阅 此处。
使用
import init, {minify} from "@minify-html/wasm";
const encoder = new TextEncoder();
const decoder = new TextDecoder();
await init();
const minified = decoder.decode(minify(encoder.encode("<p> Hello, world! </p>"), { keep_spaces_between_attributes: true, keep_comments: true }));
所有Cfg
字段都作为对象提供的第二个参数的snake_case属性可用;如果未设置,则默认为false
。
模板语法
minify-html 可以解析并保留源代码中的 {{
/{%
/{#
和 <%
语法,这允许对为大多数引擎(如 Pebble、Mustache、Django、Go、Jinja、Twix、Nunjucks、Handlebars、Sailfish、JSP、EJS 和 ERB)编写的许多 HTML 模板进行压缩。查找 preserve_*_template_syntax
Cfg 选项。
PHP 块(<?php
或 <?=
)也恰好是处理指令,默认情况下将保留。
请注意,在这些语法中,解析是“愚笨”的:它将简单地寻找下一个与闭合定界符匹配的字符子序列。如果这些块内部有嵌套或字符串字面量,可能会导致问题,但这种情况应该很少。
压缩
规范合规性
WHATWG 是当前 HTML 标准,并 废弃了所有先前标准。WHATWG 在此处列出了建议的验证器 这里。
为了进一步压缩,可以启用可能输出不符合验证的 HTML 的选项,但仍根据 WHATWG 解析规范(Firefox、Chrome、Safari 等主要浏览器引擎实现)进行解释和渲染。请参阅这些选项
allow_noncompliant_unquoted_attribute_values
allow_optimal_entities
allow_removing_spaces_between_attributes
minify_doctype
在 Rust 中,Cfg::enable_possibly_noncompliant
可以一次性启用所有这些选项。
空白字符
minify-html 具有高级上下文感知空白字符压缩功能,例如
- 在
pre
和code
中保留空白字符,这些标签对空白字符敏感。 - 在内容标签中修剪和折叠空白字符,因为渲染时空白字符将无论如何折叠。
- 在布局标签中删除空白字符,这允许使用内联布局同时保持格式化代码。
方法
有三种空白字符压缩方法。在处理文本内容时,minify-html 根据包含元素选择使用哪种方法。
折叠空白字符
适用范围:除空格敏感元素之外的所有元素。
将文本节点中的空格字符序列缩减为单个空格(U+0020)。
之前 | 之后 |
---|---|
|
|
删除整个空格
删除标签之间只包含空格字符的任何文本节点。
之前 | 之后 |
---|---|
|
|
去除空格
删除标签的前导/尾随文本节点中的任何前导/尾随空格。
之前 | 之后 |
---|---|
|
|
元素类型
minify-html假定HTML和SVG元素以特定方式使用,基于标准和最佳实践。通过做出这些假设,它可以应用最佳空格最小化策略。如果这些假设不成立,请考虑调整HTML源或关闭空格最小化。
组 | 元素 | 预期子元素 |
---|---|---|
格式化 | a 、strong 、以及其他 |
格式化元素,文本。 |
内容 | h1 、p 、以及其他 |
格式化元素,文本。 |
布局 | div 、ul 、以及其他 |
布局元素,内容元素。 |
内容优先 | label 、li 、以及其他 |
与内容类似,但可以作为一个只有一个子元素布局元素。 |
格式化元素
空格被压缩。
格式化元素通常是行内元素,它们围绕内容元素中的部分文本进行包装,因此其空格不会被修剪,因为它们可能是内容的一部分。
内容元素
空格被修剪和压缩。
内容元素通常代表一个连续的完整内容单元,如段落。因此,空格很重要,但它们通常是格式化导致的序列。
之前
<p>↵
··Hey,·I·<em>just</em>·found↵
··out·about·this·<strong>cool</strong>·website!↵
··<sup>[1]</sup>↵
</p>
之后
<p>Hey,·I·<em>just</em>·found·out·about·this·<strong>cool</strong>·website!·<sup>[1]</sup></p>
布局元素
空格被修剪和压缩。整个空格被删除。
这些元素应只包含其他元素,没有文本。这使得删除整个空格成为可能,这在使用display: inline-block
时非常有用,这样元素之间的空格(例如缩进)就不会改变布局和样式。
之前
<ul>↵
··<li>A</li>↵
··<li>B</li>↵
··<li>C</li>↵
</ul>
之后
<ul><li>A</li><li>B</li><li>C</li></ul>
内容优先元素
空格被修剪和压缩。
这些元素通常是类似内容元素,但偶尔也像只有一个子元素布局元素一样使用。整个空格没有被删除,因为它可能包含内容,但这是可以的,因为只有一个子元素,空格被修剪。
之前
<li>↵
··<article>↵
····<section></section>↵
····<section></section>↵
··</article>↵
</li>
之后
<li><article><section></section><section></section></article></li>
标签
可选的打开和关闭标签被删除。
属性
属性值中的任何实体被解码,然后计算并使用值的最短表示形式
- 使用双引号,并编码任何
"
。 - 单引号内的内容,使用任何
'
编码。 - 未引号的内容,使用
"
/'
的第一个字符(如果适用),任何>
,以及任何空白字符编码。
属性在解码后的空白字符将被修剪和合并。
布尔属性的值将被移除。如果它们的值在处理后为空或默认值,则一些其他属性将被完全移除。
对于具有等于 JavaScript MIME 类型的值的 script
标签上的 type
属性将被移除。
如果属性值在处理后为空,则除了名称之外的所有内容都将被完全移除(即没有 =
),因为空属性隐式地与具有空字符串值的属性相同。
当可能时,属性之间移除空格。
实体
如果有效且解码后的长度较短或相等,则解码实体。具有较短的实体表示的 UTF-8 序列将被编码。
不引用有效 Unicode 标量值的数值实体将被替换为 替换字符。
当可能时避免编码;例如,只有当它们后面跟随有效的标签名称字符时,<
才会在内容中编码。如果需要,将选择最短的实体表示。
注释
注释将被移除。
忽略
感叹号、处理指令和空元素不会移除,因为假定它们的声明有特殊原因。
解析
minify-html 可以处理任何 HTML,优雅地处理所有可能的语法(包括无效的语法),就像浏览器一样。有关详细信息,请参阅 Parsing.md。
问题和贡献
欢迎提交拉取请求和任何贡献!
如果 minify-html 做了意外的事情,误解了一些语法,或者错误地保留/删除了一些代码,请提出问题,并提供一些相关的代码,这些代码可以用来重现和调查问题。
依赖项
~1–1.3MB
~20K SLoC