小柚智汇-Vue项目之浅谈性能优化
Posted web—mark
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了小柚智汇-Vue项目之浅谈性能优化相关的知识,希望对你有一定的参考价值。
江头月底,新诗旧梦,孤恨清香。
概述
随着EDG夺冠的喜讯从7777公里外的冰岛传来,我也完成了自己的 第一个主导团队开发的Vue项目:
- 小柚智汇
- 以我们卓越班同学的实际需求出发,解决周报,文件,计划,打卡,考勤等实际办公学习的协同网站,共七大板块。
- 团队由7人开发
- 开发周期为3个7天
项目前端演示地址: 小柚智汇-卓越生态管理平台 http://39.105.118.190:5000
项目前端代码仓库: github地址(项目代码不完整,只做部分展示)
前端使用技术:
- vue——主要技术栈
- vue-cli——初始化项目和打包项目
- vue-fullpage——首页的全屏切换
- element-ui——主要UI库
- moment.js——格式化时间和日期
- github-markdown-css——富文本编辑器
- vue-router——路由和权限控制
- axios——封装请求
- npm——包管理工具
- 其他第三方库(今日诗词,时间流,验证码,tab切换)
后端技术方案
虽然项目昨天上线,也提供班级使用,但是从内测反馈结果来看,有很多的问题:
经过反复思考,决定做出性能优化之路:
路由懒加载
像vue这种单页面应用,如果没有应用懒加载,运用webpack打包后的文件将会异常的大,造成进入首页时,需要加载的内容过多,时间过长,会出啊先长时间的白屏,即使做了loading也是不利于用户体验,而运用懒加载则可以将页面进行划分,需要的时候加载页面,可以有效的分担首页所承担的加载压力,减少首页加载用时。
统一根路径
静态资源处理
可以看到此项目中的assets目录竟是空的,我将所有图片等引入OSS存储或者图床技术。
当然对于比较小的图片可以考虑做Base64处理。
图片优化
就图片这块来说,与其说我们是在做“优化”,不如说我们是在做“权衡”。因为我们要做的事情,就是去压缩图片的体积(或者一开始就选取体积较小的图片格式)。但这个优化操作,是以牺牲一部分成像质量为代价的。因此我们的主要任务,是尽可能地去寻求一个质量与性能之间的平衡点。
对于图片的处理,让我想起了那句:做电商就是做图片。
打开某东,某宝,里面处处可见,都是流量巨大、技术成熟的站点。
那么我项目中的【柚子小组】模块,对于图片是高需求的,时下应用较为广泛的 Web 图片格式有 JPEG/JPG、PNG、WebP、Base64、SVG 等。对于不同的图片所应用的位置不同。
- JPG 适用于呈现色彩丰富的图片,在我们日常开发中,JPG 图片经常作为大的背景图、轮播图或 Banner 图出现。
- 考虑到 PNG 在处理线条和颜色对比度方面的优势,我们主要用它来呈现小的 Logo、颜色简单且对比强烈的图片或背景等。
- 和性能关系最密切的一点就是:SVG 与 PNG 和 JPG 相比,文件体积更小,可压缩性更强。
- Base64 并非一种图片格式,而是一种编码方式。Base64 和雪碧图一样,是作为小图标解决方案而存在的。
分页处理
还是这个页面,引用了<el-pagination>
的绑定,但仅仅是对前端的分页,如果一次性请求大量数据,效果还是一样甚微,只是利用v-for对渲染进行了循环控制。
利用v-for切出前8个数组索引:
v-for="(item, index) in docs.slice((currentPage-1)*pagesize,currentPage*pagesize)" :key="index"
建议交给后端做分页处理。
长列表优化
对于自己的个性化届面,将来会有大量的列表数据下滑展示,需求如下:
- 长列表,大约超过1000行数据
- 每一行至少8列,每一列都不是单纯的文本节点,都是input,select,checkbox之类的复杂组件
- 每行最后一列有删除按钮,可以进行删除行操作。
- 锁列
这里我们要提到虚拟化列表:
借用此图,有四个概念:
- 可视列表
容器的宽高 height: 800px - 真实列表
举个栗子:现在需要被渲染出来的列表数量一共有100条,但是实际上在页面需要被渲染的列表数量只需要10条,这个10条就是所谓的真实列表。 - startIndex
我的总列表(数组)的长度为1000,而需要渲染的列表片段为100—200,那么这个开始的位置,也就是数组的index则为99。 - endIndex
最后一个元素的index是199。
实现:主要就是通过v-if去控制列表的展示,通过startIdx和endIdx的增减,去展示不同位置的数据,让这两个值递增就可以实现列表滚动。
首屏渲染时间
当我们第一次在url输入http://xxx.xxx.xxx.xxx:xxx时候,浏览器会有白屏现象,为此:
- 将白屏等待加入动画,写在index.html中
- 引入cdn外链。对于一些项目依赖,可以不用打包发布。
在自己的vue.config.js中配置:
忽略打包第三方库
externals: {
vue: 'Vue',
'vue-router': 'VueRouter',
axios: 'axios',
'element-ui': 'ELEMENT',
moment: 'moment'
},
在index.html中按需引入cdn外链
<!-- built files will be auto injected -->
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.11/vue.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/vue-router/3.2.0/vue-router.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
<!-- 引入样式 -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<!-- 引入组件库 -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
-
利用webpack生成项目体积蓝图,检查项目依赖和插件的占比
这个是优化后的:
甚至cdn外链也可以自行购买,但是需要绑定域名(备案)
-
由于CDN部署在网络运营商的机房,这些运营商又是终端用户的网络服务提供商,因此用户请求路由的第一跳就到达了CDN服务器,当CDN中存在浏览器请求的资源时,从CDN直接返回给浏览器,最短路径返回响应,加快用户访问速度,减少数据中心负载压力
-
CDN缓存的一般是静态资源,如图片、文件、CSS、script脚本、静态网页等,但是这些文件访问频度很高,将其缓存在CDN可极大改善网页的打开速度。
反向代理
启动GZIP压缩
我们可以看到,webpack打包时候,名为chunk-vendors.js
的文件,也是浏览器首要渲染的文件,在使用gzip压缩后明显体积大幅缩小。
websocket代替ajax轮询
对于消息中心,【一键签到】的功能,目前还是ajax长轮询/lang loop
ws = new WebSocket(target); //实例化一个ws长链接对象
ws.onopen = function() {
console.log("onopen"); //长链接打开
};
ws.onmessage = function(e) {
console.log(e); //长链接数据传输 主要用这个
};
ws.onclose = function() {
console.log("onclose");//长链接关闭
};
ws.onerror = function() {
console.log("onerror");//长链接出错
};
使用浏览器缓存
- 对一个网站而言,CSS、javascript、logo、图标这些静态资源文件更新的频率都比较低,而这些文件又几乎是每次http请求都需要的,如果将这些文件缓存在浏览器中,可以极好的改善性能。通过设置http头中的cache-control和expires的属性,可设定浏览器缓存,缓存时间可以是数天,甚至是几个月
- 在某些时候,静态资源文件变化需要及时应用到客户端浏览器,这种情况,可通过改变文件名实现,即更新javascript文件并不是更新javascript文件内容,而是生成一个新的JS文件并更新HTML文件中的引用。
- 在某些时候,静态资源文件变化需要及时应用到客户端浏览器,这种情况,可通过改变文件名实现,即更新javascript文件并不是更新javascript文件内容,而是生成一个新的JS文件并更新HTML文件中的引用。
减少cookie传输
一方面,cookie包含在每次请求和响应中,太大的cookie会严重影响数据传输,因此哪些数据需要写入cookie需要慎重考虑,尽量减少cookie中传输的数据量。另一方面,对于某些静态资源的访问,如CSS、script等,发送cookie没有意义,可以考虑静态资源使用独立域名访问,避免请求静态资源时发送cookie,减少cookie传输次数。
Js代码优化
这是项目中用的比较多的样式布局,是从外网搬用的。对于自己造的比较好用的轮子,可以封装成组件进行复用,避免代码的冗余。
一次200多行,最好封装成vue组件。
输入框防抖和登录处理
这篇文章很好的解释了防抖和节流。
啊这,,,,必要性。
利用本地存储
从 Cookie 到 Web Storage、IndexDB
- Cookie 是有体积上限的,它最大只能有 4KB。当 Cookie 超过 4KB 时,它将面临被裁切的命运。这样看来,Cookie 只能用来存取少量的信息。
- Web Storage 是 HTML5 专门为浏览器存储而提供的数据存储机制。它又分为 Local Storage 与 Session Storage。
- Local Storage 是持久化的本地存储,存储在其中的数据是永远不会过期的,使其消失的唯一办法是手动删除;而 Session Storage 是临时性的本地存储,它是会话级别的存储,当会话结束(页面被关闭)时,存储内容也随之被释放。
- Local Storage、Session Storage 和 Cookie 都遵循同源策略。但 Session Storage 特别的一点在于,即便是相同域名下的两个页面,只要它们不在同一个浏览器窗口中打开,那么它们的 Session Storage 内容便无法共享。
- IndexDB 是一个运行在浏览器上的非关系型数据库。既然是数据库了,那就不是 5M、10M 这样小打小闹级别了。理论上来说,IndexDB 是没有存储上限的(一般来说不会小于 250M)。它不仅可以存储字符串,还可以存储二进制数据。
// 将接口返回的用户存储到本地方便应用
window.sessionStorage.setItem('user', JSON.stringify(res.data.data))
// 通过编程式导航跳转到后台主页
this.$router.push('/page')
一般的操作都只是把token存到web storage里面,但其实还有很多不长更新的页面,和css等,都可以暂存到浏览器本地中。
总结下来,对于项目还有很多细化和优化的地方需要去做,但是这次项目的实战对个人和团队的提升是非凡的,无论是从产品设计,业务流程,前端渲染,后端服务,git协同,联调交互等。每个人对于自己的任务都非常清晰,希望它能成为每个人简历上的闪光点。
望大家共同努力,不止“小有智慧”,更能大有成就。
以上是关于小柚智汇-Vue项目之浅谈性能优化的主要内容,如果未能解决你的问题,请参考以下文章