vue3 项目部署到线上环境,初始进入系统,页面卡顿大概一分钟左右,本地正常无卡顿。localStorage缓存1MB数据导致页面卡顿。
使用vue3进行项目开发,前端框架使用jeecg-boot进行开发,项目初期,打包部署到生产环境,无异常。某天,进行前端项目打包部署到生产环境,突然出现异常情况,部署到线上环境,初始进入系统,页面卡顿大概一分钟左右,但是本地开发环境正常无卡顿。
于是使用各种工具,对系统进行分析,浏览器任务管理器,查看系统运行情况;F12查看是否有接口长耗时等问题;使用监控软件监控浏览器资源消耗情况;linux文件句柄打开限制;nginx配置等。
异常情况如下图所示:
1、异常情况分析
a.接口异常可能情况分析
运用各种工具排查观察,在开发者模式下,F12查看请求耗时情况,发现接口请求耗时无异常,都在毫秒(ms)级别能做出响应,但是接口response无响应返回值,于是怀疑后端接口问题,于是使用postman单独调用测试后端接口,发现接口响应无异常,于是排除后端服务问题。
在查看所有请求,包括静态资源,查看所有请求资源时,发现部分静态资源处于pendding状态,于是怀疑静态资源慢,因此也拷贝该资源链接,单独请求,发现资源请求无异常,也能在毫秒(ms)响应。于是排除静态资源问题。多次观察发现,系统初次登录后,进入后端管理页面,需要加载大约1分钟左右时间,请求资源链接178个,但是每次刷新系统或者登录系统时,发现请求资源链接58个左右时,就会存在部分pendding状态的请求资源,总是怀疑该部分资源请求缓慢,但是对于pendding状态的请求资源单独浏览器访问,也能在毫秒(ms)响应。于是排除网络及资源请求缓慢问题。
b.nginx配置分析
怀疑nginx配置问题导致,于是检查nginx配置,部署上线不使用缓存等,仍不能有效解决。于是在本地部署NGINX,并打包项目部署在本地进行排查分析,发现和线上存在相同情况,基本排除nginx问题。
c.缓存数据分析
通过第1点分析,怀疑是因为业务逻辑处理导致系统处于卡顿,没有进行异步操作,导致主线程阻塞导致页面请求资源不能响应。于是想到可能是因为在系统登录后,需要缓存后端数据字典及行政区划及机构数据导致,由于该部分数据大约在1MB、1MB、2MB、2MB,总共在6MB左右,于是想到使用localStorage进行数据缓存时,localStorage是属于单线程,进行同步操作导致。于是查看相关资料,localStorage能缓存数据是5MB,没对该项进行仔细排查,于是排除是该问题导致。
通过多种方式排查后,发现还是不能有效找到导致加载缓慢原因,于是又重新定位到缓存部分,注释掉缓存逻辑代码,发布到生产环境,发现还是同样缓慢。于是就是排除缓存导致。有通过多种方式排查,还是不能找到异常原因。又再次把异常情况定位到缓存进行排查,还是注释掉缓存代码,并清除浏览器缓存,关闭浏览器,重新登录系统,并进入系统,发现能正常进入系统,经过多次测试正常,最终才确认是缓存后端数据导致。
2、问题深入分析
虽然localStorage能存储大小5MB,但是并比意味着数据存读取效率高,因为使用localStorage还涉及到数据序列化等,经过测试发现,存1MB数据到localStorage,大约需要10秒左右,由于localStorage又是单线程同步操作,并阻塞主线程,导致浏览器不能正常加载资源,因此导致初始进入系统,页面卡顿大概一分钟左右情况。
3、缓存解决方案
由于缓存数据量较大,因此经过分析,最终使用indexedDB解决。
4、localforage解决方案
查阅文档,发现indexedDB相关的API操作极为复杂,对于开发使用极为不便,因此想对indexedDB相关API进行封装。但是在查阅文档资料,发现localforage已对indexedDB进行高度封装,使用极其简易,因此选择localforage对数据进行缓存。部分核心代码如下:
//数据存取// 解决数据缓存卡顿问题const userStore = useUserStore();const indexedDB = localforage.createInstance({name: 'indexedDB',// 支持config所有配置// storeName: 'keyvaluepairs', // 仅接受字母,数字和下划线});// 接口数据请求getSysDictionary().then((res) => {if (res && Object.keys(res).length > 0) {// 数据缓存indexedDB.setItem(DB_DICT_DATA_KEY, res);}});// 数据读取indexedDB.getItem(DB_DICT_DATA_KEY).then((res) => {userStore.dictItems = res;});
由于indexedDB相关API数据读写都是异步操作,因此当需要进行同步访问时,需要使用关键字await进行操作。诺调用方法不能使用async关键字,即可能是通用方法封装或者涉及UI更新,必须同步返回,此事由于异步原因,不能很好处理,即便使用then或者promise也不便于处理,那么解决思路是,数据缓存到indexedDB时,同时缓存数据到浏览器页面,比如
useUserStore,此时能解决异步导致需要UI更新问题。
5.相关大数据学习demo地址:
https://github.com/carteryh/big-data
相关文章:

