使用Google Closure Compiler优化jQuery应用程序

38

我已经在使用 jQuery 并基于它构建了一个大型应用程序。最近,我正在审查 Google Closure 库,但目前发现它并不像 jQuery 那样优雅。我认为它可能有一些潜力,会进一步研究它,但目前我打算继续使用 jQuery 作为我的基础框架。

然而,我非常 impressed with Google Closure Compiler。我很想在应用程序的构建过程中开始使用它。不幸的是,如果项目不遵循标准的 Google Closure 标准,它将不会很容易使用。

是否有任何关于开发基于jQuery项目并使用Google Closure编译器的最佳实践或良好资源?例如:

  1. 是否有意义用它来编译 jQuery 和 jQuery UI 或者仍然指向 Google CDN 上的这些资源?我确定我的 jQuery 和 jQuery UI 将更小,因为我不使用这些库的所有功能,但是指向CDN会增加文件已经在访问者缓存中的机会。

  2. 我的应用程序被分成许多文件,每个函数有一个文件。我想按特定顺序组合它们,并将它们缩小到站点上的每个部分一个文件。我想自动化这个过程。

  3. 目前我的项目具有Java后端,并且使用Maven构建。是否有意义将Google Closure编译器添加到此构建过程中?

基本上,我正在寻找任何与在 jQuery 中使用 Google Closure 编译器相关的良好资源。


请查看http://code.google.com/intl/pt-BR/closure/compiler/docs/api-tutorial3.html#mixed。 - Trinidad
8个回答

10

$(elem)['width']() 替换为 $(elem).width()

这样做可以在进行高级优化时使用,使闭包编译器不会重构 jQuery 的方法。


你可以只需包装你的脚本... (function($){...}(window['jQuery'])) - Tracker1
3
@Tracker1,那样做没有帮助:编译器会正确调用$函数,但会“优化”该方法,导致$(elem).width()变成类似于$(elem).a()的形式。 - JJJ

10

Google Closure Compiler不依赖于jQuery或任何其他库。 它有两种优化类型:

  • 简单
  • 高级

我尝试应用高级优化,但它严重破坏了我的应用程序。如果它对您的应用程序产生相同影响,则可以尝试修复您的应用程序或使用简单优化。简单优化可以减少32%的大小,高级优化可以减少约68%的大小,但无论如何都不能正常工作。

以自动化方式将JS串联到您的构建过程中绝对是正确的方式。请参见JavaScript Dependency Management

jQuery已经针对字节大小进行了大量优化,因此我怀疑您将能够通过使用Google Closure Compiler来挤出足够的性能,但是结合您的项目使用它仍然值得一试。

我认为Google Closure Library很好,但还没有开始使用它,因为我已经在MooTools上投入了大量精力。从其API来看,它似乎涵盖了除DOM操作、AJAX处理、事件处理等之外的许多方面。


谢谢!我确实发现Google Closure Library有一些吸引人的地方,但在使用了jQuery之后,它的API似乎过于冗长。然而,有一些功能确实让我感兴趣,这就是为什么我正在尝试确定是否有一种有效的方法可以将GCC和GCL与jQuery一起使用。 - Tauren
使用jQuery和GCL是完全可行的,因为它们都是好的命名空间库,分别位于jQuery/$goog中,并且它们都不修改一些人认为是额外加分的基本原型。在某些领域,例如DOM、事件、AJAX等方面,您可能会有冗余功能,您可以选择使用jQuery来处理这些功能,而使用GCL来处理其他功能。也许编写一个小的桥接层,用于包装/解包DOM节点,因为jQuery需要包装对象,而GCL则期望本机DOM节点。 - Anurag
至少对我来说,我仅使用GCL的编辑器。这是我迄今为止见过的最好的开源编辑器。具有广泛的文档。此外,您可以轻松创建自己的自定义插件。对于其余简单的DOM修改/AJAX功能,我使用JQuery。 - Shripad Krishna
2
jQuery已经针对字节大小进行了大量优化,因此我怀疑您是否能够通过使用Google Closure Compiler来挤出足够的性能。这种情况可能会在未来发生改变。jQuery团队正在研究Closure Compiler的高级优化(特别是死代码的删除),以自动删除您的应用程序实际上并不使用的任何功能。如果这成为现实,那将非常棒! http://blog.jquery.com/2011/11/22/call-for-jquery-1-8-ideas/ - Richard Connamacher
Google Closure Compiler 在开启高级优化后并不适用于所有库。如果你没有正确安排好代码,使其能够正确识别死代码(使用特殊注释,声明或包含依赖项),那么你会很失望。另一方面,如果你确实将它们正确布置,你将可以得到任何缩小器中最小的压缩输出。 - Chris Moschini
Closure编译器会剥离掉很多jQuery代码。为什么呢?因为它会移除在你的代码中从未使用过的函数。有很大可能你并没有使用很多jQuery的函数,所以这样做可以带来显著的性能提升。 - Digits

