详解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 图片上传预览-兼容标准
Jun 01 Javascript
模仿jQuery each函数的链式调用
Jul 22 Javascript
基于jQuery实现仿百度首页换肤背景图片切换代码
Aug 25 Javascript
vue引入jq插件的实例讲解
Sep 12 Javascript
Angular4实现图片上传预览路径不安全的问题解决
Dec 25 Javascript
js实现图片上传并预览功能
Aug 06 Javascript
微信小程序 MinUI组件库系列之badge徽章组件示例
Aug 20 Javascript
vue组件tabbar使用方法详解
Nov 06 Javascript
实例讲解vue源码架构
Jan 24 Javascript
node.JS的crypto加密模块使用方法详解(MD5,AES,Hmac,Diffie-Hellman加密)
Feb 06 Javascript
js实现文字头像的生成代码
Mar 07 Javascript
Vue实现背景更换颜色操作
Jul 17 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概述.
2006/10/09 PHP
用php+javascript实现二级级联菜单的制作
2008/05/06 PHP
php 显示指定路径下的图片
2009/10/29 PHP
php开启安全模式后禁用的函数集合
2011/06/26 PHP
如何使用php输出时间格式
2013/08/31 PHP
PHP新特性详解之命名空间、性状与生成器
2017/07/18 PHP
ThinkPHP框架中使用Memcached缓存数据的方法
2018/03/31 PHP
laravel框架邮箱认证实现方法详解
2019/11/22 PHP
一个不错的应用,用于提交获取文章内容,不推荐用
2007/03/03 Javascript
对 lightbox JS 图片控件进行了一下改造, 使其他支持复杂的图片说明
2010/03/20 Javascript
原生javascript兼容性测试实例
2013/07/01 Javascript
php,js,css字符串截取的办法集锦
2014/09/26 Javascript
jQuery实现文本框输入同步的方法
2015/06/20 Javascript
微信小程序 122100版本更新问题解决方案
2016/12/22 Javascript
基于Vue开发数字输入框组件
2017/12/19 Javascript
JS实现的将html转为pdf功能【基于浏览器端插件jsPDF】
2018/02/06 Javascript
vue2 前端搜索实现示例
2018/02/26 Javascript
vue插槽slot的理解和使用方法
2019/04/03 Javascript
如何在Vue中抽离接口配置文件
2019/10/31 Javascript
react-native聊天室|RN版聊天App仿微信实例|RN仿微信界面
2019/11/12 Javascript
[39:19]完美世界DOTA2联赛PWL S2 SZ vs LBZS 第二场 11.26
2020/11/30 DOTA
Python批量转换文件编码格式
2015/05/17 Python
Python中工作日类库Busines Holiday的介绍与使用
2017/07/06 Python
简单了解Python write writelines区别
2020/02/27 Python
超级实用的8个Python列表技巧
2020/08/24 Python
CSS3中几个新增加的盒模型属性使用教程
2016/03/01 HTML / CSS
Shopee马来西亚:随拍即卖,最佳行动电商拍卖平台
2017/06/05 全球购物
人事主管岗位职责范本
2013/12/04 职场文书
市场营销毕业求职信
2014/08/07 职场文书
学生会竞选演讲稿纪检部
2014/08/25 职场文书
党支部创先争优承诺书
2014/08/30 职场文书
环境工程专业毕业生求职信
2014/09/30 职场文书
雾霾停课通知
2015/04/24 职场文书
《家世》读后感:看家训的力量
2019/12/30 职场文书
python flask开发的简单基金查询工具
2021/06/02 Python
Redis特殊数据类型Geospatial地理空间
2022/06/01 Redis