优化css和JavaScript文件(压缩和合并js和css文件)
说到优化的时候,我们需要想到:压缩,拼接。也就是减少体积和HTTP次数。
我们面临的主要问题是很难按照正确的顺序合并文件。
<script src="./js/1.js"></script>
<script src="./js/2.js"></script>
<script src="./js/3.js"></script>
像这样一个文件需要引入3个js,我们希望减少http的请求次数,我们可以将这3个js合并成一个js。
我们需要gulp-useref
安装和引用如下:
npm install gulp-useref --save-dev
引用和task如下:
var useref = require('gulp-useref');
gulp.task('useref', function(){
return gulp.src('app/*.html')
.pipe(useref())
.pipe(gulp.dest('dist'))
});
下面是未进行处理的 js 引用:
<!--build:js js/main.min.js -->
<script src="./js/1.js"></script>
<script src="./js/2.js"></script>
<script src="./js/3.js"></script>
<!-- endbuild -->
<!--build:js js/main.min.js -->
<!-- endbuild -->
这个写法是必须的:表示的是将这3个js合并成一个js的名称;
下面是经过 useref处理后的:
<script src="js/main.min.js"></script>
这个处理后的文件目录;
上面的方法比较智能,但用的人并不是很多,下面介绍用的多的一个
gulp-concat
用法是将指定目录下的js合并成指定名称的js文件;
npm install gulp-concat--save-dev
具体用法:
gulp.task('concat', function(){
return gulp.src('app/js/*.js')
.pipe(concat('abiz.js'))
.pipe(gulp.dest('dist'))
});
处理之前的目录:
处理后的:
下面再对合并后的文件进行压缩操作,需要用到 gulp-uglify
npm install gulp-uglify--save-dev
我们将上面的代码修改下:
gulp.task('concat1', function(){
return gulp.src('app/js/*.js')
.pipe(concat('abiz.js'))
.pipe(uglify())
.pipe(gulp.dest('dist'))
});
这样合并后的 abiz.js 已经进行压缩后的。
中间还可以加一些其他的操作,例如:可以使用gulp-rename,修改压缩后文件的后缀,修改上述代码:
gulp.task('concat1', function(){
return gulp.src('app/js/*.js')
.pipe(concat('abiz.js'))
.pipe(rename({suffix: '.min'}))
.pipe(uglify())
.pipe(gulp.dest('dist'))
});
我们将压缩后的文件自动加个.min的后缀。
现在说说为什么 useref 比 concat 智能,为啥用的少。现在合并js文件和压缩js文件是一系列的操作,但是如果用useref进行合并js文件,但是如果再进行压缩文件,那么并不能在一个task中完成,原因是 useref所需要的src源是*.html,在进行合并后的文件源还是.html,但是对文件进行压缩的uglify()需要的src是.js类型的文件,并不能继续pipe接下来的操作。但cancat的目标文件就是.js。(这是个人理解,我觉得是这样的哈!)
压缩js基本说完了,css的合并和压缩和js基本一样,css的压缩需要用到 gulp-minify-css,具体的操作基本一样,这里就不在详细讲解了。
下面大概的提一提对图片的处理:
优化图片 使用 gulp-imagemin 插件。
操作的代码如下:
var imagemin = require('gulp-imagemin');
gulp.task('images', function(){
return gulp.src('app/images/**/*.+(png|jpg|gif|svg)')
.pipe(imagemin())
.pipe(gulp.dest('dist/images'))
});
我试试了,好像图片没有变的更小。。。。
所以让我们来试试深入了解如何对图片压缩进入更深的层次。
上面的pipe(imagemin({})),如果不写则是都以默认的配置,我们去看看具体的配置都有哪些。
optimizationLevel: 5, //类型:Number 默认:3 取值范围:0-7(优化等级)
progressive: true, //类型:Boolean 默认:false 无损压缩jpg图片
interlaced: true, //类型:Boolean 默认:false 隔行扫描gif进行渲染
multipass: true //类型:Boolean 默认:false 多次优化svg直到完全优化
这些是基础的配置,基于gulp-imagemin这个插件还可以使用其他的插件对图片再一次进行优化操作。
分别是 imagemin-pngquant 和 imagemin-jpegtran
通过插件的名字可以看出是基于上者的。
先看看官方文档
imagemin-pngquant
imagemin-jpegtran
imagemin-jpeg-recompress
以imagemin-jpeg-recompress为例子,因为这里的参数比较多:
accurate: true,//高精度模式
quality: “high”,//图像质量:low, medium, high and veryhigh;
method: “smallfry”,//网格优化:mpe, ssim, ms-ssim and smallfry;
min: 70,//最低质量
loops: 0,//循环尝试次数, 默认为6;
progressive: false,//基线优化
subsample: “default”//子采样:default, disable;
我们在引入这些插件如何使用:
gulp.task('imagemin',function () {
return gulp.src('app/img/**/*.+(png|jpg|jpeg|gif)')
.pipe(imagemin({
use: [imageminPngquant,imageminJpegtran]
}))
.pipe(gulp.dest('dist/image'))
})
在imagemin这个func里直接一个对象,当然如果这样写,这些插件用的都是默认的选项。我们也可以这样写:
gulp.task('imagemin',function () {
var jpgmin = imageminJpegRecompress({
accurate: true,
quality: "high",
method: "smallfry",
min: 70,
loops: 0,
progressive: false,
subsample: "default"
})
return gulp.src('app/img/**/*.+(png|jpg|jpeg|gif)')
.pipe(imagemin({
use: [jpgmin]
}))
.pipe(gulp.dest('dist/image'))
})
到目前为止,用到的所有的插件都是有内部配置的,增加更具体的配置可以去官网查询。这里不细讲。
组合Gulp任务
废话了这么多,我们主要有两条线路。
第一条是开发过程,我们便以Sass,监听文件,刷新浏览器。
第二条是优化,我们优化CSS,JavaScript,压缩图片,并把资源从app移动到dist。
开发任务我们上面的watch已经组装好了。
就是这个:
gulp.task('watch1',gulp.series('sass1',function(){
browserSync.init({
server: "./app"
});
gulp.watch('app/scss/**/*.scss', gulp.series('sass1'));
gulp.watch("app/*.html").on('change', browserSync.reload);
}));
我们这次来说第二条线:
我们把合并的文件,压缩的文件放到dist文件夹内,但是每次操作的时候我们先要清理dist文件夹,这里需要用到 del
npm install del --save-dev
var del = require('del');
gulp.task('clean', function() {
del('dist');
});
现在都差不多了,但是还有个问题,就是我们要确保clean任务在其他任务前优先执行,所以这里需要用到 RunSequence
但是下面的写法是基于 gulp 3.xxx 的,我本地装的是 gulp 4.xxx ,并不支持以下的写法,我只是带大家大概了解一下,讲完,我会为大家介绍 gulp 4.xxx 的解决方案。
npm install run-sequence --save-dev
var runSequence = require('run-sequence');
gulp.task('task-name', function(callback) {
runSequence('task-one', 'task-two', 'task-three', callback);
});
执行task-name时,Gulp会按照顺序执行task-one,task-two,task-thre。
RunSequence也允许你同时执行多个任务。
gulp.task('task-name', function(callback) {
runSequence('task-one', ['tasks','two','run','in','parallel'], 'task-three', callback);
});
在gulp4.xxx中,官方提供了 gulp.series() 和 gulp.parallel()方法,gulp.series(‘a’,‘b’,‘c’),这样的写法表示,会依次执行任务 a,b,c。
gulp.parallel(f,g,h)表示任务 f,g,h 会同步执行。 并且2者任务可以并用。我们修改我们本地的代码:
gulp.task('build',gulp.series('clean',gulp.parallel('concat1','images')));
在执行 build 任务的时候 会优先进行clean 任务清空dist文件夹,然后再同步执行 concat1 和 images;
总结
gulp 简单易懂 ,易入手,对开发者友好。