【问题标题】:UglifyJS: concat and minify or viceversa?UglifyJS:连接和缩小或反之亦然?
【发布时间】:2012-06-14 13:35:51
【问题描述】:

我正在编写一个使用许多 JS 文件的应用程序。 Underscore、Backbone、jQuery、滑块的 jQuery 插件,模型、路由器、集合和视图的几个文件。

在我的开发机器中,我分别加载每个文件,但在生产中我只使用一个 JS 文件(缩小、gzip 压缩、较少的 http req 等)。

在我的构建过程中,每个文件都用 UglifyJS 缩小,然后连接到 prod.js。这是构建该文件的正确方法吗?还是应该将每个文件连接到 prod.js 中,然后用 UglifyJS 缩小?

非常感谢!

【问题讨论】:

  • 这取决于使用的算法,但通常我会先连接然后缩小。

标签: javascript deployment uglifyjs


【解决方案1】:

我使用Gulp 测试了每种方法的输出。

测试设置

我使用了 9 个 JavaScript 文件,总计 19.15 kB 连接(未缩小)。每个文件都以 'use strict'; 语句开头。

结果:

  • 连接 => 丑化:7.993 kB
  • Uglify => 连接:8.093 kB
  • 差异: 0.1 kB

注意事项:

  • 连接 => Uglify 去除 9 个中的 8 个 'use strict'; 语句
  • Uglify => 连接保留所有'use strict'; 语句
  • 单个'use strict'; 语句是13 个字节。 8 × 13 字节 = 104 字节,相差 0.1 kB。

最后的想法:

使用您喜欢的顺序。

这两个过程之间的区别可以忽略不计。 Concatenate => 如果满足以下两个条件,Uglify 可以(理论上)产生(几乎不明显)更小的文件:

  • 几个单独的文件以'use strict'; 语句开头
  • 很多个单独的文件

这是我使用的gulpfile.js

var gulp = require('gulp'),
  concat = require('gulp-concat'),
  uglify = require('gulp-uglify');

var files = [
  '!app/scripts/**/*Spec.js', // Exclude test files
  'app/scripts/**/*.js'
];

// Register tasks
gulp.task('concat-min', function() {
  return gulp.src(files)
    .pipe(concat('script.min.js'))
    .pipe(uglify())
    .pipe(gulp.dest('dist'));
});

gulp.task('min-concat', function() {
  return gulp.src(files)
    .pipe(uglify())
    .pipe(concat('script.min.js'))
    .pipe(gulp.dest('dist'));
});

【讨论】:

  • 很好的测试,虽然在现实世界中,你永远不应该有全局的“使用严格”语句,这是一个巨大的皮塔要处理。我正在考虑从 Concat+Uglify 切换到 Uglify+Concat,因为当我遇到语法错误时,当错误字面意思是“意外的标记,第 19257 行”时,发现它们会很痛苦
【解决方案2】:

如果任何一种方式都对用户请求的开销产生重大影响,我会感到惊讶。

我还建议将所有这些框架连接到一个文件中实际上可能增加每个用户的开销。

为什么?

当使用流行/通用框架(例如 jQuery 等)时,将其托管在 CDN 上(例如 Google)以从缓存文件中受益 - 如果用户访问的网站也使用了 jQuery,他们根本不需要下载!更不用说减少地理延迟。

因此,通过创建您自己的独特文件,您就更有可能让用户不得不下载整个文件。

【讨论】:

  • 我宁愿先合并。由于 RichardJ 和 HotHeadMartin 提到的原因,或者更简单地说,它更安全、更有效。关于 CDN,我不会指望它。
  • 另外,您可以在使用 CDN 时进行更多并行连接。就我而言,我使用的是 webview,因此文件被预缓存的可能性为零。我先连接然后 uglify,但是为了在出现语法错误时保持理智,我认为 uglifying 然后连接是更好的方法。
【解决方案3】:

我总是将它们全部合二为一,然后再缩小。

我已经开始做的一件事是运行它,虽然 http://www.javascriptobfuscator.com/ 首先我知道这听起来很直观,但它所做的事情之一是将所有字符串存储在一个数组中,一个丑陋的数组,但是当你停止字符串重复时转到您的缩小版,我使用 Google Closure 编译器,然后它会整理字符串,您通常会得到一个更好的缩小版文件

【讨论】:

  • 我尝试在 UglifyJS 中实现这种技术(我的意思是单独存储字符串以避免重复),并注意到在 gzip 之后压缩文件比没有弄乱字符串时可靠地大。
【解决方案4】:

我强烈建议您使用requirejs,使用该库您可以制作软件包或一个最小化和统一的文件。请阅读优化工具

但是,正如 Widor 告诉您的,将所有文件合并为一个并不是一个好主意。如果您总是在线使用您的应用程序,那么其中许多库使用 google api (CDN) 性能会更好

【讨论】:

    【解决方案5】:

    不会有太大区别,因为顶层语句(和变量等)没有被触及。

    但是,当使用--lift-vars 选项时,它可能会发生变化。这在很大程度上取决于您的代码。

    【讨论】:

      【解决方案6】:

      假设你有更少的全局变量,顺序不会有太大的影响。文件大小差异非常小。我个人的偏好是 Concatenate,然后是 Uglify,它可以让您生成更好和准确的源图,而不是其他方式。 (这是因为源映射随每次转换而变化)。我想知道丑化小文件然后连接的目的是什么。基本上,这取决于你,选择权在你。连接和丑化似乎更令人满意且不易出错

      【讨论】:

        猜你喜欢
        • 2021-05-12
        • 1970-01-01
        • 2013-09-21
        • 1970-01-01
        • 2010-09-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-10
        相关资源
        最近更新 更多