Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to make Google Closure compiler *not* inline certain functions?

Closure compiler is inlining a function, but the code size is smaller if that function is not inlined (I only care about code size - this is for JS1k). Can I tell the compiler that I don't want that function inlined?

Edit: Just to explain a bit better, here's my function:

function lineTo(x,y) {
  a.lineTo(x,y);
}

where a in the canvas context. Because there are so many a.lineTos in the code, having this function used is worth it. Like this, my code is 1019 bytes (and all the lineTos are replaced by a.lineTo). If I change the function to:

function lineTo(x,y) {
  a.lineTo(x,y);
  console.log();
}

the new line somehow forces the compiler to not inline this function, which gives me 993 bytes. So if I could get rid of the console.log(); I'd save another 14 bytes.

like image 281
Skilldrick Avatar asked Nov 28 '10 16:11

Skilldrick


2 Answers

From the tutorial:

If...you find that Closure Compiler is removing functions you want to keep, there are two ways to prevent this:
* Move your function calls into the code processed by Closure Compiler.
* Export the symbols you want to keep.

You probably want the second, which is discussed here, but basically comes down to explicitly setting it as a window property:

function foo() {
}
window['foo'] = foo;

For your JS1k submission, you'd just leave the last line off as it's unneeded. note that Closure will still rename the function, but as it starts renaming your symbols with the name a and continues from there, it's unlikely to make your names longer overall.

You can try it out with the online compiler service. If you paste this in:

// ==ClosureCompiler==
// @compilation_level ADVANCED_OPTIMIZATIONS
// @output_file_name default.js
// ==/ClosureCompiler==

// ADD YOUR CODE HERE
function hello(name) {
  alert('Hello, ' + name);
}
hello('New user');

...the compiled result is

alert("Hello, New user");

But if you add

window['hello'] = hello;

...to the end, the compiled result is:

function a(b){alert("Hello, "+b)}a("New user");window.hello=a;
like image 79
T.J. Crowder Avatar answered Oct 26 '22 18:10

T.J. Crowder


This is an old question, but as of v20180101, Google Closure Compiler has an annotation that prevents inlining: @noinline.

In your original example, all you'd need is to add jsdoc with this annotation in front of the function that shouldn't be inlined:

/** @noinline */
function hello(name) {
  alert('Hello, ' + name);
}
hello('New user');
like image 20
fstanis Avatar answered Oct 26 '22 17:10

fstanis