Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"babel-plugin-transform-es2015-block-scoping": "^6.24.1",
"babel-preset-env": "^1.5.0",
"babel-traverse": "^6.24.1",
"brotli": "^1.3.2",
"butternut": "^0.4.6",
"bytes": "^2.5.0",
"chalk": "^1.1.3",
Expand Down
37 changes: 22 additions & 15 deletions packages/babel-plugin-minify-mangle-names/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const ScopeTracker = require("./scope-tracker");
const isLabelIdentifier = require("./is-label-identifier");
const bfsTraverseCreator = require("./bfs-traverse");
const fixupVarScoping = require("./fixup-var-scoping");
const keywordVisitors = require("./keyword-visitors");

const {
markEvalScopes,
Expand Down Expand Up @@ -218,21 +219,27 @@ module.exports = babel => {
* as to improve the gzip compression - as gzip likes repetition
*/
if (this.charset.shouldConsider) {
collectVisitor.Identifier = function Identifer(path) {
const { node } = path;

// We don't mangle properties, so we collect them as they contribute
// to the frequency of characters
if (
path.parentPath.isMemberExpression({ property: node }) ||
path.parentPath.isObjectProperty({ key: node })
) {
mangler.charset.consider(node.name);
Object.assign(
collectVisitor,
keywordVisitors(name => mangler.charset.consider(name)),
{
Identifier(path) {
const { node } = path;

// We don't mangle properties, so we collect them as they contribute
// to the frequency of characters
if (
path.parentPath.isMemberExpression({ property: node }) ||
path.parentPath.isObjectProperty({ key: node })
) {
mangler.charset.consider(node.name);
}
},
Literal({ node }) {
mangler.charset.consider(String(node.value));
}
}
};
collectVisitor.Literal = function Literal({ node }) {
mangler.charset.consider(String(node.value));
};
);
}

// Traverse the AST
Expand Down Expand Up @@ -507,7 +514,7 @@ module.exports = babel => {
// is running on this on single files before bundling. Therefore we
// need to achieve as much determinisim and we will not do any frequency
// sorting on the character set. Currently the number is pretty arbitrary.
const shouldConsiderSource = path.getSource().length > 70000;
const shouldConsiderSource = path.getSource().length > 20000;

const charset = new Charset(shouldConsiderSource);

Expand Down
100 changes: 100 additions & 0 deletions packages/babel-plugin-minify-mangle-names/src/keyword-visitors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/**
* For charset considerations
*
* @param cb callback to be called with keyword strings
*/
module.exports = cb => ({
VariableDeclaration({ node }) {
// let, var, const
cb(node.kind);
},
ImportDeclaration({ node }) {
cb("import");
if (node.specifiers.length > 0) cb("from");
},
ImportSpecifier({ node }) {
// import {a as b} from "a";
if (node.local.name !== node.imported.name) cb("as");
},
ExportNamedDeclaration() {
cb("export");
},
ExportDefaultDeclaration() {
cb("export default");
},
ExportSpecifier({ node }) {
if (node.local.name !== node.imported.name) cb("as");
},
"FunctionDeclaration|FunctionExpression"({ node }) {
cb("function");
if (node.async) cb("async");
},
Class({ node }) {
cb("class");
if (node.superClass) cb("extends");
},
"ClassMethod|ObjectMethod"({ node }) {
// get and set
if (node.kind) cb(node.kind);
},
UnaryExpression({ node }) {
// typeof, void, delete
cb(node.operator);
},
NewExpression() {
cb("new");
},
ThisExpression() {
cb("this");
},
Super() {
cb("super");
},
YieldExpression() {
cb("yield");
},
AwaitExpression() {
cb("await");
},
TryStatement({ node }) {
cb("try");
if (node.handler) cb("catch");
if (node.finalizer) cb("finally");
},
ThrowStatement() {
cb("throw");
},
ForInStatement() {
cb("for in");
},
ForOfStatement() {
cb("for of");
},
While(path) {
cb("while");
if (path.isDoWhileStatement()) cb("do");
},
BreakStatement() {
cb("break");
},
ContinueStatement() {
cb("continue");
},
ReturnStatement() {
cb("return");
},
BinaryExpression({ node }) {
if (node.operator === "instanceof") cb("instanceof");
},
IfStatement({ node }) {
cb("if");
if (node.alternate) cb("else");
},
SwitchStatement() {
cb("switch");
},
SwitchCase({ node }) {
if (node.test) cb("case");
else cb("default");
}
});
34 changes: 24 additions & 10 deletions scripts/benchmark.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const request = require("request");
const program = require("commander");
const compile = require("google-closure-compiler-js").compile;
const butternut = require("butternut");
const brotli = require("brotli");

const ASSETS_DIR = path.join(__dirname, "benchmark_cache");
const DEFAULT_ASSETS = {
Expand Down Expand Up @@ -49,10 +50,12 @@ class Benchmark {

const code = this.getFile(filename);
const gzipped = zlib.gzipSync(code);
const brotlied = brotli.compress(Buffer.from(code, "utf-8"));

const result = {
input: code,
gzipped,
brotlied,
filename,
items: [
this.test(this.babili, code),
Expand Down Expand Up @@ -90,12 +93,14 @@ class Benchmark {
const delta = process.hrtime(start);

const gzipped = zlib.gzipSync(output);
const brotlied = brotli.compress(Buffer.from(output, "utf-8"));
const parseTime = this.getParseTime(output);

return {
name: fn.name,
output,
gzipped,
brotlied,
parseTime,
time: delta[0] * 1e3 + delta[1] / 1e6
};
Expand Down Expand Up @@ -156,15 +161,7 @@ class Printer {
);
this.target = target;

this.header = [
"minifier",
"output raw",
"raw win",
"gzip output",
"gzip win",
"parse time (ms)",
"minify time (ms)"
];
this.header = this.getHeader();
}
print() {
switch (this.target) {
Expand Down Expand Up @@ -215,7 +212,9 @@ class Printer {
this.target === "MD" && console.log("");
console.log(`Input Size: ${bytes(data.input.length)}`);
this.target === "MD" && console.log("");
console.log(`Input Size (gzip): ${bytes(data.gzipped.length)}\n`);
console.log(`Input Size (gzip): ${bytes(data.gzipped.length)}`);
this.target === "MD" && console.log("");
console.log(`Input Size (brotli): ${bytes(data.brotlied.length)}\n`);
}
getRows(result) {
return result.items.map(item =>
Expand All @@ -236,11 +235,26 @@ class Printer {
red(col) {
return this.target === "MD" ? col : chalk.red(col);
}
getHeader() {
return [
"minifier",
"output raw",
"raw win",
"brotli output",
"brotli win",
"gzip output",
"gzip win",
"parse time (ms)",
"minify time (ms)"
];
}
getColumns(item, res) {
return [
item.name,
bytes(item.output.length),
Math.round(100 - 100 * item.output.length / res.input.length) + "%",
bytes(item.brotlied.length),
Math.round(100 - 100 * item.brotlied.length / res.brotlied.length) + "%",
bytes(item.gzipped.length),
Math.round(100 - 100 * item.gzipped.length / res.gzipped.length) + "%",
item.parseTime.toFixed(2),
Expand Down
14 changes: 12 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -785,6 +785,10 @@ balanced-match@^0.4.1:
version "0.4.2"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838"

base64-js@^1.1.2:
version "1.2.0"
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.0.tgz#a39992d723584811982be5e290bb6a53d86700f1"

bcrypt-pbkdf@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d"
Expand Down Expand Up @@ -826,6 +830,12 @@ braces@^1.8.2:
preserve "^0.2.0"
repeat-element "^1.1.2"

brotli@^1.3.2:
version "1.3.2"
resolved "https://registry.yarnpkg.com/brotli/-/brotli-1.3.2.tgz#525a9cad4fcba96475d7d388f6aecb13eed52f46"
dependencies:
base64-js "^1.1.2"

browser-resolve@^1.11.2:
version "1.11.2"
resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.2.tgz#8ff09b0a2c421718a1051c260b32e48f442938ce"
Expand Down Expand Up @@ -2705,11 +2715,11 @@ istanbul-api@^1.1.1:
mkdirp "^0.5.1"
once "^1.4.0"

istanbul-lib-coverage@^1.0.1, istanbul-lib-coverage@^1.0.2:
istanbul-lib-coverage@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.0.2.tgz#87a0c015b6910651cb3b184814dfb339337e25e1"

istanbul-lib-coverage@^1.1.0:
istanbul-lib-coverage@^1.0.2, istanbul-lib-coverage@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.0.tgz#caca19decaef3525b5d6331d701f3f3b7ad48528"

Expand Down