引子:
最近在做一个web项目的优化,遇到一个问题,就是在加载初始页面的时候会引用到很多js/css文件,每引用一个文件就会产生一个http请求,这样项目的性能就会受到很大影响。
所以我们决定将js/css文件打包成一个或者几个较大的文件,这样的话可以大量的减少http请求,从而在一定程度上提高系统的性能。
dojo的optimize优化
我使用的dojo是1.6.1版本,在util/buildscripts目录下有一个build.js文件,主要用于release的时候定义一些操作。这个文件主要引用到了jslib下的buildUtil.js文件,查看该文件,可以看到在文件开头有一段DojoBuildOptions,其中包括profile,releaseName,optimize等,具体用法参照每个option中的helpText
其次我们需要用到util/shrinksafe文件夹下的js.jar和shrinksafe.jar,这两个文件分别用来优化和压缩js/css文件
最后需要一个profile文件,在buildscripts/profiles下新建一个xxx.profile.js文件,该文件用于定义所有需要打包的js文件,写法如下:
- /* ***************************************************************** */
- /* */
- /* IBM Confidential */
- /* */
- /* OCO Source Materials */
- /* */
- /* Copyright IBM Corp. 2010 */
- /* */
- /* The source code for this program is not published or otherwise */
- /* divested of its trade secrets, irrespective of what has been */
- /* deposited with the U.S. Copyright Office. */
- /* */
- /* ***************************************************************** */
- dependencies = {
- layers: [
- {
- name: "../compressed/tms.js",
- resourceName: "tms",
- layerDependencies: [
- ],
- dependencies: [
- "dojo.cache",
- "dojox.widget.TitleGroup",
- "dijit.Calendar",
- "dijit.Dialog",
- "dijit.Menu",
- "dijit.MenuBar",
- "dijit.MenuItem",
- "dijit.PopupMenuBarItem",
- "dijit.TitlePane",
- "dijit.Tooltip",
- "dijit.TooltipDialog",
- "dijit._Templated",
- "dijit.dijit",
- "dijit.form.Button",
- "dijit.form.CheckBox",
- "dijit.form.ComboBox",
- "dijit.form.CurrencyTextBox",
- "dijit.form.DateTextBox",
- "dijit.form.DropDownButton",
- "dijit.form.Form",
- "dijit.form.NumberTextBox",
- "dijit.form.RadioButton",
- "dijit.form.RangeBoundTextBox",
- "dijit.form.Select",
- "dijit.form.TextBox",
- "dijit.form.Textarea",
- "dijit.form.TimeTextBox",
- "dijit.form.ValidationTextBox",
- "dijit.form._FormSelectWidget",
- "dijit.layout.BorderContainer",
- "dijit.layout.ContentPane",
- "dijit.layout.TabContainer",
- "dijit.layout._TabContainerBase",
- "dojo.data.ItemFileReadStore",
- "dojo.data.ItemFileWriteStore",
- "dojo.data.ObjectStore",
- "dojo.date.locale",
- "dojo.dnd.Source",
- "dojo.fx",
- "dojo.parser",
- "dojo.store.Memory",
- "dojox.grid.DataGrid",
- "dojox.grid.EnhancedGrid",
- "dojox.grid._EditManager",
- "dojox.grid._RowManager",
- "dojox.grid._RowSelector",
- "dojox.grid.cells._base",
- "dojox.grid.cells.dijit",
- "dojox.grid.enhanced._FocusManager",
- "dojox.grid.enhanced.plugins.CellMerge",
- "dojox.grid.enhanced.plugins.Cookie",
- "dojox.grid.enhanced.plugins.DnD",
- "dojox.grid.enhanced.plugins.Filter",
- "dojox.grid.enhanced.plugins.GridSource",
- "dojox.grid.enhanced.plugins.IndirectSelection",
- "dojox.grid.enhanced.plugins.Menu",
- "dojox.grid.enhanced.plugins.NestedSorting",
- "dojox.grid.enhanced.plugins.Pagination",
- "dojox.grid.enhanced.plugins.Printer",
- "dojox.grid.enhanced.plugins.Search",
- "dojox.grid.enhanced.plugins.Selector",
- "dojox.grid.enhanced.plugins.exporter.CSVWriter",
- "dojox.json.query",
- "dojox.layout.ContentPane",
- "dojox.widget.Standby",
- "com.ibm.tms.Loader",
- "tms.screens.TMSBase",
- "tms.screens.TMSScreen",
- "tms.screens.TMSTemplated",
- "tms.screens.TMSNewScreen",
- "tms.screens.notesHistory.notesHistory",
- "tms.screens.TMSTabContainer",
- "tms.common.tms",
- "com.ibm.tms.BorderContainer",
- "com.ibm.tms.ButtonSelector",
- "com.ibm.tms.Customizer",
- "com.ibm.tms.DropMultiSelect",
- "com.ibm.tms.TMSCheckedMultiSelect",
- "com.ibm.tms.TMSComboBox",
- "com.ibm.tms.TMSDropDownButton",
- "com.ibm.tms.TMSGrid",
- "com.ibm.tms.TMSGridPagination",
- "com.ibm.tms.TMSIconTooltip",
- "com.ibm.tms.TMSMessageBox",
- "com.ibm.tms.TMSTooltip",
- "com.ibm.tms.TmsSelect",
- "com.ibm.tms.form.CarrierRefTextBox",
- "com.ibm.tms.form.EmailTextBox",
- "com.ibm.tms.form.NumberTextBox",
- "com.ibm.tms.form.ValidationTextBox",
- "com.ibm.tms.form.ZipCodeTextBox",
- "com.ibm.tms.grid.Selection",
- "com.ibm.tms.grid._EditManager",
- "com.ibm.tms.grid._FocusManager",
- "com.ibm.tms.grid._RowManager",
- "com.ibm.tms.grid._RowSelector",
- "com.ibm.tms.grid.cells._base",
- "com.ibm.tms.grid.enhanced.plugins.Selector",
- "tms.screens.utils.ScreenUtils",
- "tms.screens.utils.TMSValidation"
- ]
- }
- ],
- prefixes: [
- [ "dijit", "../dijit" ],
- [ "dojox", "../dojox" ],
- [ "com.ibm.tms", "../com/ibm/tms" ],
- [ "tms.screens", "../../../tms/screens"],
- [ "tms.common", "../../../tms/js/common"]
- ]
- }
好了,准备就绪,开始优化
打包js
我们将打包js作为一个任务集成到ant中:build.xml
- <target name="compressJS">
- <echo message="Compress Javascript code..."/>
- <exec executable="java" dir="./webpages/tms/dojo/util/buildscripts"
- resolveexecutable="true" failonerror="false">
- <arg line="-classpath ../shrinksafe/js.jar;../shrinksafe/shrinksafe.jar org.mozilla.javascript.tools.shell.Main build.js action=clean,release cssOptimize=comments profile=TMS releaseName=release"/>
- </exec>
- </target>
BUILD SUCCESSFUL以后,在dojo下会生成一个release文件夹,将compressed目录下的tms.js文件和nls文件夹拷贝到根目录下,然后在初始页面中引用:
- <script src="nls/tms_en-us.js"></script>
注意,dojo.js还是得继续引用
打包css
css文件不能在profile中自定义,所以我们直接使用命令行的方式处理,build.xml:
- <target name="compressCSS">
- <echo message="Compress CSS ..."/>
- <exec executable="java" dir="${src}/webpages/tms/dojo/util/buildscripts"
- resolveexecutable="true" failonerror="false">
- <arg line="-classpath ../shrinksafe/js.jar${class_separatetoken}../shrinksafe/shrinksafe.jar org.mozilla.javascript.tools.shell.Main build_css.js"/>
- </exec>
- </target>
BUILD SUCCESSFUL以后,/css文件夹下有几个文件会变大(几十k或者一百多k),他们包含了所有你需要的css文件(打包原理就是所有被import的css文件全部被完全拷贝进来),我们只需要在页面中引用这几个css文件:
- <link type="text/css" href="css/dojoStyle.css" rel="stylesheet"/>
- <link type="text/css" href="css/tms.css" rel="stylesheet"/>
结束语
至此,打包的工作算是圆满结束。总结一下,我们利用dojo提供的工具来进行js/css文件的压缩,主要用到js.jar和shrinksafe.jar两个文件。打包原理是将所有引用的文件全部去掉注释后整体引用进来,变成一个大的文件,最后在页面中引用这些打包后的文件。
打包以后http请求数量减少了3/4左右。css的http请求只剩下两个,js的请求数有十几个,主要是_base下的js。
总算是解决这个问题了,Mark一下,实习第三周。