详解webpack性能优化——DLL


Posted in Javascript onOctober 20, 2017

Webpack性能优化的方式有很多种,本文之所以将 dll 单独讲解,是因为 dll 是一种最简单粗暴并且极其有效的优化方式。

在通常的打包过程中,你所引用的诸如:jquery、bootstrap、react、react-router、redux、antd、vue、vue-router、vuex 等等众多库也会被打包进 bundle 文件中。由于这些库的内容基本不会发生改变,每次打包加入它们无疑是一种巨大的性能浪费。

Dll 的技术就是在第一次时将所有引入的库打包成一个 dll.js 的文件,将自己编写的内容打包为 bundle.js 文件,这样之后的打包只用处理 bundle 部分。

以一个 Vue 项目为例,首先创建一个名为 webpack.dll.config.js 的文件

var path = require("path"),
fs = require('fs'),

webpack = require("webpack");

var vendors = [

'vue', 

'vue-router', 

'vuex'
];

module.exports = {

entry: {


vendor: vendors

},

output: {


path: path.join(__dirname, "dist"),


filename: "Dll.js",


library: "[name]_[hash]"

},

plugins: [


new webpack.DllPlugin({



path: path.join(__dirname, "dist", "manifest.json"),



name: "[name]_[hash]",



context: __dirname


})

]
};

这个文件的作用是将 vue、vue-router 以及 vuex 合并打包为一个名为 Dll.js 的静态资源包,同时生成一个 manifest.json 文件方便对 Dll.js 中的模块进行引用。

要注意的是,执行 webpack 命令是默认执行该目录下名为 webpack.config.js 或者 webpackfile.js 的文件。所以需要通过 --config 指令手动指定该文件,最后加入 -p 指令将 Dll.js 压缩。

$ webpack --config webpack.dll.config.js -p

这样,在项目根目录下就会多增加一个 dist 文件夹,其中有压缩之后的 Dll.js 与 manifest.json 文件。

manifest.json 文件内容如下,给各个模块赋予 id 以便引用。

