小编说:每个Web应用程序都会有CSS和JavaScript文件。现在大多数应用程序都包含很多CSS和JavaScript文件,用来增强应用的粘度与互动效果。每个CSS和JavaScript文件都需要浏览器向服务器发送请求,以获取文件内容。 因此,CSS和JavaScript文件越多,浏览器需要发送的请求就越多,从而越容易影响其性能。 本文我们将讨论两种针对CSS、JavaScript文件的优化手段——合并和缩小。本文选自《高性能PHP 7》。
性能在Web应用程序中起着至关重要的作用,甚至谷歌也很在意其查询性能。不要因为一个几KB的文件只需要1毫秒的下载时间就不去重视,因为涉及性能时每个毫秒都需要去关注。最好能优化、压缩和缓存一切。
- 合并
在合并过程中,我们可以将所有CSS文件合并为一个文件,并且使用同样的方法对JavaScript文件进行合并,从而为CSS和JavaScript创建一个单独的文件。假如我们有10个CSS文件,浏览器要发送10个请求给所有这些文件。但是,如果我们将它们合并到一个文件中,浏览器只需发送一个请求即可,从而节省了9个请求所需的时间。
- 缩小
在缩小过程中,从CSS和JavaScript文件中删除所有空行、注释和额外空格。这样,文件尺寸大大减小,从而文件加载速度更快。
我们来看看下面这段CSS代码。
代码语言:javascript复制.header {
width: 1000px;
height: auto;
padding: 10px
}
/* 让区域位于左侧 */
.float-left {
float: left;
}
/* 让区域位于右侧 */
.float-right {
float: right;
}
在缩小文件后,我们将得到如下所示的CSS代码。
代码语言:javascript复制.header{width:100px;height:auto;padding:10px}.float-left{float:left}.float-right{float:right}
同样地,缩小文件的方法也可以用于JavaScript中,代码如下。
代码语言:javascript复制/* 在页面上显示一个弹框 */
$(document).ready(function() {
alert("Page is loaded");
});
/* 三个数相加 */
function addNumbers(a, b, c) {
return a b c;
}
在缩小文件后,得到如下JavaScript代码。
代码语言:javascript复制$(document).ready(function(){alert("Page is loaded")});function addNumbers (a,b,c){return a b c;}
可以看到,在缩小后的代码中,所有不必要的空白空间和空白行都被去掉了。此外,该示例将完整的代码放在一行,所有代码注释也都被删除了。这种缩小尺寸的方法有助于快速装载,并且该文件将消耗更少的带宽,这在服务器资源有限的情况下是非常有用的。
大多数开源应用程序,如Magento、Drupal和WordPress,对缩小文件提供了内置支持,或通过第三方插件/模块支持这一功能。在这里我们不介绍如何在这些应用程序中合并CSS或JavaScript文件了,只讨论一些可以合并CSS和JavaScript文件的工具。
1 Minify
Minify是一组完全使用PHP编写的库。Minify支持CSS、JavaScript文件的合并与缩小,代码是完全面向对象和命名空间的,所以它可以嵌入任何当前流行或自主研发的框架中。
现在创建一个小项目,我们将缩小和合并CSS与JavaScript文件。项目的文件夹结构如下图所示。
上图显示了完整的项目结构。项目名称为minify。css文件夹中包含所有CSS文件,包括最小化后的文件与合并后的文件。同样,js文件夹中包含所有JavaScript文件,也包括最小化后的文件与合并后的文件。libs文件夹中包含Minify库以及Converter库。Index.php中是缩小和合并CSS与JavaScript文件的主要代码。
项目树中的data文件夹都是JS最小化后的内容。由于JavaScript的关键字需要前后都有空格,因此这些.txt文件可以用于标识它们。
下面,我们用index.php中的代码缩小CSS和JavaScript文件。
代码语言:javascript复制include('libs/Converter.php');
include('libs/Minify.php');
include('libs/CSS.php');
include('libs/JS.php');
include('libs/Exception.php');use MatthiasMullieMinify;/* 最小化CSS */
$cssSourcePath = 'css/styles.css';
$cssOutputPath = 'css/styles.min.css';
$cssMinifier = new MinifyCSS($cssSourcePath);
$cssMinifier->minify($cssOutputPath);/* 最小化JS */
$jsSourcePath = 'js/app.js';
$jsOutputPath = 'js/app.min.js';
$jsMinifier = new MinifyJS($jsSourcePath);
$jsMinifier->minify($jsOutputPath);
这段代码比较简单。首先引入了许多需要用到的lib库文件。然后,在Minify CSS代码段中指定了两个文件路径,一个是原CSS文件地址,用变量cssSourcePath标识,另一个是最小化后的CSS文件地址,用变量cssOutputPath标识。之后,实例化了一个CSS.php类的对象,并传递了需要缩小的CSS文件。最后,调用CSS类的minify方法,并与文件名一起传递输出路径,这将生成所需的最小化后的文件。
同样的办法也可以用来处理JS文件。
在所有的文件都存在的情况下运行上面的PHP代码,运行后,两个新的文件名将被创建,即styles.min.css和app.min.js。这些是原始文件的最新最小化的版本。
现在,我们使用Minify来合并多个CSS和JavaScript文件。首先,将一些CSS和JavaScript文件添加到项目的相应文件夹中。然后只需要添加一点代码到当前的代码段中即可。在下面的代码中,我将跳过所有的库,但当你使用Minify时必须要加载这些文件。
代码语言:javascript复制/* 最小化CSS */
$cssSourcePath = 'css/styles.css';
$cssOutputPath = 'css/styles.min.merged.css';
$cssMinifier = new MinifyCSS($cssSourcePath);
$cssMinifier->add('css/style.css');
$cssMinifier->add('css/forms.js');
$cssMinifier->minify($cssOutputPath);/* 最小化JS */
$jsSourcePath = 'js/app.js';
$jsOutputPath = 'js/app.min.merged.js';
$jsMinifier = new MinifyJS($jsSourcePath);
$jsMinifier->add('js/checkout.js');
$jsMinifier->minify($jsOutputPath);
看一下加粗显示的代码。在CSS部分,我们将缩小的文件和合并文件保存为style. min.merged.css,命名不重要,这完全取决于我们自己的意愿。
现在,我们将使用cssMinifier和jsMinifier对象的add方法添加新文件,然后调用minify。这将使所有附加文件合并到初始文件中,然后生成单个合并的缩小文件。
2. Grunt
根据官网介绍,Grunt是一个JavaScript任务运行器,它能够将某些重复的任务自动化,避免反复工作。Grunt是一个非常好的工具,并被程序员们广泛使用。
安装Grunt非常简单。这里我们介绍将它安装在MAC OS X系统上的流程,在Linux系统(如Debian、Ubuntu)上安装的方法与之相似。
假设Node.js与npm已经安装在你的计算机上,首先执行下面的命令。
代码语言:javascript复制sudo nom install -g grunt
执行后将会安装Grunt命令行客户端。执行结束后,使用如下命令查看Grunt的版本信息。
代码语言:javascript复制grunt -version
输出信息显示grunt-cli v0.1.13,表明这是当前的Grunt版本。
Grunt为使用者提供了命令行,使大家能够运行Grunt命令。Grunt项目需要项目文件树中的两个文件:一个是package.json,由npm使用,并列出Grunt和项目需要的Grunt插件,例如DevDependencies;另一个是GruntFile,可以分为GruntFile.js或GruntFile.coffee,用于配置Grunt及其插件。
现在我们依然使用前面的项目示例,但是目录结构有所变化。
打开命令行终端,以root权限身份执行如下命令。
代码语言:javascript复制sudo npm init
在终端中交互式地回复几个问题,将生成一个package.json文件。打开package. json文件并且按如下内容修改配置。
代码语言:javascript复制{
"name" : "grunt" //项目名
"version : "1.0.0" //项目版本
"description" : "Minify and Merge JS and CSS file",
"main" : "index.js",
"DevDependencies" : {
"grunt" : "0.4.1", //Grunt版本 //Concat插件用于合并css和js文件
"grunt-contrib-concat" : "0.1.3"
//CSS最小化插件
"grunt-contrib-cssmin" : "0.6.1",
//Uglify插件用于缩小JS文件.
"grunt-contrib-uglify" : "0.2.0"
},
"author" : "Altaf Hussain",
"license" : ""
}
代码中添加了一些注释方便大家理解。但在最终部署使用时,这些内容会被删除。
我们找到DevDependencies处的配置,添加三个Grunt插件。
最后一步是添加GruntFile文件,创建一个GruntFile.js文件放在项目的根目录下,填写内容如下。
代码语言:javascript复制module.exports = function(grunt) {
/*加载package.json文件*/
pkg: grunt.file.readJSON('package.json'),
/*默认Tasks*/
grunt.initConfig({
concat: {
css: {
src: [
'css/*' //加载CSS目录下的所有文件
],
dest: 'dest/combined.css' //最终组合成的目标文件.
}, //CSS结束
js: {
src: [
'js/*' //加载所有的JS
],
dest: 'dest/combined.js' //最终组合成的目标文件.
}, //js结束
}, //End of concat
cssmin: {
css: {
src : 'dest/combined.css',
dest : 'dest/combined.min.css'
}
},//cssmin结束
uglify: {
js: {
files: {
'dest/combined.min.js' : ['dest/combined.js'] //目标地址
Path : [src path]
}
}
} //uglify结束
}); //initConfig结束
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.registerTask('default', ['concat:css', 'concat:js',
'cssmin:css', 'uglify:js']);}; //module.exports结束
上面的代码清晰明了,关键环节也添加了注释。代码开始处引入了package.json文件,之后定义了不同的任务及其源文件和目标文件。要知道,每一个任务的源与目标语法都不相同,这取决于插件。在initConfig区块后,我们加载了不同的插件与npm任务,之后将它们注册到了GRUNT中。
运行任务。
首先合并CSS与JavaScript文件并保存到被定义的目标地址,使用如下命令。
代码语言:javascript复制grunt concat
运行上面的命令后,如果看到Done、without errors,说明任务顺利执行。
同样地,使用如下代码最小化CSS文件。
代码语言:javascript复制grunt cssmin
之后,通过下面这行命令优化JavaScript文件。
代码语言:javascript复制grunt uglify
至此,我们已经使用Grunt进行了不少操作,它还提供了其他更多功能,可以使开发人员节省很多时间。例如,如果需要更改JavaScript和CSS文件怎么办?要再次运行上述所有命令吗?不,Grunt提供了一个watch插件,可以激活并执行任务目标路径中的所有文件,无论发生什么更改,它都会自动运行起来。
更多的细节可以查看Grunt的官方网站:http://gruntjs.com/。