1.背景

在开发过程中,发现首屏加载过慢导致用户体验不佳,因此boss一声令下,需要可怜唯唯诺诺的前端来进行优化。
在优化过程中可谓是踩坑无数,百思不得其解,到最后发现是不过如此。但是网上一篇完整的叙述都很少,经常是使用webpack的例子和讲解(文档有用还要看文章干嘛?)因此想要写篇博文来记录一下自己的一些实践。

2.优化手段

在webpack中有关于代码分离的文档介绍
总的来说webpack是可以帮助我们做到资源的去重和分离,去重就是将重复的引用减少,分离将不同的资源包分离在不同的包内

3.SplitChunksPlugin

我们很快地找到这个插件和配置,应该才是webpack帮助代码分离的关键
其默认配置为

module.exports = {//...optimization: {splitChunks: {chunks: 'async',minSize: 20000,minRemainingSize: 0,minChunks: 1,maxAsyncRequests: 30,maxInitialRequests: 30,enforceSizeThreshold: 50000,cacheGroups: {defaultVendors: {test: /[\\/]node_modules[\\/]/,priority: -10,reuseExistingChunk: true,},default: {minChunks: 2,priority: -20,reuseExistingChunk: true,},},},},
};

通过默认配置我们可以看到我们分了两个包,cacheGroup和default,可是在实践中分离的包呢?
别急!其实主要是在chunks中已经有其设置,关键字为"async",该关键字是说明只有代码为主包未立即引入的第三方依赖,才会进入到此cacheGruop中来。所以添加chunks:“initial”

 defaultVendors: {test: /[\\/]node_modules[\\/]/,priority: -10,chunks: 'initial',reuseExistingChunk: true,
},

就可以看到在首屏加载的时候,我们的defaultVendors 包出现了!

4.第三方依赖动态加载(懒加载)

那么如何将我们的第三方插件在需要的时候才加载呢,这个时候就需要用到我们的动态加载了,在webpack中也有过js动态加载的描述,主要是通过ECMAScript 提案 的 import() 语法 或require.ensure来实现
不过三大框架均有自己推荐的动态导入方案:
React: Code Splitting and Lazy Loading
Vue: Dynamic Imports in Vue.js for better performance
Angular: Lazy Loading route configuration and AngularJS + webpack = lazyLoad

因此只要通过推荐的方案进行动态导入,(一般而言针对单页面spa网站,将路由懒加载就可以将大多数首屏不需要的第三方依赖抽离出来)
设置好引入后,那么我们的第三方依赖就成功从主程序中抽离出来啦~

5.继续分包

然而很多时候,一股脑将第三方包在某一路由加载时,异步地将一个包加载进入程序中,也不是一个很好的选择,
配置优化,一般而言这个时候就需要用到webpack打包分析的插件webpack-bundle-analyzer,通过插件可以分析出你的bundle,一般而言将某些大库分成不同的包就可以了
这里附上将monaco,echarts,xlsx分离的示例:

module.exports = {//...optimization: {//...cacheGroups: {//...monaco: {test: /[\\/]monaco-editor[\\/]/,name: 'monaco',reuseExistingChunk: true},echarts: {test: /[\\/](echarts-for-react|echarts|zrender)[\\/]/,name: 'echarts',reuseExistingChunk: true,},xlsx: {test: /[\\/]xlsx[\\/]/,name: 'xlsx',reuseExistingChunk: true,}}}
},

这样就将某些大库分成小小包,在将在特定路由的时候加载小小包就可以了。

附1:编译问题

在项目实践中发现动态引入一直无效,没有被webpack的splitChunks识别为动态的引入。可以从ts编译babel编译入手
这里将ts的"module":改写成"esnext"才可以被识别动态导入,附上我们的配置

{"compilerOptions": {"experimentalDecorators": true,"target": "es5","lib": ["es5", "es6", "dom"],"jsx": "react","module": "esnext","allowSyntheticDefaultImports": true,"skipLibCheck": true,"resolveJsonModule": true,"moduleResolution": "node","baseUrl": "./","downlevelIteration": true,"paths": {"@/*": ["src/*"]}},"include": ["src/**/*.ts", "src/**/*.tsx"],"exclude": ["node_modules"]
}

附2:继续优化

没有最好只有更好,虽然我们成功地将代码分离了,如果你觉得还是很慢,我还想再快怎么办,目前我可以看到的是还有这些点可以优化:
1.可以将不必要的引入去除(按需引入),将第三方库通过es语法import { }按需引入而不是import * 这种形式(发现内部库没有做到按需引入的可以自己尝试去做)
2.路由使用模块,尽量将公共组件放在一起,将路由和路由使用的库放在一个模块中,这样在加载某一路由的时候不会因为使用到了另一个路由的代码而将另一个路由同时加载出来(ps:使用了react的我竟然有些怀念Angular?)
3.首屏使用ssr渲染

