前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >webpack实战——打包优化【中】

webpack实战——打包优化【中】

作者头像
流眸
发布于 2020-11-06 02:25:53
发布于 2020-11-06 02:25:53
91200
代码可运行
举报
运行总次数:0
代码可运行

前言

上篇从多线程打包缩小打包作用域两个方面入手,对webpack打包层面做出优化。本篇描述从动态链接库思想方面继续深入探究打包层面的深度优化。

动态链接库与DLLPlugin

“动态链接库(Dynamic Link Library 或者 Dynamic-link Library,缩写为 DLL),是微软公司在微软Windows操作系统中,实现共享函数库概念的一种方式。这些库函数的扩展名是 ”.dll"、".ocx"(包含ActiveX控制的库)或者 ".drv"(旧式的系统驱动程序)。

当一段相同的子程序被多个程序调用时,为了减少内存消耗,可以将这段子程序存储为一个可执行文件,当被多个程序调用时只在内存中生成和使用同一个实例。

今天要介绍的主角“DLLPlugin”则借鉴了动态链接库的思路,对于第三方模块或者一些不常变化的模块预先进行编译和打包,然后再项目实际构建过程中直接取用。不过区别还是有的,DLLPlugin实际生成的文件是JS文件而不是动态链接库。在打包vendor的时候还会附加生成一份vendor的模块清单,这份清单将会在工程业务模块打包时起到链接和索引的作用。

1 vendor配置

首先需要为动态链接库单独创建一个Webpack配置文件,例如:webpack.vendor.config.js,注意要与webpack.config.js区分开来。

例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// webpack.vendor.config.js
const path = require('path');
const webpack = require('webpack');
const dllAssetPath = path.join(__dirname, 'dll');
const dllLibraryName = 'dllExample';

module.exports = {
    entry: ['react'],
    output: {
        path: dllAssetPath,
        filename: 'vendor.js',
        library: dllLibraryName
    },
    plugins: [
        new webpack.DllPlugin({
            name: dllLibraryName,
            path: path.join(dllAssetPath, 'manifest.json')
        })
    ]
}

其中,entry指定了将哪些模块打包为vendor,plugins的部分引入了DLLPlugin,并有如下配置:

  • name: 导出的dll library的名字,需要与output.library的值对应;
  • path: 资源清单的绝对路径,业务打包时将会使用这个清单进行模块索引;

2 vendor打包

接下来就要打包vendor并且生成资源清单。为后续方便操作,可以在package.json中配置一条运行指令:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// pachage.json
{
    ...
    "scripts": {
        ...
        "dll": "webpack --config webpack.vendor.config.js"
    }
}

然后执行npm run dll,会发现生成了一个dll目录,里面对应有两个文件:

  • vendor.js:库的代码
  • manifest.json:资源清单

感兴趣的可以打开这两个文件阅读一下。

3 链接到业务代码

