Google的Closure Compiler编译为更高效的JavaScript。我可以想象一些简单的例子,例如Closure Compiler通过直接调用函数或用文字替换常量来减少调用堆栈。但是documentation更进一步说,
“Closure编译器可以使用有关JavaScript的数据类型信息 变量提供增强的优化和警告。“
我的理解是类型化语言有两个好处:1)类型检查可以在编译期间捕获错误 - 我可以看到Closure Compiler如何模拟这种行为 - 和2)程序实际执行得更快,因为它被编译到另一个语言(比如Java到Java字节码)。使用Closure Compiler,输出仍然是JavaScript。如何根据类型信息进行优化?
答案 0 :(得分:1)
一个例子是disambiguateProperties功能,在http://closuretools.blogspot.com/2011/01/property-by-any-other-name-part-3.html
中描述正如帖子所描述的,这允许编译器选择较短的属性名称。它还允许编译器消除更多的死代码。假设您在代码中调用x.foo()
,并且有两种不同的类型都采用foo
方法:
X1.prototype.foo = function() {
// Lots and lots of code...
};
X2.prototype.foo = function() {
// Lots and lots of code...
};
如果编译器不知道x
是什么类型,它必须在代码中保留两个长foo
方法,即使其中一个方法可能永远不会被调用。如果它知道x
属于X1
类型,那么它会将方法重命名为X1$foo
和X2$foo
(或类似的东西)。然后,它可以看到永远不会调用X2$foo
,因此它会从编译的代码中删除它。这意味着下载和解析的代码更少,因此它可以使页面感觉加载速度更快,并且JS解释器必须保留在内存中的功能少一个。
答案 1 :(得分:1)
Closure Compiler中基于类型的“优化”本身并不是纯粹的优化。在编译器术语中,它严格暴露了其他优化的机会。
以下是我在http://closure-compiler.appspot.com/home
上构建的示例// ==ClosureCompiler==
// @compilation_level ADVANCED_OPTIMIZATIONS
// @use_types_for_optimization true
// @formatting pretty_print
// @output_file_name default.js
// ==/ClosureCompiler==
/** @constructor */
function X(){}
X.prototype.foo = function() {alert("X")};
/** @constructor */
function Y(){}
Y.prototype.foo = function() {alert("Y")};
window.i = new X();
window.j = new Y();
/**
* @param {!X} x
*/
window.keep = function(x) {
x.foo();
}
如果您将* use_types_for_optimization * true 切换为 false ,您会注意到该警报不再被内联。请注意,如果没有类型信息,则无法告诉调用者 keep 始终是 X 。
从这个意义上说,类型信息有助于内联。
希望有所帮助。
答案 2 :(得分:0)
文档没有说明创建执行速度更快的代码。编译器的重点始终是检查和代码大小。虽然它可以生成运行速度更快的代码(通常通过删除间接),但它也可以创建运行速度较慢的代码,因为它创建的代码违反了JS VM的某些优化标准(创建过大的函数等)。