minify-html/bench/bench.js

179 lines
4.3 KiB
JavaScript

"use strict";
const benchmark = require("benchmark");
const chartjs = require('chartjs-node');
const fs = require("fs");
const htmlMinifier = require("html-minifier");
const hyperbuild = require("hyperbuild");
const minimize = require("minimize");
const path = require("path");
const testsDir = path.join(__dirname, "tests");
const tests = fs.readdirSync(testsDir).map(name => ({
name,
content: fs.readFileSync(path.join(testsDir, name), "utf8"),
}));
const programs = {
'hyperbuild-nodejs': content => hyperbuild.minify(Buffer.from(content)),
'html-minifier': content => htmlMinifier.minify(content, {
caseSensitive: false,
collapseBooleanAttributes: true,
collapseInlineTagWhitespace: true,
collapseWhitespace: true,
conservativeWhitespace: false,
customEventAttributes: [],
decodeEntities: true,
html5: true,
ignoreCustomComments: [],
ignoreCustomFragments: [],
includeAutoGeneratedTags: true,
keepClosingSlash: false,
minifyCSS: false,
minifyJS: false,
minifyURLs: false,
preserveLineBreaks: false,
preventAttributesEscaping: false,
processConditionalComments: true,
processScripts: [],
removeAttributeQuotes: true,
removeComments: true,
removeEmptyAttributes: false,
removeEmptyElements: false,
removeOptionalTags: true,
removeRedundantAttributes: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true,
removeTagWhitespace: true,
sortAttributes: true,
sortClassName: true,
trimCustomFragments: false,
useShortDoctype: true,
}).length,
'minimize': content => new minimize().parse(content).length,
};
const colours = [
{
backgroundColor: '#9ad0f5',
borderColor: '#47aaec',
},
{
backgroundColor: '#ffb0c1',
borderColor: '#ff87a1',
},
{
backgroundColor: '#a4dfdf',
borderColor: '#4bc0c0',
},
];
const renderChart = async (file, title, cfg) => {
const chart = new chartjs(435, 320);
await chart.drawChart({
...cfg,
options: {
title: {
display: true,
text: title,
},
scales: {
xAxes: [{
barPercentage: 0.5,
gridLines: {
color: '#ccc',
},
ticks: {
fontColor: '#222',
},
}],
yAxes: [{
gridLines: {
color: '#666',
},
ticks: {
fontColor: '#222',
},
}],
},
legend: {
labels: {
fontFamily: 'Ubuntu, sans-serif',
fontColor: '#000',
},
},
},
});
await chart.writeImageToFile('image/png', path.join(__dirname, `${file}.png`));
};
const sizes = {};
const setSize = (program, test, result) => {
if (!sizes[test]) {
sizes[test] = {
original: {
absolute: tests.find(t => t.name === test).content.length,
relative: 1,
},
};
}
const original = sizes[test].original.absolute;
sizes[test][program] = {
absolute: result,
relative: result / original,
};
};
// Run once to set sizes.
for (const t of tests) {
for (const p of Object.keys(programs)) {
setSize(p, t.name, programs[p](t.content));
}
}
const suite = new benchmark.Suite();
for (const p of Object.keys(programs)) {
suite.add(p, () => {
for (const t of tests) {
programs[p](t.content);
}
});
}
suite
.on('cycle', event => {
console.info(event.target.toString());
})
.on('complete', async function () {
const speedResults = this.map(b => ({
name: b.name,
count: b.count,
ops: b.hz,
})).sort((a, b) => a.hz - b.hz);
await renderChart('speed', 'Minification speed', {
type: 'bar',
data: {
labels: speedResults.map(r => r.name),
datasets: [{
label: 'Operations per second',
...colours[0],
data: speedResults.map(r => r.ops),
}],
},
});
const testNames = Object.keys(sizes);
const programNames = Object.keys(programs);
await renderChart('minification', 'Relative minified HTML file size', {
type: 'bar',
scaleFontColor: 'red',
data: {
labels: testNames,
datasets: programNames.map((program, i) => ({
label: program,
...colours[i],
data: testNames.map(test => sizes[test][program].relative),
})),
},
});
})
.run({'async': true});