-
-
Notifications
You must be signed in to change notification settings - Fork 31
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
8086228
commit d0af75e
Showing
24 changed files
with
6,016 additions
and
6,919 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
root = true | ||
|
||
[*] | ||
indent_style = tab | ||
end_of_line = lf | ||
charset = utf-8 | ||
trim_trailing_whitespace = true | ||
insert_final_newline = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
v14.15.1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
MIT License | ||
|
||
Copyright (c) 2020 hiroki | ||
Copyright (c) Hiroki Osame <hiroki[email protected]> | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
import assert from 'assert'; | ||
import execa from 'execa'; | ||
import Listr from 'listr'; | ||
import path from 'path'; | ||
import fs from 'fs'; | ||
import byteSize from 'byte-size'; | ||
import { getSize, getGzipSize } from '../utils.js'; | ||
|
||
// const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); | ||
|
||
async function benchmark({ | ||
minifier, | ||
filePath, | ||
sampleSize, | ||
onIterationStart, | ||
}) { | ||
const results = []; | ||
|
||
for (let i = 0; i < sampleSize; i += 1) { | ||
onIterationStart(i + 1, results[i - 1]); | ||
const subprocess = execa(process.execPath, [path.join('./lib/benchmark/minifiers/' + minifier), filePath], { | ||
timeout: 1000 * 60, | ||
}); | ||
|
||
subprocess.stdout.pipe(fs.createWriteStream(`logs/${Date.now()}-${minifier}-${path.basename(filePath, '.js')}.log`)); | ||
|
||
let jsonData; | ||
try { | ||
const result = await subprocess; | ||
jsonData = JSON.parse(result.stdout); | ||
} catch (err) { | ||
console.log(err); | ||
if (err.message.match('Command timed out')) { | ||
console.log('Retrying...'); | ||
i -= 1; // Retry | ||
continue; | ||
} | ||
throw err; | ||
} | ||
if (results.length > 0) { | ||
assert(jsonData.size === results[0].size, 'Mismatching size'); | ||
} | ||
results.push(jsonData); | ||
} | ||
|
||
const avgSpeed = results.reduce((current, next) => current + next.ms, 0) / results.length; | ||
|
||
return { | ||
ms: avgSpeed, | ||
size: results[0].size, | ||
gzipSize: results[0].gzipSize, | ||
}; | ||
} | ||
|
||
const task = { | ||
title: 'Benchmarking', | ||
task(ctx) { | ||
ctx.results = {}; | ||
return new Listr( | ||
ctx.artifacts.map(({ moduleName, version, path, code }) => { | ||
return { | ||
title: `Minifying: ${moduleName} (v${version})`, | ||
task(ctx, task) { | ||
const size = getSize(code); | ||
const gzipSize = getGzipSize(code); | ||
ctx.results[moduleName] = { | ||
size, | ||
gzipSize, | ||
benchmarks: {}, | ||
}; | ||
task.output = `${byteSize(size)} (${byteSize(gzipSize)} gzipped)`; | ||
return new Listr( | ||
[ | ||
'babel-minify', | ||
'esbuild', | ||
'terser', | ||
'terser.no-compress', | ||
'uglify-js', | ||
'uglify-js.no-compress', | ||
].map((minifier) => ({ | ||
title: minifier, | ||
async task(ctx, task) { | ||
const sampleSize = 10; | ||
const benchmarked = await benchmark({ | ||
minifier, | ||
filePath: path, | ||
sampleSize, | ||
onIterationStart(iteration, lastBenchmark) { | ||
task.title = `${minifier} [${iteration}/${sampleSize}]`; | ||
if (lastBenchmark) { | ||
task.output = 'Last benchmark: ' + lastBenchmark.ms.toLocaleString() + 'ms'; | ||
} | ||
}, | ||
}).catch(err => ({})); | ||
ctx.results[moduleName].benchmarks[minifier] = benchmarked; | ||
}, | ||
})) | ||
); | ||
}, | ||
}; | ||
}) | ||
); | ||
} | ||
}; | ||
|
||
export default task; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import babelMinify from 'babel-minify'; | ||
import measure from './measure.js'; | ||
|
||
measure(async (code) => { | ||
const minified = await babelMinify(code, undefined, { | ||
sourceMaps: false, | ||
}); | ||
return minified.code; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import esbuild from 'esbuild'; | ||
import measure from './measure.js'; | ||
|
||
const service = await esbuild.startService(); | ||
|
||
await measure(async (code) => { | ||
const minified = (await service.transform(code, { | ||
minify: true, | ||
sourcemap: false, | ||
})); | ||
return minified.code; | ||
}); | ||
|
||
service.stop(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import { promises as fs } from 'fs'; | ||
import { getSize, getGzipSize } from '../../utils.js'; | ||
import stripComments from 'strip-comments'; | ||
|
||
const srcCode = (await fs.readFile(process.argv[2])).toString(); | ||
|
||
export default async function (fn) { | ||
let hrtime; | ||
const start = process.hrtime(); | ||
let minifiedCode = await fn(srcCode); | ||
hrtime = process.hrtime(start); | ||
|
||
// Remove comments from all measurements | ||
// console.time('stripComments'); | ||
// minifiedCode = stripComments(minifiedCode.trim(), { | ||
// keepProtected: false, | ||
// }); | ||
// console.timeEnd('stripComments'); Commenting it out becaues this takes 50s on three.js | ||
|
||
const success = Boolean(minifiedCode); | ||
const size = success && getSize(minifiedCode); | ||
const gzipSize = success && getGzipSize(minifiedCode); | ||
|
||
console.log(JSON.stringify({ | ||
ms: success ? (hrtime[0] * 1000) + (hrtime[1] / 1e6) : undefined, | ||
success, | ||
size, | ||
gzipSize, | ||
})); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { minify } from 'terser'; | ||
import measure from './measure.js'; | ||
|
||
measure(async (code) => { | ||
const minified = await minify(code, { | ||
sourceMap: false, | ||
}); | ||
return minified.code; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import { minify } from 'terser'; | ||
import measure from './measure.js'; | ||
|
||
measure(async (code) => { | ||
const minified = await minify(code, { | ||
sourceMap: false, | ||
compress: false, | ||
}); | ||
return minified.code; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import UglifyJs from 'uglify-js'; | ||
import assert from 'assert'; | ||
import measure from './measure.js'; | ||
|
||
measure(async (code) => { | ||
const minified = await UglifyJs.minify(code, { | ||
sourceMap: false, | ||
}); | ||
assert(!minified.error, minified.error); | ||
return minified.code; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import UglifyJs from 'uglify-js'; | ||
import assert from 'assert'; | ||
import measure from './measure.js'; | ||
|
||
measure(async (code) => { | ||
const minified = await UglifyJs.minify(code, { | ||
sourceMap: false, | ||
compress: false, | ||
}); | ||
assert(!minified.error, minified.error); | ||
return minified.code; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,50 +1,57 @@ | ||
const {promises: fs} = require('fs'); | ||
const _ = require('lodash'); | ||
const minifiers = require('./minifiers'); | ||
const md = require('./md'); | ||
const {getStrGzipSize} = require('./utils'); | ||
|
||
(async packages => { | ||
let results = ''; | ||
|
||
for (const pkg of packages) { | ||
const pkgPath = require.resolve(pkg); | ||
const content = await fs.readFile(pkgPath); // eslint-disable-line no-await-in-loop | ||
const benchmarks = await minifiers.runMinifiers(content.toString()); // eslint-disable-line no-await-in-loop | ||
|
||
const ms = benchmarks.filter(b => b.ms); | ||
_.minBy(ms, 'ms').annotation.time = '🐇'; | ||
_.maxBy(ms, 'ms').annotation.time = '🐢'; | ||
|
||
const size = benchmarks.filter(b => b.size); | ||
_.minBy(size, 'size').annotation.size = '🐥'; | ||
_.maxBy(size, 'size').annotation.size = '🐷'; | ||
|
||
const gzip = benchmarks.filter(b => b.gzipSize); | ||
_.minBy(gzip, 'gzipSize').annotation.gzip = '🐥'; | ||
_.maxBy(gzip, 'gzipSize').annotation.gzip = '🐷'; | ||
|
||
results += md.moduleSection({ | ||
pkg, | ||
pkgPath, | ||
size: content.length, | ||
gzipSize: getStrGzipSize(content), | ||
benchmarks | ||
}); | ||
} | ||
|
||
const mdString = md.readme({ | ||
minifiersList: minifiers.minifiers.map(m => `- [${m.name}](${m.repo})`).join('\n'), | ||
results | ||
}); | ||
|
||
await fs.writeFile('./readme.md', mdString); | ||
})([ | ||
'lodash', | ||
'vue/dist/vue.runtime.common.dev', | ||
'react/cjs/react.development.js', | ||
'moment', | ||
'terser', | ||
'd3/dist/d3', | ||
'jquery' | ||
].sort()); | ||
import { promises as fs } from 'fs'; | ||
import Listr from 'listr'; | ||
import { resolveModule, getVersion } from './utils.js'; | ||
import benchmark from './benchmark/index.js'; | ||
import updateReadme from './update-readme.js'; | ||
import path from 'path'; | ||
|
||
const { results } = await (new Listr([ | ||
benchmark, | ||
updateReadme, | ||
])).run({ | ||
artifacts: await Promise.all([ | ||
{ | ||
moduleName: 'lodash', | ||
path: 'lodash', | ||
}, | ||
{ | ||
moduleName: 'three', | ||
path: 'three', | ||
}, | ||
{ | ||
moduleName: 'vue', | ||
path: 'vue/dist/vue.runtime.common.dev.js', | ||
}, | ||
{ | ||
moduleName: 'react', | ||
path: 'react/cjs/react.development.js', | ||
}, | ||
{ | ||
moduleName: 'moment', | ||
path: 'moment', | ||
}, | ||
{ | ||
moduleName: 'd3', | ||
path: 'd3/dist/d3.js', | ||
}, | ||
{ | ||
moduleName: 'jquery', | ||
path: 'jquery', | ||
}, | ||
{ | ||
moduleName: 'terser', | ||
path: path.resolve('node_modules/terser/dist/bundle.min.js'), | ||
}, | ||
].sort((a, b) => a.moduleName.localeCompare(b.moduleName)).map(async (m) => { | ||
const path = m.path.startsWith('/') ? m.path : (await resolveModule(m.path)); | ||
return { | ||
moduleName: m.moduleName, | ||
version: await getVersion(m.moduleName), | ||
path, | ||
code: await fs.readFile(path), | ||
}; | ||
})), | ||
}).catch(err => { | ||
console.log(err); | ||
return err.context; | ||
}); |
Oops, something went wrong.