【问题标题】:Use closure compiler to remove unused parts of jQuery使用闭包编译器删除 jQuery 的未使用部分
【发布时间】:2011-08-24 23:35:53
【问题描述】:

是否可以使用闭包编译器来删除 jQuery 的未使用部分?

我有一个只使用 jQuery 的网络 (json) 函数的脚本,我想要一个删除所有其他内容的缩小脚本。

我尝试过调用它:

    java -jar compiler.jar --compilation_level=ADVANCED_OPTIMIZATIONS --js=jquery-latest.js --js=my_script.js  --js_output_file=out.js

但我最终得到的文件不小于常规缩小的 jQuery 源代码。

编辑:我应该提到这背后的原因。该脚本将包含在 3rd 方网站中,它需要更高版本的 jQuery(1.5 或 1.6)。我认为处理此问题的最简单方法是将最新版本捆绑在脚本中(仅适用于我的脚本,不涉及 window.jQuery),删除未使用的部分以减小大小。这样,如果他们已经有旧版本的 jQuery,它就不会干扰。

【问题讨论】:

  • 你缩小了闭包编译的 jQuery 吗?还是您的压缩程序已经删除了死代码?
  • 我缩小了未缩小的 jQuery。我做了一个试验,根本没有添加任何代码,并通过高级优化缩小了 jQuery,期望得到一个空文件,因为没有调用任何方法(如高级优化常见问题解答)
  • 可以从github获取代码。只需 fork 它,删除你不想要的东西并重新构建。

标签: jquery minify google-closure-compiler


【解决方案1】:

在 jQuery 中无法删除“未使用”的方法,因为您可以以疯狂的方式调用方法,例如:

<input id="test" value="hello!"/>

alert($('#test')[prompt('Method?')]()); // input "val" in the prompt box

闭包编译器不可能知道会使用什么方法。

小提琴: http://jsfiddle.net/garreh/xDDXt/


作为一些旁注:

  • 最新的jQuery (1.6) 生产版本只有31kb。通过适当的缓存控制,这将被浏览器下载一次并在本地缓存。
  • 您可能会帮自己一个忙,以优化通常尺寸更大的事物,即图像。
  • ...或减少浏览器请求,例如使用 CSS sprite 技术来更好地优化您的网站。
  • 将您的 jQuery 代码 &lt;script&gt; 标签放在页面底部,以实现更大的下载并行化。 http://developer.yahoo.com/blogs/ydn/posts/2007/07/high_performanc_5/

【讨论】:

  • 更不用说,如果它是一个面向外部的网站,您应该引用 jQuery CDN(Google 或 MS),因此用户很有可能根本不会下载它,并且如果他们这样做了,它会非常快并且与您网站的内容并行下载。
  • 感谢旁注。 @Adam:我添加了一个编辑来解释这样做的原因:包括第 3 方网站中的脚本,依赖于更高版本的 jQuery,但不干扰 3 日已经存在的(可能更低)版本的 jQuery派对网站
  • 问题是在许多网站上 80% 的用户都没有返回所以缓存无法提供帮助..
【解决方案2】:

首先,要删除死代码,您需要高级模式。我看到你已经在使用它了。

其次,必须编写代码以符合使用高级模式的严格限制。我想您已经完成了这项工作并彻底检查了您的代码——否则编译后的代码将无法工作。

然后你需要引用 jQuery “externs” 文件——你可以从 Closure Compiler 的网站上得到它。如果没有这个 externs 文件,Closure 会重命名 jQuery 中不应该的属性和函数。

最后,jQuery 不是为使用 Closure Compiler 的高级模式而编写的。它在许多地方创建了无法优化的“别名”。即使在代码库中的任何地方都有一个别名,整个 jQuery 对象都将被拉入其中。

简短的回答:如果没有大量工作,就不可能使用闭包编译器的高级模式和 jQuery 来删除死代码。

题外话:Dojo Toolkit 是迄今为止唯一可以在高级模式下与 Closure Compiler 一起使用的流行 JavaScript 库(除了 Closure 库)。支持 Closure Compiler 的所有高级功能(例如删除死代码、方法虚拟化、命名空间扁平化等)。

查看此链接以获取 TODO 文档:http://dojo-toolkit.33424.n3.nabble.com/file/n2636749/Using_the_Dojo_Toolkit_with_the_Closure_Compiler.pdf?by-user=t

【讨论】:

  • 您是否可以添加任何解释或示例或参考链接来解释您的陈述it creates "aliases" which cannot be optimized away:什么是“别名”,无法优化?
  • 自这个答案以来,闭包编译器经历了巨大的变化。 2-3年前不可能的事情现在可能不会。我建议您查看编译器的最新文档以找出答案。
  • 基本上,alias 是实现对象相同属性的另一种方法。创建别名的最简单方法是var foo = { bar: 123 }; var baz = foo; 在此示例中,bazfoo 的别名。这意味着foo.bar 有另一个访问它的路径(即baz.bar)。在这种情况下,不可能“扁平化”命名空间(即将foo.bar 重命名为x),因为这样baz.bar 将被挂起。因此别名总是会阻止某些优化。但是,正如我所说,请检查最新的编译器,看看他们是否放宽了这条规则。
【解决方案3】:

编译器不会对 jQuery 库做任何事情的原因有很多,首先是 jQuery“导出”本身:

window.jQuery = jQuery

在高级模式下,这个习语用来告诉编译器一个值在脚本外部使用,所以对象本身永远不会被删除,名称层次结构不会折叠,等等。

如果您删除它,jQuery 会将自己嵌入到匿名函数函数包装器中,这会阻止许多 ADVANCED 模式的全局范围优化(名称层次结构、用于类型分析的类检测等)。

但是,当您删除它时没有太大变化,但我没有寻找下一个问题。

【讨论】:

  • 我曾尝试删除该行,“window.jQuery = window.$ = jQuery;”并得到与您相同的结果:没有任何变化。我怀疑这是因为 Gary 提出的问题,您可以通过多种方式调用 jQuery 的函数,以至于它无法分辨出哪些正在使用,哪些没有。
【解决方案4】:

改用ender

它的理念是一组组合的微框架。不需要功能,就不要将其构建到 ender 中。

如果您只需要 ajax,请将 ajax 模块添加到您的 ender 构建中。

【讨论】:

    猜你喜欢
    • 2013-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-26
    相关资源
    最近更新 更多