{
 "name": "vendor_2beb750db72b1cda4321",
 "content": {
  "./node_modules/process/browser.js": {
   "id": 0,
   "meta": {}
  },
  "./node_modules/vue-router/dist/vue-router.esm.js": {
   "id": 1,
   "meta": {
    "harmonyModule": true
   },
   "exports": [
    "default"
   ]
  },
  "./node_modules/vue/dist/vue.runtime.esm.js": {
   "id": 2,
   "meta": {
    "harmonyModule": true
   },
   "exports": [
    "default"
   ]
  },
//.......

最后在 webpack.config.js 中添加引用。在 plugins 属性中添加 DllReferencePlugin 插件,并指明 manifest.json 文件的引用路径。

//...
plugins: [
  new webpack.DllReferencePlugin({
    context: __dirname,
    manifest: require('./dist/manifest.json')
  })
]

在确保成功执行 webpack.dll.config.js 文件后,执行 webpack -p 进行项目打包。

详解webpack性能优化——DLL

可以看到打包在 Dll 文件中的文件都被 delegated(委派) ,而不是直接打进 bundle 文件中。

这样我们就将所有的资源完成打包,生成的 dist 目录如下:

详解webpack性能优化——DLL

不过 dist 文件夹要想作为一个完整的工程还少一个 html 文件,我创建了一个名为 pack.js 的文件,使用 nodejs 的 fileSystem 对 html 文件进行修改并拷贝。

pack.js

var fs = require('fs');

fs.readFile('./index.html', 'utf8', (err, data) => {
  if (!err) {
    var dataStr = data.toString(),
    timestamp = (new Date()).getTime();
  
    dataStr = dataStr
          .replace('bundle.js', 'bundle.js?v='+timestamp)
          .replace('<!-- dll -->', '<script src="./dist/Dll.js?v='+ timestamp +'"></script>');

    fs.writeFile('./dist/index.html', dataStr, (error) => {
      if (!error) {
        console.log('HTML file copy successfully');
      } else {
        console.log(error);
      }
    });
  } else {
    console.log(err);
  }
});

我们需要在模块的入口 html 中添加 <!-- dll --> 的占位字符,pack.js 的作用就是将 html 文件拷贝一份到 dist 目录下,同时将 <!-- dll --> 替换为引用 Dll.js 的 script 标签,并在引用文件后添加时间戳。

<!-- .... -->
<body>
<div id="demo" class="container"></div>

<!-- dll -->
<script src="./bundle.js"></script>
</body>
</html>

在执行 webpack -p 打包后,输入下面命令运行 pack.js,就会在 dist 目录下生成 html 文件。

$ node pack.js

详解webpack性能优化——DLL

内容如下:

<!-- .... -->
<body>
<div id="demo" class="container"></div>

<script src="./dist/Dll.js?v=1488250309725"></script>
<script src="./bundle.js?v=1488250309725"></script>
</body>
</html>

这样 dist 文件夹就作为一个完整的、不需要任何手动操作、已经压缩混淆后的项目可以直接进行线上的部署。

实际项目模板参考地址如下。由于笔者作为 React 与 Vue 的双持开发者,所以创建了两个模板,以便之后通过 yomen(yo) 之类的进行脚手架工具化。

https://github.com/Darylxyx/generator-yx-react

https://github.com/Darylxyx/generator-yx-vue

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JQuery,Extjs,YUI,Prototype,Dojo 等JS框架的区别和应用场景简述
Apr 15 Javascript
jQuery 操作option的实现代码
Mar 03 Javascript
JavaScript Memoization 让函数也有记忆功能
Oct 27 Javascript
使用js检测浏览器是否支持html5中的video标签的方法
Mar 12 Javascript
jQuery实现指定内容滚动同时左侧或其它地方不滚动的方法
Aug 08 Javascript
在线引用最新jquery文件的实现方法
Aug 26 Javascript
JS实现快速的导航下拉菜单动画效果附源码下载
Nov 01 Javascript
将angular.js项目整合到.net mvc中的方法详解
Jun 29 Javascript
vue插件开发之使用pdf.js实现手机端在线预览pdf文档的方法
Jul 12 Javascript
24个ES6方法解决JS实际开发问题(小结)
May 31 Javascript
vue+element-ui表格封装tag标签使用插槽
Jun 18 Javascript
eslint+prettier统一代码风格的实现方法
Jul 22 Javascript
vue利用better-scroll实现轮播图与页面滚动详解
Oct 20 #Javascript
浅谈如何使用 webpack 优化资源
Oct 20 #Javascript
利用jQuery实现简单的拖曳效果实例代码
Oct 20 #jQuery
Js利用prototype自定义数组方法示例
Oct 20 #Javascript
js 中rewrap-ajax.js插件实例代码
Oct 20 #Javascript
jQuery访问浏览器本地存储cookie、localStorage和sessionStorage的基本用法
Oct 20 #jQuery
JS 中使用Promise 实现红绿灯实例代码(demo)
Oct 20 #Javascript
You might like
用PHP动态生成虚拟现实VRML网页
2006/10/09 PHP
解析func_num_args与func_get_args函数的使用
2013/06/24 PHP
php比较两个字符串长度的方法
2015/07/13 PHP
PHP生成制作验证码的简单实例
2016/06/12 PHP
仿百度的关键词匹配搜索示例
2013/09/25 Javascript
jquery插件jquery倒计时插件分享
2013/12/27 Javascript
JS数组去重与取重的示例代码
2014/01/24 Javascript
jquery使用jxl插件导出excel示例
2014/04/14 Javascript
整理Javascript基础语法学习笔记
2015/11/29 Javascript
Bootstrap组件(一)之菜单
2016/05/11 Javascript
PassWord输入框代码分享
2016/06/07 Javascript
Javascript Event(事件)的传播与冒泡
2017/01/23 Javascript
使用Node.js实现简易MVC框架的方法
2017/08/07 Javascript
javascript实现Emrips反质数枚举的示例代码
2017/12/06 Javascript
使用JQuery自动完成插件Auto Complete详解
2019/06/18 jQuery
详解Howler.js Web音频播放终极解决方案
2020/08/23 Javascript
浅谈JavaScript 声明提升
2020/09/14 Javascript
Vue路由权限控制解析
2020/11/09 Javascript
Linux RedHat下安装Python2.7开发环境
2017/05/20 Python
python3基于OpenCV实现证件照背景替换
2018/07/18 Python
Python+appium框架原生代码实现App自动化测试详解
2020/03/06 Python
Python 实现自动完成A4标签排版打印功能
2020/04/09 Python
利用Python实现某OA系统的自动定位功能
2020/05/27 Python
CSS3中currentColor关键字的妙用
2016/02/27 HTML / CSS
html5 乒乓球(碰撞检测)实例二
2013/07/25 HTML / CSS
全球领先的鞋类零售商:The Walking Company
2016/07/21 全球购物
微软英国官方网站:Microsoft英国
2016/10/15 全球购物
苏格兰销售女装、男装和童装的连锁店:M&Co
2018/03/16 全球购物
如何打造一封优秀的留学推荐信
2014/01/25 职场文书
国家助学金获奖感言
2014/01/31 职场文书
2014年党课学习材料
2014/05/11 职场文书
企业宣传策划方案
2014/05/29 职场文书
干部作风整顿自我剖析材料和整改措施
2014/09/18 职场文书
食品仓管员岗位职责
2015/04/01 职场文书
2015年宣传思想工作总结
2015/05/22 职场文书
学校扫黄打非工作总结
2015/10/15 职场文书