Vue项目打包压缩的实现(让页面更快响应)


Posted in Javascript onMarch 10, 2020

影响网页响应速度的因素有很多,例如:http请求次数太多、服务器本身处理请求太久、请求内容太大、JS脚本执行耗时过长、浏览器回流重绘等。网站页面的响应速度与用户体验息息相关,直接影响到用户是否愿意继续访问你的网站。对于Vue项目而言,最普遍的问题可能在于打包后的文件太大,导致加载时间过长。

我的一个小项目,仅有三四个页面,但因为服务器带宽太小了,加载时间过长的问题尤为明显,于是采用路由懒加载和gzip压缩的方式优化了一下,访问速度得到了显著提升。

一、路由懒加载:分割代码块

Vue支持异步组件,即可以在使用组件的地方使用一个Promise,Promise最终会通过resolve回传一个组件对象。而webpack的动态import的方式可以让代码分块进行打包,并且返回一个Promise(正是异步组件所需要的)。在路由配置表里使用import可以将各个页面组件分割成不同的代码块,然后当路由被访问的时候才加载对应的组件,这样就避免将所有内容打包在一个chunk里,从而“按需加载”,大大提高响应速度。

没有使用动态加载的路由配置方式:

// router.js
import VueRouter from 'vue-router'
import Vue from 'vue'
Vue.use(VueRouter)

import Home from '@/pages/Home'
import Tree from '@/pages/Tree'
import SearchHighlight from '@/pages/SearchHighlight'
import Watermark from '@/pages/Watermark'

export default new VueRouter({
 routes: [
  {
   path: '/',
   component: Home,
   children: [
    {
     path: 'tree',
     name: 'Tree',
     component: Tree
    },
    {
     path: 'search-highlight',
     name: 'SearchHighlight',
     component: SearchHighlight
    },
    {
     path: 'watermark',
     name: 'Watermark',
     component: Watermark
    }
   ]
  }
 ]
})

执行yarn build(或npm run build)打包,查看dist文件夹下的js和css:

Vue项目打包压缩的实现(让页面更快响应)

可以看到打包后js和css下各有两个文件,其中chunk-vendors文件包含了所有页面js或者css文件,大小分别为769K、270K。现在修改路由配置使用动态加载组件的方式打包,来看一下打包的文件是怎样的。

使用 () => import('xxx')的形式引入组件:

// router.js
import VueRouter from 'vue-router'
import Vue from 'vue'
Vue.use(VueRouter)

export default new VueRouter({
 routes: [
  {
   path: '/',
   component: () => import('@/pages/Home'),
   children: [
    {
     path: 'tree',
     name: 'Tree',
     component: () => import('@/pages/Tree')
    },
    {
     path: 'search-highlight',
     name: 'SearchHighlight',
     component: () => import('@/pages/SearchHighlight')
    },
    {
     path: 'watermark',
     name: 'Watermark',
     component: () => import('@/pages/Watermark')
    }
   ]
  }
 ]
})

执行yarn build(或npm run build)打包,查看dist文件夹下的js和css:

Vue项目打包压缩的实现(让页面更快响应)

js和css文件夹下各多出来了4个chunk-*文件,刚好对应我们动态引入的4个组件,这样在我们访问到某个页面,才会加载页面对应的chunk-*.js和chunk-*.css。观察文件大小,核心的JS文件chunk-venders大小从769K降低到了725K,因为我的4个页面代码都非常简单,看起来优化效果不大,然而在一个页面很多的大型项目中,优化效果会非常明显,CSS部分也是如此。

二、压缩请求资源

1. 原理介绍

日常我们在使用网盘的时候,上传一个很大的文件夹肯定很慢,这时候我们会把它压缩成一个压缩包,需要下载的时候下载下来解压就可以了,这样大大节省了上传和下载的时间。同样的原理可以用于网络请求,当我们向服务器请求一个资源时,比如js或者css文件,服务器将文件压缩,然后返回到浏览器,浏览器操作解压之后即可使用。

首先浏览器在发送请求的时候,会通过请求头Accept-Encoding告知服务器,本浏览器支持哪些编码格式的资源。打开浏览器的network,查看当前网页的某个请求的请求头:

Vue项目打包压缩的实现(让页面更快响应)

