首屏加载慢原因: Vue只有第一次会加载页面, 以后的每次页面切换,只需要进行组件替换。因为Vue 是SPA,所以首页第一次加载时会把所有的组件以及组件相关的资源全都加载了,造成网站首页打开速度变慢的问题 (打包构建时 js包会很大)*

1、路由懒加载

懒加载: 把代码在一些逻辑断点处分离开,然后在一些代码块中完成某些操作后,立即引用或即将引用另外一些新的代码块。

通过import()引用的子模块会被单独分离出来,打包成一个单独的文件(打包出来的文件被称为chunk )依照webpack原本的打包规则打包项目,我们就无法确定子模块在打包出来的哪个JS文件中,而且子模块的代码会和其他代码混合在同一个文件中。这样就无法进行懒加载操作。所以,要实现懒加载,就得保证懒加载的子模块代码单独打包在一个文件中。

懒加载(按需加载)原理分两步:

  1. 将需要进行懒加载的子模块打包成独立的文件 children chunk
  2. 借助函数来实现延迟执行子模块的加载代码

实现方法:

// 在进入路由后才会加载这个 chunk 文件
component: () => import('@/views/emOrderHandle/eeOrderTxzSocTwoHandle') // 每个组件打包成一个js文件
// 指定了相同的webpackChunkName,会合并打包成一个js文件。 把组件按组分块
() => import(/* webpackChunkName: "orderHandleRoute" */ './UserDetails.vue')
() => import(/* webpackChunkName: "orderHandleRoute" */ './eeOrderTxzSocTwoHandle.vue')

2、CDN链接& externals

默认的打包规则会将开发环境中 npm 引入的依赖打入项目公共模块集合中 即 chunk-vendors.js在页面首次加载时会被下载。通过减小公共依赖包体积达到优化首屏速度的目的

externals 的作用在于防止将某些 import 的包(package)打包到 bundle 中,而是在运行时(runtime)再去从外部(CDN方式)获取这些扩展依赖,我们可以在 bootcdn网站上找到相关包的CDN链接

// externals 排除不需要打包的依赖包
module.exports = {// vue/cli 中在此处管理 webpack 配置configureWebpack: (config) => {externals: {'vue': 'Vue','vue-router': 'VueRouter','vuex': 'Vuex''element-ui': 'ELEMENT','axios': 'axios'}}
}

externals 处理之后就不会出现在打包之后的 js 包中了, 接下来还需要在vue的入口html中加入CDN链接

<!-- index.html -->
<script src="https://cdn.bootcdn.net/xxx.min.js"></script>
<script src="https://cdn.bootcdn.net/xxx.min.js"></script>
<script src="https://cdn.bootcdn.net/xxx.min.js"></script>
<link href="https://xxx/index.css">

3、使用 splitChunks 插件,配置分离规则

SplitChunks插件来控制Webpack打包生成的js文件的内容的精髓就在于,防止模块被重复打包,拆分过大的js文件,合并零散的js文件。最终的目的就是减少请求资源的大小和请求次数。