一看就会的webpack的代码分离(分包)优化首屏加载实践相关推荐

  1. webpack优化系列七:首屏加载优化

    前端项目打包之后默认情况下的配置文件较大,部署后首次加载反应较慢,甚至会出现几秒白屏的现象,对于用户的体验感不是很好,所以需要进一步优化一下: 本文主要记录一下本人自己的理解,如果其他方案可评论指导. ...

  2. miniblink载入html,(转)miniblink跨线程异步JS回调,及miniblink提升首屏加载速度的代码...

    转自:aardio培训群 , 感谢 Jacen He 校长提供代码 miniblink 不能回调JS确实非常麻烦, 因为用web做界面,很自然的会调用耗时操作,不能回调逻辑会变的很复杂. 针对这个aa ...

  3. 使用Webpack的代码分离实现Vue懒加载(译文)

    当一个Vue的项目体积变得十分庞大的时候,使用Webpack的代码分离功能将Vue Components,routes或Vuex的代码进行分离并按需加载,会极大的提高App的首屏加载速度. 在Vue的 ...

  4. Webpack系列——代码分离(Code Splitting)

    代码分离(Code Splitting) // index.js import _ from 'lodash'; const ele = document.createElement('div'); ...

  5. Code Splitting代码分包(路由懒加载)

    code split代码分包(路由懒加载) 前言,​在应用打包结果过大时,按照设置的规则打包到不同的bundle中,提高应用响应速度.也就是当一个页面进行加载的时候如果太慢,那么你就可以考虑对工程进行 ...

  6. Android4.0图库Gallery2代码分析(二) 数据管理和数据加载

    Android4.0图库Gallery2代码分析(二) 数据管理和数据加载 2012-09-07 11:19 8152人阅读 评论(12) 收藏 举报 代码分析android相册优化工作 Androi ...

  7. 一行代码实现全站pjax无刷新加载

    之前也没有研究过pjax,但是没事走访别人博客时看到不少经过pjax的网站,响应速度很快,今天一篇<一行代码实现全站pjax无刷新加载>测试后发发现效果确实不错,但是由于我是老的媒体范板子 ...

  8. html引用单文件组件,webpack入坑之旅(五)加载vue单文件组件_html/css_WEB-ITnose

    需要什么? 在经过前面的四个练习,相信已经对于 webapck有了一定的了解,现在我们就来一个综合案例,进一步甲申年对于 webpack的理解. 首先我们应该思考要解析 .vue类型的文件,需要什么样 ...

  9. 百度联盟广告代码php,Javascript 实现广告后加载 可加载百度谷歌联盟广告[原创]_javascript技巧...

    本文主要介绍一种新的广告后加载的方式,支持自定义HTML广告.百度联盟广告和谷歌联盟广告.这种方式在页面加载完成后执行,不影响内容的显示,对用户更加友好. 我们在网站上放置广告,最简单的方法就是把JS ...

最新文章

  1. spring定时每天早上八点_Spring Boot教程(13) – 简单定时任务
  2. 全美第二的机器人项目核心数学课免费开放,院长亲自授课,作业讲义全同步...
  3. mysql范围条件_MySQL 索引及优化实战(一)
  4. 全球及中国便携式卧式空压机行业前景动态与投资趋势分析报告2022版
  5. html写三角形,css3怎么写三角形?
  6. python 倒计时_Excel制作竞答倒计时器
  7. VTK:可视化算法之FindCellIntersections
  8. sama5d3 环境检测 gpio--yk测试
  9. STM32通用定时器输出PWM
  10. 两个前置摄像头_W21 5G性能篇 | 五摄像头组合,洞悉画面之美
  11. 基于vue.js的dialog插件art-dialog-vue2.0发布
  12. C++基础知识(四)文件的基本操作
  13. MVC中单选按钮的实现
  14. 哈夫曼编码的理解(Huffman Coding)
  15. 新消费业内人说不出口的10个问题
  16. 微信小程序英文版:实现一键切换中英双语版(已组件化)
  17. python 多因素方差分析_SPSS分析技术:多元方差分析
  18. python画羊_python编程羊车门问题代码示例
  19. 羊了怎么居家办公?免费不限速的远程控制软件RayLink一解燃眉之急!!
  20. Asset Pricing:Introduction

热门文章

  1. 运算放大器的基础原理
  2. wince开发板装linux,米尔i.MX28开发板上市 携Linux和WinCE系统
  3. Kepware助力宾夕法尼亚大学实现校园运营管理
  4. QQ影音自动下载字幕乱码
  5. 自动化运维管理平台TASKCTL如何在Docker安装部署
  6. 安装新版本Cmake
  7. 大区的选择(数据之间的传递)以及用户名的输入
  8. Thymeleaf功能标签th:block
  9. JHipster自动生成项目
  10. LTDZ_35-4400M 频谱仪使用