小柚智汇-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 等。对于不同的图片所应用的位置不同。

  1. JPG 适用于呈现色彩丰富的图片,在我们日常开发中,JPG 图片经常作为大的背景图、轮播图或 Banner 图出现。
  2. 考虑到 PNG 在处理线条和颜色对比度方面的优势,我们主要用它来呈现小的 Logo、颜色简单且对比强烈的图片或背景等。
  3. 和性能关系最密切的一点就是:SVG 与 PNG 和 JPG 相比,文件体积更小,可压缩性更强。
  4. 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之类的复杂组件
  • 每行最后一列有删除按钮,可以进行删除行操作。
  • 锁列

这里我们要提到虚拟化列表:
在这里插入图片描述

借用此图,有四个概念:

  1. 可视列表
    容器的宽高 height: 800px
  2. 真实列表
    举个栗子:现在需要被渲染出来的列表数量一共有100条,但是实际上在页面需要被渲染的列表数量只需要10条,这个10条就是所谓的真实列表。
  3. startIndex
    我的总列表(数组)的长度为1000,而需要渲染的列表片段为100—200,那么这个开始的位置,也就是数组的index则为99。
  4. endIndex
    最后一个元素的index是199。

实现:主要就是通过v-if去控制列表的展示,通过startIdx和endIdx的增减,去展示不同位置的数据,让这两个值递增就可以实现列表滚动。

首屏渲染时间

在这里插入图片描述

当我们第一次在url输入http://xxx.xxx.xxx.xxx:xxx时候,浏览器会有白屏现象,为此:

  1. 将白屏等待加入动画,写在index.html中
    在这里插入图片描述
  2. 引入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协同,联调交互等。每个人对于自己的任务都非常清晰,希望它能成为每个人简历上的闪光点。

在这里插入图片描述

望大家共同努力,不止“小有智慧”,更能大有成就。

  • 30
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 14
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值