// splitChunks 的默认配置
module.exports = {chainWebpack(config) {config.optimization.splitChunks({chunks: 'async',minSize: 30000,maxSize: 0,minChunks: 1,maxAsyncRequests: 6, // 同时也限制了同一 priority 最大分块次数maxInitialRequests: 4,automaticNameDelimiter: '~',cacheGroups: {vendors: {name: 'chunk-vendors',test: /[\\/]node_modules[\\/]/,priority: -10,chunks: 'all'},common: {name: 'chunk-common',minChunks: 2,priority: -20,chunks: 'initial',reuseExistingChunk: true}}}}
}

在默认配置下(chunks === 'async')main.js中异步加载或间接异步加载的模块,都会被另外打包生成一个js文件

// 异步加载的模块:通过import('xxx') 或 require(['xxx'],() =>{}) 加载的模块。
// 同步加载的模块:通过 import xxx 或 require('xxx') 加载的模块。

根据 cacheGroups中对vendors的设定:

  • test匹配项目从node_modules中加载的模块并根据 chunks的设定提取打包
  • chunks: 'initial'时表示:node_modules在项目中被异步或同步加载多少次,那这个模块就被提取多少次,分别打包到不同文件中。
  • chunks: 'all'时表示:node_modules不管异步加载还是同步加载的模块都是提取打包到一个文件中。

可以看到所有的 node_modules模块都被提取到chunk-vendors文件中去了

下一步继续提取chunk-vendors减小它的体积:可以将诸如element-uixlsx等模块提取为一个个独立的文件

cacheGroups: {vendors: {name: 'chunk-vendors',test: /[\\/]node_modules[\\/]/,priority: -10,chunks: 'all'},common: {name: 'chunk-common',minChunks: 2,priority: -20,chunks: 'initial',reuseExistingChunk: true},// 继续添加其他提取规则 注意 priority 要比 vendors 大才能提取出来'element-ui': {name: 'element-ui',test: /[\\/]element-ui[\\/]/,chunks: 'all',priority: 0},'moment': {name: 'moment',test: /[\\/]moment[\\/]/,chunks: 'all',priority: 0},'xlsx': {name: 'xlsx',test: /[\\/]xlsx[\\/]/,chunks: 'all',priority: 0},'lodash': {name: 'lodash',test: /[\\/]lodash[\\/]/,chunks: 'all',priority: 0}
}

还可以继续提取出现在多个chunk中的文件

CoEffectReportComponents: {name: 'CoEffectReportComponents',test: /[\\/]CoEffectReportComponents[\\/]/,reuseExistingChunk: true,priority: 0
},
dataEntryInput: {name: 'dataEntryInput',test: /[\\/]dataEntryInput[\\/]/,reuseExistingChunk: true,priority: 0
}

SplitChunks插件配置选项

  • chunks选项,决定要提取那些模块。

    • 默认是async:只提取异步加载的模块出来打包到一个文件中。

      • 异步加载的模块:通过import('xxx')require(['xxx'],() =>{})加载的模块。
    • initial:提取同步加载和异步加载模块,如果xxx在项目中异步加载了,也同步加载了,那么xxx这个模块会被提取两次,分别打包到不同的文件中。

      • 同步加载的模块:通过 import xxxrequire('xxx')加载的模块。
    • all:不管异步加载还是同步加载的模块都提取出来,打包到一个文件中。
  • minSize选项:规定被提取的模块在压缩前的大小最小值,单位为字节,默认为30000,只有超过了30000字节才会被提取。

  • maxSize选项:把提取出来的模块打包生成的文件大小不能超过maxSize值,如果超过了,要对其进行分割并打包生成新的文件。单位为字节,默认为0,表示不限制大小。

  • minChunks选项:表示要被提取的模块最小被引用次数,引用次数超过或等于minChunks值,才能被提取。

  • maxAsyncRequests选项:最大的按需(异步)加载次数,默认为 6。

  • maxInitialRequests选项:打包后的入口文件加载时,还能同时加载js文件的数量(包括入口文件),默认为4。

  • 先说一下优先级 maxInitialRequests / maxAsyncRequests <maxSize<minSize

  • automaticNameDelimiter选项:打包生成的js文件名的分割符,默认为~

  • name选项:打包生成js文件的名称。

  • cacheGroups选项,核心重点,配置提取模块的方案。里面每一项代表一个提取模块的方案。下面是cacheGroups每项中特有的选项,其余选项和外面一致,若cacheGroups每项中有,就按配置的,没有就使用外面配置的。

    • test选项:用来匹配要提取的模块的资源路径或名称。值是正则或函数。
    • priority选项:方案的优先级,值越大表示提取模块时优先采用此方案。默认值为0。
    • reuseExistingChunk选项:true/false。为true时,如果当前要提取的模块,在已经在打包生成的js文件中存在,则将重用该模块,而不是把当前要提取的模块打包生成新的js文件。
    • enforce选项:true/false。为true时,忽略minSizeminChunksmaxAsyncRequestsmaxInitialRequests外面选项

4、开启 gzip 压缩

gzip压缩能够缩小一倍多的体积,是非常有效的优化手段,兼容性也很好

响应头里显示有Content-Encoding: gzip,表示浏览器支持并且启用了Gzip压缩的资源

  • 代码层压缩
// CompressionPlugin 插件在 vue/cli 中的使用
module.exports = {configureWebpack: (config) => {if (process.env.NODE_ENV === 'production') {return {plugins: [new CompressionPlugin({test: /\.js$|\.html$|\.css$|\.jpg$|\.jpeg$|\.png/, // 需要压缩的文件类型threshold: 10240, // 归档需要进行压缩的文件大小最小值 10kdeleteOriginalAssets: false // 是否删除原文件})]}}}
}
  • 服务端压缩 (nginx)
http {gzip on; # 开启gzip压缩gzip_min_length 4k; # 小于4k的文件不会被压缩,大于4k的文件才会去压缩gzip_buffers 16 8k; # 处理请求压缩的缓冲区数量和大小,比如8k为单位申请16倍内存空间;使用默认即可,不用修改gzip_http_version 1.1; # 早期版本http不支持,指定默认兼容,不用修改gzip_comp_level 2; # gzip 压缩级别,1-9,理论上数字越大压缩的越好,也越占用CPU时间。实际上超过2的再压缩,只能压缩一点点了,但是cpu确是有点浪费。因为2就够用了gzip_types text/plain application/x-javascript application/javascript text/javascript text/css application/xml application/x-httpd-php image/jpeg image/gif image/png application/vnd.ms-fontobject font/x-woff font/ttf; # 压缩的文件类型 MIME类型gzip_vary on; # 是否在http header中添加Vary: Accept-Encoding,一般情况下建议开启
}

多层 nginx 代理时 gzip 不生效的坑:

# 第一层
http {gzip_static on;gzip_http_version 1.1;gzip_proxied expired no-cache no-store private auth;gzip_vary on;
}# 第二层
http {gzip_static on;gzip_http_version 1.0;gzip_proxied expired no-cache no-store private auth;gzip_vary on;
}

5、服务端渲染 SSR (未完待续)

vue2首屏性能优化(splitChunks/externals/gzip/路由懒加载)相关推荐

  1. vue路由懒加载_优化vue项目的首屏加载速度

    最近使用vue-cli3构建了一个小型的博客系统,完工之后,build打包出来发现一个chunk-vendors包就有1.1m,部署上去之后,访问的时候,首屏加载非常慢.居然需要21s,体验极差. 这 ...

  2. vue首屏性能优化,解决页面加载时间过长(白屏)方法

    vuecli做了个spa项目,大概有几十个个路由 直接 npm run build打包出来,有一个 1M的巨大 js文件,导致首页白屏时间过长 分析工具 vuecli 2.x自带了分析工具,只要运行 ...

  3. Vue首屏性能优化组件

    Vue首屏性能优化组件 简单实现一个Vue首屏性能优化组件,现代化浏览器提供了很多新接口,在不考虑IE兼容性的情况下,这些接口可以很大程度上减少编写代码的工作量以及做一些性能优化方面的事情,当然为了考 ...

  4. vue“路由懒加载” 技术,让网页快速加载 (优化篇)

    (含代码示例.截图演示)让中大型vue项目,按需加载文件,让网页快速渲染! 官方文档:路与懒加载 所谓的路由懒加载: 代码示例 · 对比: 1. 没有优化的代码(截图1 · 省略) import Vu ...

  5. 微信小程序优化:如何实现图片懒加载?

    前言 当我们在使用微信小程序浏览图片时,不可避免地会遇到加载缓慢的情况.这不仅会影响用户体验,还会耗费用户的流量.那么,有没有一种方法可以让图片在用户需要时再进行加载,从而提升用户体验和减少流量消耗呢 ...

  6. 02、如何进行网站性能优化或怎么加快页面的加载速度

    2.如何进行网站性能优化? 1) 减少HTTP请求数 合并js文件 合并css文件 雪碧图的使用(css sprite) 使用base64表示简单的图片 2)减小资源体积 gzip压缩 js混淆 cs ...

  7. Web前端性能优化——如何有效提升静态文件的加载速度

    原文链接:https://wetest.qq.com/lab/view/345.html?from=content_qcloud WeTest 导读 此文总结了笔者在Web静态资源方面的一些优化经验. ...

  8. 【前端优化】Externals 实现运行时加载依赖

    webpack(vue-cli 自带) 中的 externals 配置选项提供了从输出的 bundle 中排除依赖的方法.防止将某些(自己配置)依赖打包,而是在项目运行时(runtime)从外部加载这 ...

  9. 性能优化---vue路由懒加载和异步组件

    1.路由懒加载 整个网页默认是刚打开就去加载所有页面,路由懒加载就是只加载你当前点击的那个模块. 实现方式有: 1.require:加载组件. component: resolve => req ...

最新文章

  1. JavaScript作用域面试题避坑指南
  2. 机器手六维坐标怎么定义_从基础到实操,一本书读懂ABB工业机器人
  3. 杨泽业:让你的网站无限可能之给你的网站增加汉字转拼音的新功能
  4. DataSnap 2009 系列之二 (方法篇)
  5. java同名过滤器_Gateway Redis令牌桶请求限流过滤器
  6. 提高BSEG处理效率
  7. SAP系统财务模块的集团公司处理模式
  8. aws创建html网页,AWS: 在AWS上创建一个网站,综合运用(Lambda + Api Gateway + Dynamodb + S3)...
  9. QT QML 在qml中自定义信号
  10. 纪念中学15-5(=10)天感想
  11. 移动pc常用Meta标签
  12. mysql bin oct_python 讲解进制转换 int、bin、oct、hex
  13. 夜深人静写算法(二)- 动态规划
  14. excel max函数的使用
  15. 从《象形拳法真诠》看王芗斋与薛颠
  16. 为什么要将图片转为base64格式
  17. Google Research等机构提出新的AI算法以了解人脑网络中的电刺激效应
  18. 一首歌曲,没有寻找到试听资源
  19. Linux下wait_for_completion引起的开机定屏
  20. 权力的游戏刷声望辅助【多开辅助】权力的游戏手游辅助挂机刷石油资源采集脚本

热门文章

  1. 粗糙集 matlab,粗糙集理论权重确定方法用matlab实现
  2. 花旗金融 热招职位(上海+大连)
  3. MAUI 框架入门学习01
  4. python >>按位运算符号解释
  5. mysql的check约束怎么设置_Mysql中怎样实现check约束?
  6. 服务器集群安装matlab2015
  7. 用nodejs写一个简易小爬虫
  8. maya包裹表情变形_MAYA制作逼真的人物表情之变形制作教程
  9. 广播接收器动静态注册
  10. 10元买啤酒问题Java递归