试过之后,我们就要考虑将vendor链接到项目中去了。这里推荐与DLLPlugin配套的插件“DLLReferencePlugin”,它起到索引和链接作用。在工程的webpack配置文件中(注意是webpack.config.js,不是vendor的配置文件),通过DLLReferencePlugin来获取刚才打包好的资源清单,然后在页面中添加vendor.js就可以引用。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// webpack.cinfig.js
const path = require('path');
const webpack = require('webpack');
module.exports = {
    ...
    plugins: [
        new webpack.DllReferencePlugin({
            manifest: require(path.join(__dirname, 'dll/manifest.json')
        })
    ]
}

那么 index.html 引入会即可:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
...

<body>
...

<script src="dll/vendor.js"></script>
<script src="dist/app.js"></script>
</body>

设置完毕后,当页面执行到vendor.js时,会声明全局变量dllExample,而manifest相当于注入app.js的资源地图,app.js会通过name字段找到名为DLLExample的library,再进一步获取其内部模块。

4 潜在问题

细心的小伙伴或许已经发现了,在当前配置中会存在一个问题:当打开manifest.json文件后,可以发现每个模块都会有一个id,其值是按照数字顺序递增的,而业务代码在引用vendor中模块时也是引用这个数字id,当我们更vendor时这个数字id也会随之发生改变。

现假设我们工程目录中有如下资源文件,并每个资源都加上了chunk hash:

  • vendor@[hasn].js
  • pageUser@[hasn].js
  • pageIndex@[hasn].js
  • util@[hasn].js

现在vendor中you一些模块,例如包含了react,其id为5.当尝试添加更多模块到vendor中的时候,那么重新进行Dll构建时,moment.js可能出现在react之前,此时react的id会变为6.而pageUser和pageIndex是通过id进行引用的,因此他们的文件内容也发生了改变。此时我们会面临如下情况:

  1. 两个页面的chunk hash均发生了改变。这是我们不希望看到的,因为他们本身并无变化,但是vendor的改变却驱使用户不得不重新下载所有资源。
  2. 两个页面chunk hash没有改变,但是这种情况更为糟糕:vendor中的模块id改变了,但是用户没有更新缓存,使用的还是旧版本的内容,而引用不到新的vendor模块,导致页面发生错误。并且对于开发者而言,这个错误却难以排查,因为开发环境下一切正常!

针对上述的问题2,解决方法是在打包vendor时添加上HashedModuleIdsPlugin,如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// webpack.vendor.config.js
module.exports = {
    ...
    plugins: [
        new webpack.DllPlugin({
            name: dllLibraryName,
            path: path.join(dllAssetPath, 'manifest.json')
        }),
        // 添加HashedModuleIdsPlugin
        new webpack.HashedModuleIdsPlugin();
    ]
}

“HashedModuleIdsPlugin是webpack3中被引入进来的,主要就是为了解决数字id的问题。HashedModuleIdsPlugin可以把id的生成算法修改为根据模块的引用路径生成一个字符串hash。

注:从webpack3开始,模块id不仅可以是数字,也可以是字符串。

小结

本篇从动态链接库思想着手,介绍了DLLPlugin与其配套插件DLLReferencePlugin使用,将第三方库与一些不常改动的模块编译打包,处理为类似于动态链接库的JS文件,以此来节约服务器资源。下一篇介绍打包优化最后一个环节:死代码检测与去除。

往期推荐

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-10-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 流眸 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
Power BI数据+工作计划推送到手机
现在依据数据好坏为门店制定下一步工作计划。例如,点击宁波市江南路这一行,弹出对话框:
wujunmin
2025/04/30
550
Power BI数据+工作计划推送到手机
霓虹灯数字时钟(可复制源代码)
我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=3c0nu17s7yck8
半夜喝可乐
2024/09/30
860
霓虹灯数字时钟(可复制源代码)
Power BI SVG、HTML、Deneb圆角条形图对比
wujunmin
2025/05/04
780
Power BI SVG、HTML、Deneb圆角条形图对比
销售排行榜这么做:Power BI绝对值和占比组合图
偶然间在网上看到一个研发费用图表,同时显示了各大公司的研发花费以及研发费用占营收的比例。个人认为这个图表非常实用,可以广泛应用于零售业各环节。比如,店铺销售排行榜和对公司的整体业绩贡献,产品销售排行榜和毛利贡献……
wujunmin
2022/05/19
1.5K0
销售排行榜这么做:Power BI绝对值和占比组合图
Power BI 卡片图平滑轮播
这里使用DAX+HTML实现,轮播原理为CSS动画,假设展示三个指标,度量值如下:
wujunmin
2025/04/29
610
Power BI 卡片图平滑轮播
Power BI 图表空心化
本公众号已经分享了超过百种DAX+SVG自定义的图表,本文介绍如何将自定义图表空心化。所谓空心图表是指没有填充颜色,仅有边框颜色的图表。下图展示了条形图的空心效果:
wujunmin
2022/12/13
1.1K0
Power BI 图表空心化
Power BI表格高级交互:分页浏览
当行数较多时,Power BI内置表格只能滚动条向下浏览。借助HTML,我们可以实现分页浏览。下图右下角显示了页码,点击任意数字即可跳转:
wujunmin
2025/04/02
700
Power BI表格高级交互:分页浏览
Power BI 标签倾斜式卡片图
主流的卡片图标签横平竖直,视觉疲劳。借助SVG,我们可以使用DAX绘制图表,轻松实现倾斜样式的卡片图,下图的左侧和右侧对城市标签进行了倾斜:
wujunmin
2025/02/10
960
Power BI 标签倾斜式卡片图
Power BI原生图表自定义填充图案
以上所有效果不依赖任何第三方视觉对象,完全使用Power BI内置图表生成,交互功能一个不少(比如工具提示),数据标签,条件格式也完全支持。这是怎么办到的?
wujunmin
2022/12/13
1.1K0
Power BI原生图表自定义填充图案
股市震荡,Power BI这么展示
图表中的卡片和柱形图都很常规,最下方的百分比堆积条形图有点特色。Power BI使用DAX可以轻松模拟,以下是我模拟的四种样式:
wujunmin
2025/04/09
860
股市震荡,Power BI这么展示
Power BI 模拟网易居中条形图
在网易数读看到一个条形图,如下图右侧所示,特点有:类别标签居中,条形居中,带有背景阴影,条形和阴影均为圆角。
wujunmin
2022/12/13
5500
Power BI 模拟网易居中条形图
Power BI同期对比这么看
同期对比常规状态下可以使用簇状条形图/柱形图,以下是Power BI内置图表的效果。
wujunmin
2022/05/19
1.6K0
Power BI同期对比这么看
Power BI 模拟VisActor子弹进度图
之前介绍过VisActor可视化库,本文开始第一个模仿:子弹图,效果如下图所示,条形为实际值,红色的图标像一个图钉,为目标值:
wujunmin
2024/01/24
2350
Power BI 模拟VisActor子弹进度图
Power BI 豪华动态业绩杜邦分析
杜邦分析法(DuPont analysis)是一种分析企业财务状况的方法,得名于美国杜邦公司。该思路可以应用于销售业绩分析。如下图模拟杜邦分析图对门店零售业务的业绩进行分解(参考:黄成明老师的《数据化管理》)
wujunmin
2025/03/18
1070
Power BI 豪华动态业绩杜邦分析
Power BI 一行度量值绘制条形图
我这两年一直鼓吹DAX驱动可视化,有些人觉得实施有点繁琐,那么今天请大家欣赏一个简单到极致的作品:一行度量值绘制条形图。
wujunmin
2025/02/10
700
Power BI 一行度量值绘制条形图
Power BI两两对比这样做
源自知识星球星友遇到的一个对比问题,本文使用一个度量值实现元素间两两对比,主要用来和优秀对标。示例是零售店铺之间的差异。
wujunmin
2022/07/13
1.3K0
Power BI两两对比这样做
Power BI图表虚线化
上一节讲了如何将图表空心化(Power BI 图表空心化),本节继续这个话题,将图表虚线化。虚线化,顾名思义,就是把图表的线条改为虚线。下图是气泡条件格式虚线后的样子:
wujunmin
2022/12/13
2K0
Power BI图表虚线化
Power BI 表格矩阵椭圆突出重点数据
Power BI表格效果如下图所示,将特别好或者特别差的数据使用椭圆框选出来。如何实现?
wujunmin
2022/12/13
4930
Power BI 表格矩阵椭圆突出重点数据
Power BI多指标排名寻找业绩机会点
一个店铺的一个指标数值通常没有价值,价值在比较中产生。我们常常通过指标排名来发现店铺优劣势。在表格中,一个指标一列,10个指标则新建10列进行排名。
wujunmin
2021/09/07
4760
Power BI模拟麦肯锡哑铃图表现差异
麦肯锡McKinsey Insights APP展示了一种直观表现差异的哑铃图,如下图所示。
wujunmin
2022/12/13
4810
Power BI模拟麦肯锡哑铃图表现差异
相关推荐
Power BI数据+工作计划推送到手机
更多 >
LV.1
这个人很懒,什么都没有留下~
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档