CommonsChunkPlugin并不是分离第三方库的好办法(DllPlugin科学利用浏览器缓存)
webpack算是个磨人的小妖精了。之前一直站在glup阵营,使用browserify打包,发现webpack已经火到爆炸,深怕被社区遗落,赶紧拿起来把玩一下。本来只想玩一下的。尝试打包了以后,就想启个webpack服务器,之后就想添加热替换,什么css文件单独拆分,各种 loader 处理优化打包结果,各种 source-map 有什么不同,一个都不能少。其中添加热替换时候,因为应用的服务器和webpack服务器没有使用同一个,产生了一点波折。然后就到了今天这个主题了。
逐步展开今天的主题:
为什么要分离第三方库?
这个好处显而易见,第三方库是比较稳定的,不会轻易改变,利用浏览器缓存后,用户再次加载页面会减少服务器请求,提高速度优化体验。提取多个应用(入口)公共模块的作用和他类似,公共部分会被缓存,所有应用都可以利用缓存内容从而提高性能。
分离第三方库就能利用浏览器换缓存了么?
同样显而易见是否定的,导致无法利用缓存的因素有很多,比如最明显的有可能你每次分离的库文件重新打包都会得到不同的名称,这个比较容易发现,再比如说后台的同事给js文件设置的缓存过期时间为0,这就尴尬了,但0就不能利用缓存了么?并不是,只要文件是完全不变的,注意是完全不变,包括修改时间,依然会利用缓存,性能飞起。想利用缓存必须先了解缓存,这里简单提一下:
浏览器缓存机制是什么样的?
HTTP1.1给的策略是使用Cache-control配合Etag,
Cache-control设置举例:
'Cache-Control': 'public, max-age=600',
max-age即过期时间,如果已过期的话,还会查看Etag,
ETag的值:
Apache中,ETag的值默认是对文件的索引节(INode),大小(Size)和最后修改时间(MTime)进行Hash后得到的。
如果Etag相同,依然不会请求新资源,而会使用以前的文件。
CommonsChunkPlugin 到底是用来干什么的?
字面理解,提取公共包,公共包那就是不只一个地方使用喽,单页应用(单入口)的库只有他自己使用,不能算公共包吧?这个插件提取的公共包,每次是会重新打包的(Etag会不同),无论是节约打包时间,(虽然微不足道的时间但毕竟是无用功:库根本没变么),还是对浏览器缓存的利用(万一 max-age 过期了你就放弃缓存了么?)都不是好的方案。最佳方案浮出水面:DllPlugin
DllPlugin有什么优势?
只对库文件打包一次。也就是说,只要库文件不变,只需要打包一次,以后再打包业务代码和库文件没关系啦,这样一来真正做到了库文件永远是那个库文件,只要库文件不变,缓存永远有效(Etag不变),打起包来把库丢到脑后,神清气爽。介绍一下最简单的使用方式:
首先另写一个 webpack 配置文件,毕竟是单独打包库了,假设 webpack.config.dll.js
const path = require('path')
const webpack = require('webpack');
module.exports = {
entry: {
vendor: ['react', 'react-dom', 'react-hot-loader', 'immutable', 'redux', 'react-redux', 'react-router-dom', 'redux-logger',
'redux-persist', 'redux-persist-transform-immutable', 'redux-thunk'],
},
output: {
filename: 'js/[name].js',
path: path.resolve(__dirname, 'public'),
library: '[name]', // 当前Dll的所有内容都会存放在这个参数指定变量名的一个全局变量下,注意与DllPlugin的name参数保持一致
},
plugins: [
new webpack.DllPlugin({
path: path.resolve(__dirname, 'public/manifest.json'), // 本Dll文件中各模块的索引,供DllReferencePlugin读取使用
name: '[name]',
}),
],
}
在原来的配置文件中添加 DllReferencePlugin 插件
new webpack.DllReferencePlugin({
manifest: require('./public/manifest.json'), // 指定manifest.json
name: 'vendor', // 当前Dll的所有内容都会存放在这个参数指定变量名的一个全局变量下,注意与DllPlugin的name参数保持一致
}),
终端先运行:
webpack -p --progress --config ./webpack.config.dll.js
把库文件先打个包,只要库不变,以后就用这个包了,再打包业务代码,完活。
推荐策略:
各行其是。
如果是单页应用,那只用DllPlugin打包库文件即可,业务代码一个包搞定。
如果是多页应用,DllPlugin打包完库文件,开发时可能会用很多公共的业务代码而且可能随时变动,这就要利用CommonsChunkPlugin来做他本该做的事,再把公共业务提取出来,至于缓存,起码在页面间切换时,公共部分还是会被缓存的。
CommonsChunkPlugin并不是分离第三方库的好办法(DllPlugin科学利用浏览器缓存)的更多相关文章
- webpack分离第三方库(CommonsChunkPlugin并不是分离第三方库的好办法DllPlugin科学利用浏览器缓存)
webpack算是个磨人的小妖精了.之前一直站在glup阵营,使用browserify打包,发现webpack已经火到爆炸,深怕被社区遗落,赶紧拿起来把玩一下.本来只想玩一下的.尝试打包了以后,就想启 ...
- pycharm每次新建项目都要重新安装一些第三方库的解决办法(转载防删)
目前有三个解决办法,也是亲测有用的: 第一个方法:因为之前有通过pycharm的project interpreter里的+号添加过一些库,但添加的库只是指定的项目用的,如果想要用,就必须用之前的项目 ...
- pycharm安装第三方库失败解决办法
一.报错信息:[file][Default Settint]---Project Interpreter 点击 搜索suds安装模块报错 解决:依据上图提示找到C:\Program Files\Jet ...
- cocoapods导入第三方库后,xcode上import不提示,找不到第三方库的解决办法
选择你的工程tagets, -> Build Settings -> Search Paths -> User Header Search Paths 双击User Header S ...
- webpack 的第三方库分离并持久化缓存
我们常常需要在浏览器缓存一些稳定的资源,如第三方库等.要达到这个目标,只需要两步: 1.提取出“稳定的资源”: 2.提供稳定的文件hash . 处理后的出的文件就像这样子: app.1w3ad4q4. ...
- Python 标准库、第三方库
Python 标准库.第三方库 Python数据工具箱涵盖从数据源到数据可视化的完整流程中涉及到的常用库.函数和外部工具.其中既有Python内置函数和标准库,又有第三方库和工具.这些库可用于文件读写 ...
- 运用NodeJs环境并依赖第三方库,框架等实现网站前后端分离报错问题及处理方法
运用NodeJs环境并依赖第三方库,框架等实现网站前后端分离报错问题及处理方法 问题一: SyntaxError: missing ) after argument list in .....\vie ...
- iOS程序开发引用的第三方库之间出现duplicate symbol时的处理方法
iOS程序集成的第三方库过多时,很容易出现某几个库同时用到了一样的函数库,也就是在你的程序link时会提示duplicate symbol,而重复的符号又不是由你自己程序的代码造成的,也就说没法通过直 ...
- iOS开发常用第三方库
UI 动画 网络相关 Model 其他 数据库 缓存处理 PDF 图像浏览及处理 摄像照相视频音频处理 响应式框架 消息相关 版本新API的Demo 代码安全与密码 测试及调试 AppleWatch ...
随机推荐
- HDU 5556 最大独立集
这题主要有了中间的一些连通块的限制,不太好直接用二分图最大独立集做.考虑到图比较小,可以作补图求最大团来求解. #include <iostream> #include <vecto ...
- 2017河工大校赛补题CGH and 赛后小结
网页设计课上实在无聊,便开始补题,发现比赛时候僵着的东西突然相通了不少 首先,"追妹"这题,两个队友讨论半天,分好多种情况最后放弃(可是我连题目都没看啊),今天看了之后试试是不是直 ...
- bzoj4817 [Sdoi2017]树点涂色
Description Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路 径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色. ...
- 实现图片的循环滚动——JS的简单应用
首先默认都了解JS的循环分支运算符等基本语法 用CSS实现简单的布局也是会的. 然后我们就可以来了解一下 [DOM 树节点] 它分为三大类:元素节点.文本节点.属性节点 文本节点跟属性节点为元素节点的 ...
- seajs模块标识命名和解析规则
模块标识采用路径形式,但要注意与路径的区别.require.require.async的第一个参数是模块标识.而seajs.use第一个参数为文件路径. use是全局的,require是局部的.模块标 ...
- Spring框架基础知识
本人博客文章网址:https://www.peretang.com/basic-knowledge-of-spring-framework/ Spring框架简介 Spring , 一个开源的框架 , ...
- Redis学习-Set
在Redis中,Set类型是没有排序的字符集合,和List类型一样,可以在该类型的数据值上执行添加.删除或判断某一元素是否存在等操作.需要说明的是,这些操作的时间复杂度为O(1),即常量时间内完成次操 ...
- Kafka学习-复制
复制 Kafka可以通过可配置的服务器数量复制每个主题分区的日志(可以为每个主题设置复制因子).这允许在集群中的服务器发生故障时自动故障转移到其他副本,因此在存在故障的情况下,消息仍然可用. 其他消息 ...
- Java内存模型四
volatile的特性 当我们声明共享变量为volatile后,对这个变量的读/写将会很特别.理解volatile特性的一个好方法是:把对volatile变量的单个读/写,看成是使用同一个锁对这些单个 ...
- AngularJS操作DOM——angular.element
addClass()-为每个匹配的元素添加指定的样式类名 after()-在匹配元素集合中的每个元素后面插入参数所指定的内容,作为其兄弟节点 append()-在每个匹配元素里面的末尾处插入参数内容a ...