RE nodejs/node#12938
I thought this might have been something Prepack would take care of but not sure it does.
Expected Prepack to remove unreachable / dead code. c is always false, therefore the console.logs _should_ be killed but they are not.
const c = false;
var n = 0;
var start = Date.now();
function f( ) {
for (let i = 0; i < 1000000; i++) {
if (c) {
console.log('Yes');
}
if (c) {
console.log('Yes');
}
if (c) {
console.log('Yes');
}
if (c) {
console.log('Yes');
}
if (c) {
console.log('Yes');
}
if (c) {
console.log('Yes');
}
}
console.log( "time:", Date.now() - start );
start = Date.now();
if( n++ < 1000 )
setTimeout( f, 0 );
}
var f, start, n;
(function () {
var _$1 = this;
function _0() {
for (let i = 0; i < 1000000; i++) {
}
_$1.console.log("time:", _$1.Date.now() - _$1.start);
_$1.start = _$1.Date.now();
if (_$1.n++ < 1000) _$1.setTimeout(_$1.f, 0);
}
let _1 = false;
f = _0;
start = undefined;
n = undefined;
n = 0;
var _$0 = Date.now();
if (typeof _$0 !== "number") {
throw new Error("Prepack model invariant violation: " + _$0);
}
start = _$0;
}).call(this);
var f, start, n;
(function () {
var _$1 = this;
function _0() {
for (let i = 0; i < 1000000; i++) {
if (_1) {
_$1.console.log('Yes');
}
if (_1) {
_$1.console.log('Yes');
}
if (_1) {
_$1.console.log('Yes');
}
if (_1) {
_$1.console.log('Yes');
}
if (_1) {
_$1.console.log('Yes');
}
if (_1) {
_$1.console.log('Yes');
}
}
_$1.console.log("time:", _$1.Date.now() - _$1.start);
_$1.start = _$1.Date.now();
if (_$1.n++ < 1000) _$1.setTimeout(_$1.f, 0);
}
let _1 = false;
f = _0;
start = undefined;
n = undefined;
n = 0;
var _$0 = Date.now();
if (typeof _$0 !== "number") {
throw new Error("Prepack model invariant violation: " + _$0);
}
start = _$0;
}).call(this);
Here's what's going on: Prepack only optimizes code that gets _executed_ along the global code path - that's what we consider the _initialization phase_. Residual functions such as f just get carried over into the prepacked code (with some tweaks to properly resolve captured variables). As f doesn't get invoked here, it doesn't get optimized. Small wrinkle: If you would invoke f, I'd expect that you get an internal TODO telling you that setTimeout is not yet supported.
I think that this is more of a case of lack of constant folding. The constant c is false and so the inner functions don't get eliminated.
Prepack currently doesn't do constant folding since that's a task that most minifiers will do for you. We recommend that you use a minifier after Prepacking which will take care of that.
Right. This keeps coming up. I created a dedicated issue for this that describes in some more detail what's going on, and what needs to happen: #632