详解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 核心函数以及jQuery对象
Mar 23 Javascript
仿中关村在线首页弹出式广告插件(jQuery版)
May 03 Javascript
防止xss和sql注入:JS特殊字符过滤正则
Apr 18 Javascript
利用Keydown事件阻止用户输入实现代码
Mar 11 Javascript
前端必备神器 Snap.svg 弹动效果
Nov 10 Javascript
JS输入用户名自动显示邮箱后缀列表的方法
Jan 27 Javascript
详解用webpack2.0构建vue2.0超详细精简版
Apr 05 Javascript
Node.Js生成比特币地址代码解析
Apr 21 Javascript
JavaScript函数节流和函数去抖知识点学习
Jul 31 Javascript
JS使用正则表达式判断输入框失去焦点事件
Oct 16 Javascript
Vue学习之axios的使用方法实例分析
Jan 06 Javascript
解决vue的router组件component在import时不能使用变量问题
Jul 26 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中UNIX时间戳和日期间的转换与计算实例
2014/11/19 PHP
php打印输出棋盘的实现方法
2014/12/23 PHP
php统计数组元素个数的方法
2015/07/02 PHP
解读PHP中上传文件的处理问题
2016/05/29 PHP
JavaScript入门教程(9) Document文档对象
2009/01/31 Javascript
一个cssQuery对象 javascript脚本实现代码
2009/07/21 Javascript
document.getElementById的简写方式(获取id对象的简略写法)
2010/09/10 Javascript
JavaScript中“+”的陷阱深刻理解
2012/12/04 Javascript
上传文件返回的json数据会被提示下载问题解决方案
2014/12/03 Javascript
jQuery结合ajax实现动态加载文本内容
2015/05/19 Javascript
JavaScript图片轮播代码分享
2015/07/31 Javascript
JavaScript中boolean类型之三种情景实例代码
2016/11/21 Javascript
微信小程序实现实时圆形进度条的方法示例
2017/02/24 Javascript
JavaScript实现审核流程状态的动态显示进度条
2017/03/15 Javascript
Angular2+国际化方案(ngx-translate)的示例代码
2017/08/23 Javascript
JavaScript中重名的函数与对象示例详析
2017/09/28 Javascript
JS实现动态添加外部js、css到head标签的方法
2019/06/05 Javascript
NumPy排序的实现
2020/01/21 Python
使用PyWeChatSpy自动回复微信拍一拍功能的实现代码
2020/07/02 Python
python 爬取B站原视频的实例代码
2020/09/09 Python
python实现图像随机裁剪的示例代码
2020/12/10 Python
详解matplotlib中pyplot和面向对象两种绘图模式之间的关系
2021/01/22 Python
moosejaw旗下的户外商品促销网站:Mountain Steals
2017/02/27 全球购物
世界上获奖最多的手机镜头:Olloclip
2018/03/03 全球购物
美国购买新书和二手书网站:Better World Books
2018/10/31 全球购物
微软加拿大官方网站:Microsoft Canada
2019/04/28 全球购物
main 函数执行以前,还会执行什么代码
2013/04/17 面试题
生物技术专业毕业生求职信范文
2013/12/14 职场文书
共产党员公开承诺书范文
2014/03/28 职场文书
新春寄语大全
2014/04/09 职场文书
岗位说明书范文
2014/05/07 职场文书
青年志愿者活动方案
2014/08/17 职场文书
学习优秀共产党员先进事迹思想报告
2014/09/17 职场文书
起诉离婚协议书样本
2014/11/25 职场文书
2014年宣传部个人工作总结
2014/12/06 职场文书
运动会1000米加油稿
2015/07/21 职场文书