diff --git a/.gitignore b/.gitignore index 1cb47a1..5311eff 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ yarn-error.log coverage .idea bundle +.DS_Store diff --git a/.nycrc.json b/.nycrc.json index dc72b6e..f8eadf4 100644 --- a/.nycrc.json +++ b/.nycrc.json @@ -12,6 +12,7 @@ "**/bundle", "**/stub", "rollup.config.js", + "benchmark", "**/*.config.*" ], "branches": 100, diff --git a/.putout.json b/.putout.json index 77ee3e8..b684fed 100644 --- a/.putout.json +++ b/.putout.json @@ -4,5 +4,5 @@ "eslint/convert-rc-to-flat": "on" } }, - "ignore": ["bundle"] + "ignore": ["bundle", "benchmark"] } diff --git a/README.md b/README.md index dbbb6b4..9074459 100644 --- a/README.md +++ b/README.md @@ -98,17 +98,9 @@ minify(source, { }); ``` -### How it's compared to [Terser](https://github.com/terser/terser)? +### How it's compared to X(your benchmark)? -For [such code](https://github.com/coderaiser/minify/issues/96#issuecomment-1546605157): - -- 🔥 `@putout/minify`: `475B` -- ❌ `terser`: `482B` - -`react.js`: - -- 🔥 `@putout/minify`: `16309B` -- ❌ `terser`: `16346B` +[Benchmark](benchmark) ## License diff --git a/benchmark/.gitignore b/benchmark/.gitignore new file mode 100644 index 0000000..6a093b6 --- /dev/null +++ b/benchmark/.gitignore @@ -0,0 +1,3 @@ +source/* +!source/example* +result diff --git a/benchmark/README.md b/benchmark/README.md new file mode 100644 index 0000000..921edaa --- /dev/null +++ b/benchmark/README.md @@ -0,0 +1,53 @@ +# Benchmark + +This is a performance benchmark of the following bundlers: + +- Bun +- esbuild +- Terser +- @putoutjs/minify + +To run the benchmark: + +- Need to install bun globally (https://bun.sh/docs/installation) + +```sh +$ npm install +$ node index.js +``` + +## Results + +The `real` results, as run on a 13-inch M1 Macbook air: + +Time in ms +``` +┌──────────┬─────┬─────────┬────────┬─────────────────┐ +│ (index) │ bun │ esbuild │ terser │ putoutjs_minify │ +├──────────┼─────┼─────────┼────────┼─────────────────┤ +│ react │ 58 │ 50 │ 230 │ 2509 │ +│ solidjs │ 21 │ 16 │ 270 │ 12735 │ +│ treejs │ 74 │ 100 │ 1787 │ │ +│ lodash │ 21 │ 27 │ 603 │ 108901 │ +│ vue │ 60 │ 62 │ 1455 │ │ +│ angular │ 32 │ 41 │ 1320 │ │ +│ jquery │ 18 │ 23 │ 548 │ 80481 │ +│ example1 │ 42 │ 35 │ 108 │ 330 │ +└──────────┴─────┴─────────┴────────┴─────────────────┘ +``` + +Size in bytes +``` +┌──────────┬───────────────────┬───────────────────┬───────────────────┬──────────────────┬──────────────────┐ +│ (index) │ original │ bun │ esbuild │ terser │ putoutjs_minify │ +├──────────┼───────────────────┼───────────────────┼───────────────────┼──────────────────┼──────────────────┤ +│ react │ '10751 (100.0%)' │ '10553 (98.2%)' │ '10644 (99.0%)' │ '10391 (96.7%)' │ '10052 (93.5%)' │ +│ solidjs │ '28537 (100.0%)' │ '21888 (76.7%)' │ '20553 (72.0%)' │ '28202 (98.8%)' │ '21886 (76.7%)' │ +│ treejs │ '677935 (100.0%)' │ '680368 (100.4%)' │ '657528 (97.0%)' │ '677573 (99.9%)' │ │ +│ lodash │ '73015 (100.0%)' │ '72551 (99.4%)' │ '72189 (98.9%)' │ '70751 (96.9%)' │ '73688 (100.9%)' │ +│ vue │ '196075 (100.0%)' │ '196443 (100.2%)' │ '193091 (98.5%)' │ '195200 (99.6%)' │ │ +│ angular │ '177368 (100.0%)' │ '178187 (100.5%)' │ '177834 (100.3%)' │ '176388 (99.4%)' │ │ +│ jquery │ '87533 (100.0%)' │ '87451 (99.9%)' │ '87119 (99.5%)' │ '86958 (99.3%)' │ '85889 (98.1%)' │ +│ example1 │ '853 (100.0%)' │ '494 (57.9%)' │ '490 (57.4%)' │ '481 (56.4%)' │ '482 (56.5%)' │ +└──────────┴───────────────────┴───────────────────┴───────────────────┴──────────────────┴──────────────────┘ +``` diff --git a/benchmark/cli/minify.js b/benchmark/cli/minify.js new file mode 100644 index 0000000..edf430a --- /dev/null +++ b/benchmark/cli/minify.js @@ -0,0 +1,5 @@ +import {minify} from '@putout/minify'; +import { readFileSync, writeFileSync } from 'node:fs' + +const body = readFileSync(process.argv[2], 'utf8'); +writeFileSync(process.argv[3], minify(body)); diff --git a/benchmark/index.js b/benchmark/index.js new file mode 100644 index 0000000..9c3fcc8 --- /dev/null +++ b/benchmark/index.js @@ -0,0 +1,155 @@ +import { get } from "node:https"; +import { statSync, writeFileSync, createWriteStream, rmSync } from "node:fs"; +import { execSync } from 'node:child_process' + +const listFiles = { + react: { + url: "https://cdn.jsdelivr.net/npm/react@18.3.1/umd/react.production.min.js", + }, + solidjs: { + url: "https://cdn.jsdelivr.net/npm/solid-js@1.8.17/dist/solid.min.js", + }, + treejs: { + url: "https://cdn.jsdelivr.net/npm/three@0.165.0/build/three.module.min.js", + }, + lodash: { + url: "https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js", + }, + vue: { + url: "https://cdn.jsdelivr.net/npm/vue@3.4.29/dist/vue.global.min.js", + }, + angular: { + url: "https://cdn.jsdelivr.net/npm/angular@1.8.3/angular.min.js", + }, + jquery: { + url: 'https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js', + }, + example1: { + file: "./source/example1.js", + } +}; + +const compressors = { + bun: 'bun build --minify {dist} --outfile {out}', + esbuild: './node_modules/.bin/esbuild {dist} --bundle --minify --outfile={out}', + terser: './node_modules/.bin/terser {dist} --compress --mangle --comments false -o {out}', + 'putoutjs_minify': 'node ./cli/minify.js {dist} {out}' +}; + +let debug = () => {}; +// debug = console.log; + +function fileExists(path) { + try { + const s = statSync(path); + debug(`File ${path} exists ${s.size} bytes`) + return s.size > 0; + } catch (e) { + debug(`File ${path} does not exist`) + return false; + } +} + +async function downloadFile(url, dest) { + if (fileExists(dest)) { + debug(`File ${dest} already exists`) + return; + } + return new Promise((resolve, reject) => { + debug(`Downloading ${url} to ${dest}`); + get(url, (res) => { + const file = createWriteStream(dest, ""); + res.pipe(file); + res.on("end", () => { + debug(`Downloaded ${url} to ${dest}`); + resolve(); + }); + }); + }); +} + +function fileFromUrl(url) { + return `./source/${url}.js` +} + +async function download() { + for (const [key, value] of Object.entries(listFiles)) { + if (!value.url) continue; + const { url } = value; + const dest = fileFromUrl(key); + await downloadFile(url, dest); + } +} + +function getPathFromFile(file) { + return listFiles[file].file || fileFromUrl(file); +} + +function removeFile(filePath) { + rmSync(filePath, { force: true }); +} + +async function compareTask(file) { + const dist = getPathFromFile(file); + const result = {}; + for (const [key, value] of Object.entries(compressors)) { + const out = `./result/${file}-${key}.js`; + removeFile(out); + const cmd = value.replace('{dist}', dist).replace('{out}', out); + debug(`Running: ${cmd}`); + let endTime = 0; + try { + const startTime = Date.now(); + execSync(cmd, { stdio: 'pipe', encoding: 'utf8' }); + endTime = Date.now() - startTime; + } catch (e) { + console.error(`Error running ${key}: ${e.message} ${e.stderr}`); + continue; + } + const fileSize = statSync(out).size; + result[key] = { + time: endTime, + size: fileSize, + } + console.log(`File: ${file} Compressor: ${key} Time: ${endTime}ms Size: ${fileSize} bytes`) + } + return result; +} + +function convertMap(fn, obj) { + return Object.fromEntries(Object.entries(obj).map(([k, v]) => [k, fn(v, k, obj)]).filter(([k, v]) => v !== undefined)); +} + +function convertTable(obj, key) { + return convertMap(convertMap.bind(null, (v) => v[key]), obj); +} + +async function compare() { + const result = {}; + for (const key of Object.keys(listFiles)) { + result[key] = await compareTask(key); + const originalSize = statSync(getPathFromFile(key)).size; + result[key] = { + original: { size: originalSize }, + ...result[key] + } + } + return result; +} + +async function main() { + await download(); + const result = await compare(); + debug(result) + const resultTime = convertTable(result, 'time'); + debug(resultTime) + console.log('Time in ms') + console.table(resultTime); + const resultSize = convertMap(convertMap.bind(null, (v, k, obj) => `${v} (${(100 * v / obj.original).toFixed(1)}%)`),convertTable(result, 'size')); + + debug(resultSize) + console.log('Size in bytes') + console.table(resultSize); +} + +main(); diff --git a/benchmark/package-lock.json b/benchmark/package-lock.json new file mode 100644 index 0000000..cf482e0 --- /dev/null +++ b/benchmark/package-lock.json @@ -0,0 +1,515 @@ +{ + "name": "@putout/minify-benchmark", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@putout/minify-benchmark", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "@putout/minify": "^4.1.0", + "esbuild": "^0.21.5", + "terser": "^5.31.1" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@putout/minify": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@putout/minify/-/minify-4.1.0.tgz", + "integrity": "sha512-fhIknvGP2o9OO2uJacc3wBJq7nEpZoQT1gUP2OADEQUAWdw9KNwdQHFaHFRq8m/775ksrTIKc5aUqAw8B3XBQQ==", + "engines": { + "node": ">=18" + } + }, + "node_modules/acorn": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz", + "integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/terser": { + "version": "5.31.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.1.tgz", + "integrity": "sha512-37upzU1+viGvuFtBo9NPufCb9dwM0+l9hMxYyWfBA+fbwrPqNJAhbZ6W47bBFnZHKHTUBnMvi87434qq+qnxOg==", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + } + } +} diff --git a/benchmark/package.json b/benchmark/package.json new file mode 100644 index 0000000..35b5d4b --- /dev/null +++ b/benchmark/package.json @@ -0,0 +1,20 @@ +{ + "name": "@putout/minify-benchmark", + "version": "1.0.0", + "main": "index.js", + "type": "module", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "homepage": "https://github.com/putoutjs/minify/tree/master/benchmark#readme", + "license": "MIT", + "repository": { + "type": "git", + "url": "git://github.com/putoutjs/minify.git" + }, + "dependencies": { + "@putout/minify": "^4.1.0", + "esbuild": "^0.21.5", + "terser": "^5.31.1" + } +} diff --git a/benchmark/source/example1.js b/benchmark/source/example1.js new file mode 100644 index 0000000..386dc6f --- /dev/null +++ b/benchmark/source/example1.js @@ -0,0 +1,31 @@ +jQuery(function ($) +{ + var dp; + if (typeof ($.datepicker) != 'undefined') + { + $('#ep_ipo_date').datepicker({ + dateFormat: 'yy-mm-dd', changeYear: true, changeMonth: true + }); + $('#ep_ipo_date_dp').click(function () + { + if (($('#ui-datepicker-div').is(':visible') && dp == $(this).attr('id'))) + { + $('#ep_ipo_date').datepicker('hide'); + dp = null; + } + else + { + $('#ep_ipo_date').datepicker('show'); + dp = $(this).attr('id'); + } + }); + + $("#ep_ipo_date").focusout(function () + { + if (!(/^[\d]{2}\/[\d]{2}\/[\d]{4}$/).test($(this).val()) && $(this).val().length != 0) + { + $(this).val(''); + } + }); + } +});