Improve bench
This commit is contained in:
parent
2e4015de40
commit
7d5ba5033b
|
@ -19,8 +19,7 @@ A Rust HTML minifier meticulously optimised for speed and effectiveness, with bi
|
|||
|
||||
Comparison with [html-minfier](https://github.com/kangax/html-minifier) and [minimize](https://github.com/Swaagie/minimize), run on the top web pages. [See the breakdown here.](./bench)
|
||||
|
||||
<img width="415" alt="Chart showing speed of HTML minifiers" src="https://wilsonl.in/minify-html/bench/0.6.1/core/average-speeds.png">
|
||||
<img width="415" alt="Chart showing compression of HTML minifiers" src="https://wilsonl.in/minify-html/bench/0.6.1/core/average-sizes.png">
|
||||
<img width="415" alt="Chart showing speed of HTML minifiers" src="https://wilsonl.in/minify-html/bench/0.6.1/core/average-speeds.png"><img width="415" alt="Chart showing compression of HTML minifiers" src="https://wilsonl.in/minify-html/bench/0.6.1/core/average-sizes.png">
|
||||
|
||||
The [onepass](https://github.com/wilsonzlin/minify-html/tree/master/rust/onepass) variant is even more optimised for speed. See its [README](https://github.com/wilsonzlin/minify-html/tree/master/rust/onepass) for more details.
|
||||
|
||||
|
|
|
@ -6,12 +6,7 @@ It also contains a set of common web pages as tests for benchmarking.
|
|||
|
||||
## Comparison
|
||||
|
||||
The [Node.js version of minify-html](../nodejs) is tested against [html-minfier](https://github.com/kangax/html-minifier) and [minimize](https://github.com/Swaagie/minimize) in two dimensions:
|
||||
|
||||
- Speed as operations per second.
|
||||
- Minified file size compared to the original.
|
||||
|
||||
[Benchmark.js](https://benchmarkjs.com) is used to determine speed. Each minifier is run against each file in the [tests](./tests) folder, which are HTML pages fetched from popular websites:
|
||||
Each minifier is run against each file in the [inputs](./inputs) folder, which are HTML pages fetched from popular websites:
|
||||
|
||||
|File name|URL|
|
||||
|---|---|
|
||||
|
@ -35,37 +30,14 @@ For more information on how the tests are fetched, see [fetch.js](./fetch.js).
|
|||
|
||||
On this [project's README](../README.md), average graphs are shown. Graphs showing per-test results are shown below:
|
||||
|
||||
<img width="435" alt="Chart showing speed of HTML minifiers per test" src="https://wilsonl.in/minify-html/bench/0.6.1/core/speeds.png"> <img width="435" alt="Chart showing effectiveness of HTML minifiers per test" src="https://wilsonl.in/minify-html/bench/0.6.1/core/sizes.png">
|
||||
<img width="435" alt="Chart showing speed of HTML minifiers per test" src="https://wilsonl.in/minify-html/bench/0.6.1/core/speeds.png"><img width="435" alt="Chart showing effectiveness of HTML minifiers per test" src="https://wilsonl.in/minify-html/bench/0.6.1/core/sizes.png">
|
||||
|
||||
Since speed depends on the input, speed charts show performance relative to the Node.js minify-html as a percentage.
|
||||
|
||||
The settings used for each minifier can be found in [minifiers.js](./minifiers.js). Some settings to note:
|
||||
|
||||
- `conservativeCollapse` is enabled for html-minifier as otherwise some whitespace would be unsafely removed with side effects. minify-html can safely remove whitespace with context if configured properly.
|
||||
Results depend on the input, so charts show performance relative to minify-html as a percentage.
|
||||
|
||||
## Running
|
||||
|
||||
Make sure to install the dependencies listed in [package.json](./package.json) by running `npm i` or `yarn`.
|
||||
Run [build](./build) to build the minifiers.
|
||||
|
||||
Run [build.sh](./build.sh) to build @minify-html/js with the local minify-html.
|
||||
|
||||
Run [sizes.js](sizes.js) to run each HTML minifier against each test and record the minified size results. This will also output the minified files in `min` if inspection of minified outputs is necessary. [compare.sh](./compare.sh) is a useful script for viewing a character-by-character diff between the minified outputs of minify-html and html-minifier for a specific test. Pass the test's file name as the first argument.
|
||||
|
||||
Run [speeds.js](./speeds.js) to benchmark the performance of each HTML minifier against each test and record the op/s results.
|
||||
Run [run](./run) to benchmark the performance of each HTML minifier against each test and record the op/s results.
|
||||
|
||||
Run [graph.js](./graph.js) to render graphs from recorded speed and size results in the `results` folder.
|
||||
|
||||
## minify-html-bench
|
||||
|
||||
The [minify-html-bench](./minify-html-bench) folder contains a Rust executable subproject that runs the local minify-html on all tests for many iterations to calculate speed as operations per second.
|
||||
|
||||
This can be useful for profiling the core code or checking the performance of minify-html in other languages with native bindings.
|
||||
|
||||
It takes two arguments:
|
||||
|
||||
- `--tests`: path to the folder containing tests to use as inputs.
|
||||
- `--iterations`: how many iterations to run per test.
|
||||
|
||||
The results will be written to stdout as a JSON object, where properties are the test file names and values are the operations per second.
|
||||
|
||||
Profiling minify-html can be done on Linux by using [profile.sh](./profile.sh), which uses `perf`. The generated report can be used using `perf report`.
|
||||
|
|
120
bench/graph.js
120
bench/graph.js
|
@ -1,7 +1,7 @@
|
|||
const results = require("./results");
|
||||
const fs = require("fs/promises");
|
||||
const https = require("https");
|
||||
const path = require("path");
|
||||
const fs = require("fs/promises");
|
||||
const results = require("./results");
|
||||
|
||||
const GRAPHS_DIR = path.join(__dirname, "graphs");
|
||||
const SPEEDS_GRAPH = path.join(GRAPHS_DIR, "speeds.png");
|
||||
|
@ -10,7 +10,6 @@ const AVERAGE_SPEEDS_GRAPH = path.join(GRAPHS_DIR, "average-speeds.png");
|
|||
const AVERAGE_SIZES_GRAPH = path.join(GRAPHS_DIR, "average-sizes.png");
|
||||
|
||||
const speedColours = {
|
||||
"@minify-html/js": "#2e61bd",
|
||||
"minify-html": "#2e61bd",
|
||||
"minify-html-onepass": "#222",
|
||||
};
|
||||
|
@ -21,12 +20,57 @@ const sizeColours = {
|
|||
};
|
||||
const defaultSizeColour = "rgb(188, 188, 188)";
|
||||
|
||||
const averageChartOptions = (label) => ({
|
||||
options: {
|
||||
legend: {
|
||||
display: false,
|
||||
},
|
||||
scales: {
|
||||
xAxes: [
|
||||
{
|
||||
barPercentage: 0.5,
|
||||
gridLines: {
|
||||
display: false,
|
||||
},
|
||||
ticks: {
|
||||
fontColor: "#555",
|
||||
fontSize: 20,
|
||||
},
|
||||
},
|
||||
],
|
||||
yAxes: [
|
||||
{
|
||||
type: "linear",
|
||||
scaleLabel: {
|
||||
display: true,
|
||||
fontColor: '#222',
|
||||
fontSize: 24,
|
||||
fontStyle: "bold",
|
||||
labelString: label,
|
||||
padding: 12,
|
||||
},
|
||||
position: "left",
|
||||
ticks: {
|
||||
callback: "$$$_____REPLACE_WITH_TICK_CALLBACK_____$$$",
|
||||
fontColor: "#222",
|
||||
fontSize: 20,
|
||||
},
|
||||
gridLines: {
|
||||
color: "#eee",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const breakdownChartOptions = (title) => ({
|
||||
options: {
|
||||
legend: {
|
||||
display: true,
|
||||
labels: {
|
||||
fontColor: "#000",
|
||||
fontSize: 20,
|
||||
},
|
||||
},
|
||||
title: {
|
||||
|
@ -64,52 +108,6 @@ const breakdownChartOptions = (title) => ({
|
|||
},
|
||||
});
|
||||
|
||||
const axisLabel = (fontColor, labelString) => ({
|
||||
display: true,
|
||||
fontColor,
|
||||
fontSize: 24,
|
||||
fontStyle: "bold",
|
||||
labelString,
|
||||
padding: 12,
|
||||
});
|
||||
|
||||
const averageChartOptions = (label) => ({
|
||||
options: {
|
||||
legend: {
|
||||
display: false,
|
||||
},
|
||||
scales: {
|
||||
xAxes: [
|
||||
{
|
||||
barPercentage: 0.5,
|
||||
gridLines: {
|
||||
display: false,
|
||||
},
|
||||
ticks: {
|
||||
fontColor: "#555",
|
||||
fontSize: 16,
|
||||
},
|
||||
},
|
||||
],
|
||||
yAxes: [
|
||||
{
|
||||
type: "linear",
|
||||
scaleLabel: axisLabel("#222", label),
|
||||
position: "left",
|
||||
ticks: {
|
||||
callback: "$$$_____REPLACE_WITH_TICK_CALLBACK_____$$$",
|
||||
fontColor: "#222",
|
||||
fontSize: 16,
|
||||
},
|
||||
gridLines: {
|
||||
color: "#eee",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const renderChart = (cfg, width, height) =>
|
||||
new Promise((resolve, reject) => {
|
||||
const req = https.request("https://quickchart.io/chart", {
|
||||
|
@ -147,9 +145,7 @@ const renderChart = (cfg, width, height) =>
|
|||
await fs.mkdir(GRAPHS_DIR, { recursive: true });
|
||||
|
||||
const res = results.calculate();
|
||||
const speedMinifiers = [...res.minifiers].sort(
|
||||
(a, b) => res.minifierAvgOps[a] - res.minifierAvgOps[b]
|
||||
);
|
||||
const speedMinifiers = ["html-minifier", "minimize", "minify-html", "minify-html-onepass"];
|
||||
const sizeMinifiers = ["minimize", "html-minifier", "minify-html"];
|
||||
const inputs = Object.keys(res.inputSizes).sort();
|
||||
|
||||
|
@ -159,7 +155,7 @@ const renderChart = (cfg, width, height) =>
|
|||
{
|
||||
type: "bar",
|
||||
data: {
|
||||
labels: speedMinifiers.map((m) => m.replace(" (", "\n(")),
|
||||
labels: speedMinifiers,
|
||||
datasets: [
|
||||
{
|
||||
backgroundColor: speedMinifiers.map(
|
||||
|
@ -184,7 +180,7 @@ const renderChart = (cfg, width, height) =>
|
|||
{
|
||||
type: "bar",
|
||||
data: {
|
||||
labels: sizeMinifiers.map((m) => m.replace(" (", "\n(")),
|
||||
labels: sizeMinifiers,
|
||||
datasets: [
|
||||
{
|
||||
backgroundColor: sizeMinifiers.map(
|
||||
|
@ -212,14 +208,14 @@ const renderChart = (cfg, width, height) =>
|
|||
label: minifier,
|
||||
data: inputs.map(
|
||||
(input) =>
|
||||
res.perInputOps[minifier][input] / res.maxInputOps[input]
|
||||
res.perInputOps[minifier][input] / res.perInputOps['minify-html'][input]
|
||||
),
|
||||
})),
|
||||
},
|
||||
...breakdownChartOptions("Operations per second (higher is better)"),
|
||||
...breakdownChartOptions("Operations per second, relative to minify-html"),
|
||||
},
|
||||
900,
|
||||
1000
|
||||
800,
|
||||
1280
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -232,13 +228,13 @@ const renderChart = (cfg, width, height) =>
|
|||
labels: inputs,
|
||||
datasets: sizeMinifiers.map((minifier) => ({
|
||||
label: minifier,
|
||||
data: inputs.map((input) => res.perInputReduction[minifier][input]),
|
||||
data: inputs.map((input) => res.perInputReduction[minifier][input] / res.perInputReduction['minify-html'][input]),
|
||||
})),
|
||||
},
|
||||
...breakdownChartOptions("Size reduction (higher is better)"),
|
||||
...breakdownChartOptions("Size reduction, relative to minify-html"),
|
||||
},
|
||||
900,
|
||||
1000
|
||||
800,
|
||||
1280
|
||||
)
|
||||
);
|
||||
})();
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
[compare.sh](./compare.sh) is a useful script for viewing a character-by-character diff between the minified outputs of minify-html and html-minifier for a specific test. Pass the test's file name as the first argument.
|
|
@ -0,0 +1 @@
|
|||
Profiling minify-html can be done on Linux by using [profile.sh](./profile.sh), which uses `perf`. The generated report can be used using `perf report`.
|
|
@ -8,7 +8,7 @@ An HTML minifier that provides the functionality of [minify-html](https://github
|
|||
|
||||
## Performance
|
||||
|
||||
<img alt="Chart showing speed of HTML minifiers" src="https://wilsonl.in/minify-html/bench/0.6.1/core/average-speeds.png">
|
||||
<img width="600" alt="Chart showing speed of HTML minifiers" src="https://wilsonl.in/minify-html/bench/0.6.1/core/average-speeds.png">
|
||||
|
||||
## Usage
|
||||
|
||||
|
|
Loading…
Reference in New Issue