Accept-Encoding的值表示浏览器支持gzip生成的编码格式或者deflate压缩算法生成的编码格式,这就告诉服务器,如果可以把该请求的资源用这两个方法压缩一下给我也是可以的。Accept-Encoding可能还会有compress压缩、identity不压缩的默认格式。

如果服务器对资源进行压缩编码了,它就会通过响应头Content-Encoding告知当前请求用了什么编码格式,当然如果服务器没干这事,则不会返回这个响应头,比如某个请求用gzip压缩了返回的内容:

Vue项目打包压缩的实现(让页面更快响应)

2. 服务器配置

一般我们部署到服务器会使用nginx来做代理服务器,所有的请求都通过nginx转发,这里演示一下nginx配置gzip压缩文件后再返回。配置前先看看示例项目发布到线上的请求情况:

Vue项目打包压缩的实现(让页面更快响应)

可以看到之前生成的chunk-vendors文件,大小725K,请求时间7.10秒,其中下载时间7.05秒,太慢了。配置一下nginx,打开gzip:

server {
    gzip on;
    gzip_types text/plain application/javascript application/x-javascript text/javascript text/xml text/css;
}

这个配置作用是,当nginx服务器返回gzip_types中列出的内容类型时,先使用gzip进行压缩(当然,前提是请求方支持gzip),执行sudo nginx -s reload让该配置生效,此时刷新刚才的页面看一下效果:

Vue项目打包压缩的实现(让页面更快响应)

同样的一个请求,请求内容的大小变成了216K,而下载时间直接降低到了1s多,效果显著!nginx还有gzip的其它配置项,比如可以用gzip_comp_level可以控制压缩率(当然压缩率更高可能意味着更大的服务器消耗),有兴趣的同学可以查看nginx文档。

3. webpack打包时直接使用gzip压缩

上一步骤中,返回内容是在请求服务器的时候使用gzip进行压缩的。这样存在的问题时,对于同一个资源的不同请求,反复压缩,这无疑会增加服务器的CPU和内存消耗。使用webpack的话,可以直接用compression-webpack-plugin插件对我们的代码进行压缩。先安装compression-webpack-plugin到dev依赖:

// yarn安装
yarn add compression-webpack-plugin -D
// 或npm
npm install compression-webpack-plugin --save-dev

简单配置,更多配置可了解官方文档:compression-webpack-plugin:

const CompressionPlugin = require('compression-webpack-plugin')

module.exports = {
 // ...
 configureWebpack: {
  plugins: [
   new CompressionPlugin({
    test: /\.(js|css)?$/i, // 哪些文件要压缩
    filename: '[path].gz[query]', // 压缩后的文件名
    algorithm: 'gzip', // 使用gzip压缩
    minRatio: 1, // 压缩率小于1才会压缩
    deleteOriginalAssets: true // 删除未压缩的文件,谨慎设置,如果希望提供非gzip的资源,可不设置或者设置为false
   })
  ]
 }
}

打包一下看看dist下的js和css文件夹,现在文件都被压缩成了.gz:

Vue项目打包压缩的实现(让页面更快响应)

经过压缩之后chunk-vendors仅有176K,比起原始的725K,压缩了近80%。像图片、字体之类的也可以用这个方法进行压缩,只要修改test配置项的正则表达式匹配这类文件即可。不过现在,还需要在nginx服务器配置一下静态压缩:

server {
  gzip on;
  gzip_types text/plain application/javascript application/x-javascript text/javascript text/xml text/css;
  
  gzip_static on;
}

gzip_static设置为on之后,这样在访问资源的时候,如果存在“资源路径.gz”的文件,则会直接返回该文件,其优先级高于动态的gzip。现在访问一下页面:

Vue项目打包压缩的实现(让页面更快响应)

如果把鼠标悬指到chunk-vendors的size上,可以看到提示“176KB transfered over network, resource size: 724K”。如果你的项目出现请求资源文件太大,可以试试gzip之类的压缩手段,相信有立竿见影的效果。