vue3 项目部署到线上环境,初始进入系统,页面卡顿大概一分钟左右,本地正常无卡顿。localStorage缓存1MB数据导致页面卡顿。
使用vue3进行项目开发,前端框架使用jeecg-boot进行开发,项目初期,打包部署到生产环境,无异常。某天,进行前端项目打包部署到生产环境,突然出现异常情况,部署到线上环境,初始进入系统…...

软件更新中的风险识别与质量保证机制分析
您好,我是程序员小羊! “微软蓝屏”事件暴露了网络安全哪些问题? 近日,一次由微软视窗系统软件更新引发的全球性“微软蓝屏”事件,不仅成为科技领域的热点新闻,更是一次对全球IT基础设施韧性与安全性…...

QT下载与安装
我们要下载开源的QT,方式下载方式: 官网 登录地址:http://www.qt.io.com 点击右上角的Download. Try.按钮;进入一下画面: 如果进入的是以下画面: 直接修改网址:www.qt.io/download-dev; 改为w…...

Java 2.2 - Java 集合
Java 集合,也叫做容器,主要是由两大接口派生而来:一个是 Collection 接口,主要用于存放单一元素;另一个是 Map 接口,主要用于存放键值对。对于 Collection 接口,其下又有三个主要的子接口&#…...

Linux驱动.之I2C,iic驱动层(二)
一、 Linux下IIC驱动架构 本篇只分析,一个整体框架。 1、首先说说,单片机,的i2c硬件接口图,一个i2c接口,通过sda和scl总线,外接了多个设备device,通过单片机,来控制i2c的信号发生&…...

【STM32】USART串口和I2C通信
个人主页~ USART串口和I2C通信 USART串口一、串口1、简介2、电路要求3、参数及时序 二、USART外设1、USART结构2、波特率发生器 三、数据包1、HEX数据包HEX数据包接收 2、文本数据包文本数据包接收 I2C通信一、简介二、通信协议1、硬件电路2、I2C时序基本单元 三、I2C外设1、简…...

【Material-UI】按钮组:垂直按钮组详解
文章目录 一、按钮组概述1. 组件介绍2. 基本用法 二、垂直按钮组的应用场景1. 导航菜单2. 表单操作3. 选项切换 三、按钮组的样式定制1. 变体(Variants)2. 颜色(Colors) 四、垂直按钮组的优势1. 空间利用2. 可读性与易用性3. 视觉…...

DDR5 的优势与应用
DDR5 是新一代 DRAM 内存,具有一系列强大的功能,可提升可靠性、可用性和可维护性 (RAS),降低能耗并显著提高性能。请查看下方表格,了解 DDR4 和 DDR5 之间的一些主要特性差异。 DDR5 的优势 特性/选项 DDR4DDR5DDR5 优势数据速率…...

STM32 - 笔记
1 STM32的串口通信 【keysking的STM32教程】 第8集 STM32的串口通信_哔哩哔哩_bilibili 波特律动 串口助手...

基于QT实现的简易WPS(已开源)
一、开发工具及开源地址: 开发工具:QTCreator ,QT 5 开源地址: GitHub - Whale-xh/WPS_official: Simple WPS based on QTSimple WPS based on QT. Contribute to Whale-xh/WPS_official development by creating an acc…...
Flask-WTF 表单处理详细教程(第六阶段)
目录 Flask-WTF 表单处理详细教程1. 安装 Flask-WTF2. 创建 Flask 应用3. 创建表单类表单字段解释: 4. 渲染表单渲染模板CSRF 保护 5. 表单验证6. 处理错误7. 完整示例8. 结论 Flask-WTF 表单处理详细教程 Flask-WTF 是 Flask 框架的一个扩展,简化了 We…...

