vue项目性能优化

用户上传文件的时候,如果文件过大,那么上传可能就会很耗时。而且一旦上传的过程中发生了网络中断,那上传就前功尽弃了。为了提高用户的体验,我们可以选择断点续传,也就是把文件切分成小块后,挨个上传。这样即使中间上传中断,但下次再上传时,只上传缺失的那些部分就可以了。可以看到,断点上传虽然在性能上,会造成网络请求变多的问题,但也极大地提高了用户上传的体验。

文章目录

  • vue项目性能优化
  • 一、上传文件有两套方案
  • 1、基于文件流方案代码
  • 2、基于BASE64的上传方案
  • 二、如何实现断点续传?
  • 总结

一、上传文件有两套方案

1、基于文件流(form-data) element-ui上传组件默认是基于文件流的
2、客户端把文件转化为BASE64,再传给后台

1、基于文件流方案代码

用element-ui提供基于文件流的上传方案:

<template><div id="app"><!-- action:存放的是文件上传到服务器的接口地址--><el-uploaddragaction="/single1":show-file-list="false":on-success="handleSuccess":before-upload="beforeUpload"><i class="el-icon-upload"></i><div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div></el-upload><!-- IMG --><div class="uploadImg" v-if="img"><img :src="img" alt /></div></div>
</template><script>
/** 默认上传*   格式:multipart/form-data*   数据格式:form-data*      file 文件流信息*      filename 文件名字*   上传成功后获取服务器返回信息,通知on-success回调函数执行* 内部封装了ajax*/
export default {name: "App",data() {return {img: null,};},methods: {handleSuccess(result) {if (result.code == 0) {this.img = result.path;}},beforeUpload(file) {// 格式校验let { type, size } = file;if (!/(png|gif|jpeg|jpg)/i.test(type)) {this.$message("文件合适不正确~~");return false;}if (size > 200 * 1024 * 1024) {this.$message("文件过大,请上传小于200MB的文件~~");return false;}return true;},},
};
</script>

2、基于BASE64的上传方案

<template><div id="app"><el-upload drag action :auto-upload="false" :show-file-list="false" :on-change="changeFile"><i class="el-icon-upload"></i><div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div></el-upload><!-- IMG --><div class="uploadImg" v-show="img"><img :src="img" alt /></div></div>
</template><script>
import { fileParse } from "./assets/utils";
import axios from "axios";
import qs from "qs";export default {name: "App",data() {return {img: null,};},methods: {async changeFile(file) {if (!file) return;file = file.raw;// 继续做格式校验/** 把上传的文件先进行解析(FileReader)* 把其转换base64编码格式* 自己基于axios把信息传递给服务器* ...*/let result = await fileParse(file, "base64");result = await axios.post("/single2",qs.stringify({chunk: encodeURIComponent(result),filename: file.name,}),{headers: {"Content-Type": "application/x-www-form-urlencoded",},});result = result.data;if (result.code == 0) {this.img = result.path;}},},
};
</script>

二、如何实现断点续传?

1、拿到文件,对文件进行切片,有两个方式,一种时固定数量,另一种时固定大小。
2、用SparkMD5库对每一个分片进行命名(服务器接口后,会对相同hash的文件进行合并)
3、发请求传文件,可以有串行和并行两种方式。这里使用串行,一个一个发,方便点击暂停上传的时候取消发送。

4、可以拿一个数组保存待发的文件,上传成功的文件可以从数组里面删除。这样,当再次点击继续发送的时候,就不需要重复发送了。

5、等全部文件发完了,再发一个请求告诉服务器文件发完了

dom部分:

<div id="app"><el-upload drag action :auto-upload="false" :show-file-list="false" :on-change="changeFile"><i class="el-icon-upload"></i><div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div></el-upload><!-- PROGRESS --><div class="progress"><span>上传进度:{{total|totalText}}%</span><el-link type="primary" v-if="total>0 && total<100" @click="handleBtn">{{btn|btnText}}</el-link></div><!-- VIDEO --><div class="uploadImg" v-if="video"><video :src="video" controls /></div></div>

文件上传时调用的方法:

   async changeFile(file) {if (!file) return;console.log('file', file)file = file.raw;// 解析成buffer数据// 切片处理,把文件切成多个部分(固定数量/固定大小)// 每一个切片都有自己的部分数据和自己的名字let buffer = await fileParse(file, "buffer"),spark = new SparkMD5.ArrayBuffer(),suffix;spark.append(buffer);let hash = spark.end();suffix = /\.([0-9a-zA-Z]+)$/i.exec(file.name)[1];console.log('suffix', suffix)// 创建100个切片let partList = [],partsize = file.size / 100,cur = 0;for(let i = 0; i < 100; i++) {let item = {chunk: file.slice(cur, cur + partsize),filename: `${hash}_${i}.${suffix}`,       };cur += partsize;partList.push(item)}this.partList = partList;this.hash = hash;this.sendRequest();},

发送请求的方法:

async sendRequest() {// 根据100个切片创建100个请求(集合)let requestList = [];this.partList.forEach((item, index) => {// 每一个函数都是发送一个切片的请求let fn = () => {let formData = new FormData();formData.append("chunk", item.chunk);formData.append("filename", item.filename);return axios.post('/single3', formData, {headers: { "Content-Type": "multipart/form-data" },}).then(res => {res = res.data;if (res.code == 0) {this.total += 1;this.partList.splice(index, 1);}})}requestList.push(fn);})let complete = async () => {let result = await axios.get("/merge", {params: {hash: this.hash,},});result = result.data;if (result.code == 0) {this.video = result.path;}};let i = 0;let send = async() => {// 都发完了if (this.abort) return;if (i >= requestList.length) {complete();return;}await requestList[i]();i++;send();}send();},

处理切换按钮的逻辑:

 handleBtn() {if (this.btn) {// 断点续传this.btn = false;this.abort = false;this.sendRequest();return;}// 暂停上传this.btn = true;this.abort = true;}

总结

虽然文件断点续传的功能要浪费额外的性能,造成网络请求变多的问题,但是这提高了用户体验。
视频资源
项目代码

vue项目性能优化——断点续传相关推荐

  1. Vue项目性能优化篇

    Vue项目性能优化是个老生常谈的问题了,本人开发过程中也查过很多关于Vue项目优化的文章,每篇文章说的都差不多,本章我就结合我的心得和大家的智慧做一个总结. 1.懒加载 懒加载应该是提高性能的最简单有 ...

  2. Vue 项目性能优化方案

    前言 Vue 框架通过数据双向绑定和虚拟 DOM 技术,帮我们处理了前端开发中最脏最累的 DOM 操作部分, 我们不再需要去考虑如何操作 DOM 以及如何最高效地操作 DOM:但 Vue 项目中仍然存 ...

  3. 前端Vue 项目性能优化

    前言 Vue 框架通过数据双向绑定和虚拟 DOM 技术,帮我们处理了前端开发中最脏最累的 DOM 操作部分, 我们不再需要去考虑如何操作 DOM 以及如何最高效地操作 DOM:但 Vue 项目中仍然存 ...

  4. 接手同事vue项目两个月的血和泪,关于vue项目性能优化,缩短首屏加载时间

    最近接手了别人做的vue项目,项目跑起来后,有些页面很卡,首屏加载也慢,打包速度也慢.于是,研究了很久vue的项目性能优化,下面我将从两个部分来详解vue项目的性能优化: 代码优化 webpack打包 ...

  5. Vue项目性能优化方案

    一.代码层面的优化  1.v-if和v-show的使用场景  (1)v-if适用于在运行时很少改变条件,不需要频繁切换条件的场景,属于真正的条件渲染,会确保在切换过程中,元素适当的被销毁和重建,也是惰 ...

  6. 收藏这些vue项目性能优化方式,总有一天能用上

    vue项目如何进行性能优化?下面本篇文章给大家分享一些vue项目一定会用到的性能优化方法,希望对大家有所帮助! 提起性能优化 很多人眼前浮现的面试经验是不是历历在目呢?反正,性能优化在我看来他永远是前 ...

  7. vue项目性能优化(图片优化)

    一.图片保存阶段 ps 或 sketch 等图片,保存时或保存后,使用photoshop .jpg 图片选择 "连续" .png图片选择 "优化" 二. 图片压 ...

  8. vuejs项目性能优化 - 总结篇

    首页等页面加载慢?打包编译后css/js文件过大?试试压缩.路由懒加载等技术 打包编译后,过大的文件如:app.css.app.js.vendor.js 本着 "开发环境".&qu ...

  9. oracle性能优化求生指南_Vue项目性能优化--实践指南,网上最全最详细

    点击上方 "程序员小乐"关注, 星标或置顶一起成长 第一时间与你相约 每日英文 Some happened could not forget, even forget also o ...

最新文章

  1. 抽象类(abstract class)和接口(Interface)的区别
  2. python summary结果提取_Python coverage.summary方法代码示例
  3. pycharm remote 远程项目 同步 本地_利器:PyCharm本地连接服务器搭建深度学习实验环境的三重境界...
  4. 作者:林立,华中科技大学计算机科学与技术学院讲师。
  5. fastdfs删除过期文件_Spring Boot 系列:使用 Spring Boot 集成 FastDFS
  6. 《计算机网络》学习笔记 ·003【数据链路层】
  7. Android View的生命周期详解
  8. VBA实战技巧精粹018:如何汇总数据
  9. 百度定位出现162错误码
  10. python3.5安装scipy_Python3上的Scipy安装
  11. 新手gxf学python---文件操作之登录、注册功能
  12. 荧光染料 ICG-HSA 吲哚菁绿修饰人血白蛋白
  13. 你想要的样子 我都有
  14. C语言编程联练习 烤烧饼
  15. MySQL 内核原理分析(一)
  16. notion 科研_科研新手全面入坑指南
  17. 郭鹤年--亚洲糖王与酒店巨子
  18. 仿联想商城laravel实战---3、前端页面搭建(什么情况下需要路由接参数)
  19. 主机托管服务是怎样收费的?你对主机又了解多少?
  20. python音乐制作案例_Python制作线上音乐播放器的代码示例

热门文章

  1. HTML标签学习基础新人笔记
  2. 社群活动——撬动用户参与意愿的7个指导原则
  3. 将后台的图像数据传回前台并显示出来
  4. 黑马-linux编程
  5. 电脑桌面不见了怎么办?只能调出任务管理器!
  6. 毕设-SpringBoot学生请假系统
  7. 一种LCD屏闪问题的调试
  8. yaourt 之 Curl 错误
  9. OpenCV开发笔记(六十七):红胖子8分钟带你深入了解特征点暴力匹配(图文并茂+浅显易懂+程序源码)
  10. P9:最大池化的使用