详解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 URL编码和解码使用说明
Apr 12 Javascript
jquery+ashx无刷新GridView数据显示插件(实现分页、排序、过滤功能)
Apr 25 Javascript
js实现从右向左缓缓浮出网页浮动层广告的方法
May 09 Javascript
JavaScript中数组的合并以及排序实现示例
Oct 24 Javascript
JS使用post提交的两种方式
Dec 03 Javascript
js实现商品抛物线加入购物车特效
Nov 18 Javascript
Vue.js学习笔记之常用模板语法详解
Jul 25 Javascript
使用vue-cli+webpack搭建vue开发环境的方法
Dec 22 Javascript
微信小程序仿美团城市选择
Jun 06 Javascript
小程序获取周围IBeacon设备的方法
Oct 31 Javascript
Vue源码解析之数据响应系统的使用
Apr 24 Javascript
vue登录页面cookie的使用及页面跳转代码
Jul 10 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
使用 eAccelerator加速PHP代码的目的
2007/03/16 PHP
php多进程模拟并发事务产生的问题小结
2018/12/07 PHP
PHP数据源架构模式之表入口模式实例分析
2020/01/23 PHP
使用js写的一个简易的投票
2013/11/27 Javascript
jQuery实现感应鼠标动画效果自动伸长的输入框实例
2015/02/24 Javascript
Javascript中For In语句用法实例
2015/05/14 Javascript
js中获取时间new Date()的全面介绍
2016/06/20 Javascript
jQuery实现的导航下拉菜单效果
2016/07/04 Javascript
微信小程序 WXML、WXSS 和JS介绍及详解
2016/10/08 Javascript
利用JavaScript实现拖拽改变元素大小
2016/12/14 Javascript
vue双向绑定的简单实现
2016/12/22 Javascript
AngularJS学习第二篇 AngularJS依赖注入
2017/02/13 Javascript
通过npm引用的vue组件使用详解
2017/03/02 Javascript
Node.js微信 access_token ( jsapi_ticket ) 存取与刷新的示例
2017/09/30 Javascript
nodejs搭建本地服务器轻松解决跨域问题
2018/03/21 NodeJs
Vue.js获取被选择的option的value和text值方法
2018/08/24 Javascript
优雅的elementUI table单元格可编辑实现方法详解
2018/12/23 Javascript
jQuery事件多次绑定与解绑问题实例分析
2019/02/19 jQuery
jQuery轮播图功能制作方法详解
2019/12/03 jQuery
vue-以文件流-blob-的形式-下载-导出文件操作
2020/08/07 Javascript
详解vue中使用transition和animation的实例代码
2020/12/12 Vue.js
nodejs中使用worker_threads来创建新的线程的方法
2021/01/22 NodeJs
python基于BeautifulSoup实现抓取网页指定内容的方法
2015/07/09 Python
在Pycharm terminal中字体大小设置的方法
2019/01/16 Python
详解Python中is和==的区别
2019/03/21 Python
Python csv模块使用方法代码实例
2019/08/29 Python
python飞机大战pygame碰撞检测实现方法分析
2019/12/17 Python
瑞典最好的运动鞋专卖店:Sneakersnstuff
2016/08/29 全球购物
Lancer Skincare官方网站:抗衰老皮肤护理
2020/11/20 全球购物
高级Java程序员面试题
2016/06/23 面试题
英语教学随笔感言
2014/02/20 职场文书
生物制药专业求职信
2014/03/11 职场文书
工作求职自荐信
2014/06/13 职场文书
党员批评与自我批评发言材料
2014/10/14 职场文书
浅谈Golang 切片(slice)扩容机制的原理
2021/06/09 Golang
利用 JavaScript 构建命令行应用
2021/11/17 Javascript