到此这篇关于Vue项目打包压缩的实现(让页面更快响应)的文章就介绍到这了,更多相关Vue项目打包压缩内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
Sample script that displays all of the users in a given SQL Server DB
Jun 16 Javascript
jquery 事件执行检测代码
Dec 09 Javascript
ASP.NET jQuery 实例14 在ASP.NET form中校验时间范围
Feb 03 Javascript
js输入框邮箱自动提示功能代码实现
Dec 10 Javascript
JS实现动态增加和删除li标签行的实例代码
Oct 16 Javascript
js实现显示手机号码效果
Mar 09 Javascript
详解如何使用Vue2做服务端渲染
Mar 29 Javascript
详解基于Angular4+ server render(服务端渲染)开发教程
Aug 28 Javascript
Layui table 组件的使用之初始化加载数据、数据刷新表格、传参数
Sep 11 Javascript
JavaScript实现短信倒计时60s
Oct 09 Javascript
JavaScript图片处理与合成总结
Mar 04 Javascript
微信小程序导航栏跟随滑动效果的实现代码
May 14 Javascript
vue实现瀑布流组件滑动加载更多
Mar 10 #Javascript
JavaScript代理模式原理与用法实例详解
Mar 10 #Javascript
JavaScript命令模式原理与用法实例详解
Mar 10 #Javascript
JavaScript实现指定数量的并发限制的示例代码
Mar 10 #Javascript
vue中的使用token的方法示例
Mar 10 #Javascript
vue瀑布流组件实现上拉加载更多
Mar 10 #Javascript
JS如何在数组指定位置插入元素
Mar 10 #Javascript
You might like
smarty实例教程
2006/11/19 PHP
php基础知识:类与对象(4) 范围解析操作符(::)
2006/12/13 PHP
PHP实现多文件上传的方法
2015/07/08 PHP
PHP实现路由映射到指定控制器
2016/08/13 PHP
php多进程并发编程防止出现僵尸进程的方法分析
2020/02/28 PHP
JS中confirm,alert,prompt函数区别分析
2011/01/17 Javascript
jQuery下实现等待指定元素加载完毕(可改成纯js版)
2013/07/11 Javascript
基于Javascript实现弹出页面效果
2016/01/01 Javascript
理解javascript中Map代替循环
2016/02/26 Javascript
JavaScript中this的四个绑定规则总结
2016/09/26 Javascript
详解javascript事件绑定使用方法
2016/10/20 Javascript
浅谈vue3中effect与computed的亲密关系
2019/10/10 Javascript
详解Nuxt.js 实战集锦
2019/11/19 Javascript
[48:41]VP vs VG Supermajor小组赛 B组胜者组决赛 BO3 第二场 6.2
2018/06/03 DOTA
[07:20]2018DOTA2国际邀请赛寻真——逐梦Mineski
2018/08/10 DOTA
[46:38]完美世界DOTA2联赛PWL S2 Magma vs PXG 第三场 11.28
2020/12/02 DOTA
python正则表达式修复网站文章字体不统一的解决方法
2013/02/21 Python
Python代码解决RenderView窗口not found问题
2016/08/28 Python
Python之pandas读写文件乱码的解决方法
2018/04/20 Python
Django 忘记管理员或忘记管理员密码 重设登录密码的方法
2018/05/30 Python
flask框架蓝图和子域名配置详解
2020/01/25 Python
python openCV自制绘画板
2020/10/27 Python
BeautifulSoup中find和find_all的使用详解
2020/12/07 Python
关于canvas.toDataURL 在iOS运行失败的问题解决
2020/09/16 HTML / CSS
英国时尚运动品牌的合集:The Sports Edit
2017/12/20 全球购物
追悼会子女答谢词
2014/01/28 职场文书
市场推广策划方案
2014/06/02 职场文书
战略合作意向书
2014/07/29 职场文书
班子查摆四风个人对照检查材料思想汇报
2014/10/04 职场文书
四风问题个人剖析材料
2014/10/07 职场文书
银行党员批评与自我批评
2014/10/15 职场文书
离婚被告代理词
2015/05/23 职场文书
张丽莉事迹观后感
2015/06/16 职场文书
员工保密协议范本,您一定得收藏!很有用!
2019/08/08 职场文书
开学季:喜迎新生,迎新标语少不了
2019/11/07 职场文书
解决Python保存文件名太长OSError: [Errno 36] File name too long
2022/05/11 Python