详解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 相关文章推荐
Javascript查询DBpedia小应用实例学习
Mar 07 Javascript
checkbox设置复选框的只读效果不让用户勾选
Aug 12 Javascript
JavaScript中for..in循环陷阱介绍
Nov 12 Javascript
使用百度地图api实现根据地址查询经纬度
Dec 11 Javascript
js实现百度联盟中一款不错的图片切换效果完整实例
Mar 04 Javascript
JavaScript中的return语句简单介绍
Dec 07 Javascript
Bootstrap源码解读下拉菜单(4)
Dec 23 Javascript
详解angularjs 关于ui-router分层使用
Jun 12 Javascript
Vue+Flask实现简单的登录验证跳转的示例代码
Jan 13 Javascript
JS面向对象之单选框实现
Jan 17 Javascript
小程序中的箭头函数的具体使用
Jun 19 Javascript
js实现炫酷光感效果
Sep 05 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中使用数组实现堆栈数据结构的代码
2012/02/05 PHP
php生成静态html页面的方法(2种方法)
2015/09/14 PHP
PHP操作MySQL的mysql_fetch_* 函数的常见用法教程
2015/12/25 PHP
详解Window7 下开发php扩展
2015/12/31 PHP
Thinkphp5.0自动生成模块及目录的方法详解
2017/04/17 PHP
PHP 中 var_export、print_r、var_dump 调试中的区别
2018/06/19 PHP
JavaScript 判断判断某个对象是Object还是一个Array
2010/01/28 Javascript
深入分析Cookie的安全性问题
2015/03/01 Javascript
javascript实现鼠标移到Image上方时显示文字效果的方法
2015/08/07 Javascript
详解JavaScript 中的 replace 方法
2016/01/01 Javascript
javascript中this指向详解
2016/04/23 Javascript
JQuery动态添加Select的Option元素实现方法
2016/08/29 Javascript
如何安装控制器JavaScript生成插件详解
2018/10/21 Javascript
vue-iview动态新增和删除的方法
2020/06/17 Javascript
Python采集腾讯新闻实例
2014/07/10 Python
小小聊天室Python代码实现
2016/08/17 Python
Python实现登录接口的示例代码
2017/07/21 Python
Python判断一个list中是否包含另一个list全部元素的方法分析
2018/12/24 Python
Python空间数据处理之GDAL读写遥感图像
2019/08/01 Python
python实现BP神经网络回归预测模型
2019/08/09 Python
详解pycharm连接不上mysql数据库的解决办法
2020/01/10 Python
Python类的动态绑定实现原理
2020/03/21 Python
哪种Python框架适合你?简单介绍几种主流Python框架
2020/08/04 Python
Lands’ End官网:经典的美国生活方式品牌
2016/08/14 全球购物
为智能设备设计个性化保护套网站:caseable
2017/01/05 全球购物
亚马逊意大利站点:Amazon.it
2020/12/31 全球购物
幼儿教师个人求职信范文
2013/09/21 职场文书
有多年工作经验的自我评价
2014/03/02 职场文书
幼儿园圣诞节活动总结
2015/05/06 职场文书
导游词之蓬莱长岛
2019/12/17 职场文书
nginx简单配置多个server的方法
2021/03/31 Servers
oracle DGMGRL ORA-16603报错的解决方法(DG Broker)
2021/04/06 Oracle
css 中多种边框的实现小窍门
2021/04/07 HTML / CSS
教你用Python爬取英雄联盟皮肤原画
2021/06/13 Python
C站最全Python标准库总结,你想要的都在这里
2021/07/03 Python
如何设置多台电脑共享打印机?多台电脑共享打印机的方法
2022/04/08 数码科技