9
我相信从1.4.2版本开始(或许更早),jQuery默认使用Google Closure Compiler进行缩小。因此,最好继续通过Google CDN引用jQuery/jQuery UI。然而,将Closure编译器集成到构建过程中以合并和缩小JS文件仍然有益处。具体来说,每个页面加载的JS请求减少,传输的数据变小,有望提高客户端页面加载性能。这些是我们在将Closure编译器集成到构建过程中遇到的一些挑战:
  1. 构建编译命令 - 我们需要一种在构建过程中以自动化方式调用编译器并传递所有必要参数的方法。对我们来说,这意味着编写控制台应用程序来构造命令。如果您的环境支持shell脚本,那可能是一个优势。

  2. 管理依赖项 - Closure编译器确实具有自动排序组合JS的能力,以保留依赖关系。为了利用此功能,必须使用goog.provide\goog.require为JS文件进行注释,以告诉编译器依赖关系是什么(--manage_closure_dependencies)。编译器还将从组合JS中排除任何不需要的JS(即未通过goog.require语句引用的JS)。以下是一些需要注意的事项:

    • 如果要在组合输出中包含所有JS文件,请确保在编译中包含一个“清单”JS文件,该文件仅包含每个要包含的文件的goog.require语句(即没有goog.provide语句)。
    • 如果您没有使用Closure库,请确保使用SIMPLE_OPTIMIZATIONS或更高版本进行编译。否则,编译器将不会删除goog.provide/goog.require语句。或者,您还可以定义自己的goog.provide/goog.require JS函数以避免出错。
    • 确保没有循环依赖项,否则将面临后果。
  3. 编译组合脚本的调试版本 - 如果需要,您可以使用--formatting PRETTY_PRINT标志编译组合脚本的调试版本。这将输出等效的脚本,并保留用于开发/调试的空格。

虽然闭包编译器的文档有时可能比较稀少,但它已经足够让你开始使用,并且一直在不断改进 - 因此请定期检查更新,而不仅仅是在 Stack Overflow 上;)希望这能帮到你。

5

5

4
使用extern文件编写答案。 - Taha Jahangir

4
使用闭包编译器/高级版使jQuery正常工作对我来说很困难,但由于你正在处理多个文件,我认为在这里查看模块选项非常重要: 使用Closure Compiler中的--module选项创建多个输出文件 我一直在网上搜寻良好的文档,但是真的非常少。通过使用单个jQuery外部,我能够很好地进行编译——包括多个文件等。
@echo off
java -jar bin\compiler.jar ^
    --compilation_level=ADVANCED_OPTIMIZATIONS ^
    --externs "externs\jquery-1.8.js" ^
    --language_in=ECMASCRIPT5_STRICT ^
    --warning_level=VERBOSE ^
    --module_output_path_prefix .\compiled\ ^
    ^
    --module_wrapper core:"(function(){%%s%%})();" ^
    --js ".\corelib.js" ^
    --module core:1 ^
    ^
    --module_wrapper somescript"(function(){%%s%%})();" ^
    --js ".\some_other_runtime_loaded_script" ^
    --module somescript:1:core ^
    ^
    --module_wrapper somescript1:"(function(){%%s%%})();" ^
    --js ".\some_other_runtime_loaded_script" ^
    --module somescript1:1:core

描述

--module_wrapper name:wrapper

这样可以让你将脚本包装在闭包中 - 因为编译器默认会删除它们。如果像我一样使用"use strict",那么这是不允许的。
--module name:#:dependency

name       Name of the script that will get written
#          number of scripts above that line to include into this script
dependency What script does this depend on?

1
Tauren,你可以使用closure-compiler主页来测试你的代码。你可以导入你的JQuery库或其他东西并尝试它。如果可能的话,使用匿名函数定义你的JavaScript代码,这样可以避免命名冲突。使用Google库的provide函数来使用命名空间。另一个可以帮助你的好资源是Google JavaScript Style Guide

-1

您可以使用kjscompiler:https://github.com/knyga/kjscompiler,并指定任何您喜欢的库作为外部库。它们不会被压缩。这是一个非常好的解决方案。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接