C语言 | Leetcode C语言题解之第330题按要求补齐数组
题目: 题解: int minPatches(int* nums, int numsSize, int n) {int patches 0;long long x 1;int index 0;while (x < n) {if (index < numsSize && nums[index] < x) {x nums[index];index;} else {x << 1;patches;}}retu…...

无人机之测绘行业篇
无人机倾斜摄影技术凭借快速高效、机动灵活、成本低等优势,正慢慢颠覆传统测绘的作业方式,已成为测绘行业的“新宠”,将倾斜摄影技术应用到无人机上,实际上就是在做一个三维模型,而建立起来的这个模型更加真实…...
Java编程:每日挑战
目录 题目1.一个抽象类并不需要其中所有的方法都是抽象的。( )2.下面有关java hashmap的说法错误的是?A. HashMap 的实例有两个参数影响其性能:“初始容量” 和 “加载因子”。B. HashMap 的实现不是同步的,意味着它不…...

【自动驾驶】ubuntu server安装桌面版
目录 安装桌面版当锁屏界面使用root用户登录错误时 这里环境一开始是ubuntu20.04服务器版本 安装桌面版 sudo apt-get update sudo apt-get upgrade apt-get install -y ubuntu-desktop # 如果你不想安装一些附加的程序,可用以下命令 sudo apt install --no-instal…...

前端模块化-手写mini-vite
前言 本文总结了一些关于 Vite 的工作原理,以及一些实现细节。 本节对应的 demo 可以在这里找到。 什么是 Vite Vite 是一个基于浏览器原生 ES imports 的开发服务器。利用浏览器去解析 imports,在服务器端按需编译返回,完全跳过了打包这个…...

SpringBoot中fastjson扩展: 自定义序列化和反序列化方法实战
❃博主首页 : 「码到三十五」 ,同名公众号 :「码到三十五」,wx号 : 「liwu0213」 ☠博主专栏 : <mysql高手> <elasticsearch高手> <源码解读> <java核心> <面试攻关> ♝博主的话 :…...

【QT】鼠标按键事件 - QMouseEvent QKeyEvent
qt 事件 事件1. 事件概念2. 事件的处理3. 按键事件(1)单个按键(2)组合按键 4. 鼠标事件(1)鼠标单击事件(2)鼠标释放事件(3)鼠标双击事件(4&#x…...
纯手工在内网部署一个Docker私有仓库
纯手工在内网部署一个Docker私有仓库 下载Docker仓库的镜像上传仓库的镜像导入仓库的镜像启动仓库镜像配置客户端的Docker上传镜像到本地仓库从本地仓库拉取镜像 下载Docker仓库的镜像 这个镜像不太好找,有需要的可以从下面的地址中下载。 通过百度网盘分享的文件…...
农林经济管理学报
《农林经济管理学报》是由江西省教育厅主管、江西农业大学主办、北京大学中国农业政策研究中心和中国人民大学农业与农村发展学院学术支持的农林经管类学术双月刊,以主要刊载农林经济政策与理论,反映农林经济管理前沿动态和研究成果,开展学术…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
【Java学习笔记】Arrays类
Arrays 类 1. 导入包:import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序(自然排序和定制排序)Arrays.binarySearch()通过二分搜索法进行查找(前提:数组是…...

关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...

前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
css的定位(position)详解:相对定位 绝对定位 固定定位
在 CSS 中,元素的定位通过 position 属性控制,共有 5 种定位模式:static(静态定位)、relative(相对定位)、absolute(绝对定位)、fixed(固定定位)和…...

基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...
PostgreSQL——环境搭建
一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在࿰…...

ui框架-文件列表展示
ui框架-文件列表展示 介绍 UI框架的文件列表展示组件,可以展示文件夹,支持列表展示和图标展示模式。组件提供了丰富的功能和可配置选项,适用于文件管理、文件上传等场景。 功能特性 支持列表模式和网格模式的切换展示支持文件和文件夹的层…...