性能优化记录

您好,如果喜欢我的文章,可以关注我的公众号「量子前端」,将不定期关注推送前端好文~

前言

最近零零散散的对刚接手的一个新项目做了一些优化,白屏、打包相关的内容都涉及到了,写一篇文章来记录一下。

白屏相关

DNS预解析、资源预加载

对于项目中有很多静态资源涉及到的公共域名,如g.alicdn.cmon,采用DNS预连接 + 解析:

<link rel="preconnect" href="//g.alicdn.com" crossorigin />
<link rel="dns-prefetch" href="//g.alicdn.com" />

对于项目中一些必要的JS资源,采用资源预加载,可以大幅度缩短资源加载时间:

<link rel="preload" href="https://g.alicdn.com/eleme-risk/xxxxxxx-pc/0.0.99/js/index.js" as="script" />
<link rel="preload" href="//g.alicdn.com/alilog/mlog/aplus_v2.js" as="script" />

结果:整体白屏时间降低400~600ms。

页面级路由懒加载

原本项目打包出来的JS文件只有一个bundle.js,涵盖了整个项目的业务代码,对于业务方来说来说,可能访问最多的就是新增和详情两个页面,所以对于首屏加载是不友好的,应该优化成访问哪个页面加载对应页面的资源,基于Ice2.0调研,将路由中的组件都转换为懒加载模式:

routes.ts

import { lazy, IRouterConfig } from 'ice';
// ice不支持layout组件设置为懒加载
import Layout from '@/layouts/BasicLayout';const Home = lazy(() => import(/* webpackChunkName: 'Home' */ '@/pages/Home'));
const NotFound = lazy(() => import(/* webpackChunkName: 'NotFound' */ '@/components/NotFound'));
const ManualDetect = lazy(() => import(/* webpackChunkName: 'ManualDetect' */ '@/pages/ManualDetect'));
const AddMission = lazy(() => import(/* webpackChunkName: 'addMission' */ '@/pages/ReconnaissanceMission/add-mission'));
const MissionDetail = lazy(() => import(/* webpackChunkName: 'missionDetail' */ '@/pages/ReconnaissanceMission/missionDetail'),
);
const NewMissionDetail = lazy(() => import(/* webpackChunkName: 'newMissionDetail' */ '@/pages/ReconnaissanceMission/newMissionDetail'),
);
const NoPermission = lazy(() => import(/* webpackChunkName: 'NoPermission' */ '@/pages/NoPermission'));
const Board = lazy(() => import(/* webpackChunkName: 'Board' */ '@/pages/Board'));
const BusinessInsight = lazy(() => import(/* webpackChunkName: 'BusinessInsight' */ '@/pages/BusinessInsight'));
const ChuangDaoInsight = lazy(() => import(/* webpackChunkName: 'ChuangDaoInsight' */ '@/pages/ChuangDaoInsight'));
const Report = lazy(() => import(/* webpackChunkName: 'Report' */ '@/pages/Report'));const routes: IRouterConfig[] = [{path: '/',component: Layout,children: [{path: '/manualDetect',component: ManualDetect,},{path: '/addMission',component: AddMission,},{path: '/MissionDetail',component: MissionDetail,},{path: '/newMissionDetail',component: NewMissionDetail,},{path: '/',exact: true,component: Home,},{path: '/noPermission',exact: true,component: NoPermission,},{path: '/board',exact: true,component: Board,},{path: '/businessInsight',exact: true,component: BusinessInsight,},{path: '/chuangDaoInsight',exact: true,component: ChuangDaoInsight,},{path: '/report',exact: true,component: Report,},{component: NotFound,},],},
];export default routes;

看一下效果。

在改动前是这样的:

在这里插入图片描述

无论访问哪个页面,请求固定的JS文件,大小为2.3MB。

改动以后发版:

首屏刷新:

在这里插入图片描述

切换一个路由:

在这里插入图片描述

效果很明显了,文件资源也小了很多,白屏时间自然就下降了。

详细的文章在这里:

React中的懒加载以及在Ice中实践

结果:白屏时间整体降低,请求资源大小整体下降。

构建相关

优化本地热更新时间

项目本地热更新时间比较慢,大约在8~9秒,基于ice运行时中间件在每次代码变更时加入缓存同时移除对node_module目录下的babel转换,可以写一段这样的代码:

module.exports = ({ onGetWebpackConfig }) => {onGetWebpackConfig((config) => {config.module.rule('tsx').test(/\.jsx?|\.tsx?$/).exclude.add(/node_modules/).end().use('babel-loader').tap((options) => {return {...options,cacheDirectory: true,};});});
};

build.json中注入该插件:

{// ..."plugins": ["@ali/build-plugin-faas",["build-plugin-ignore-style",{"libraryName": "antd"}],"@ali/build-plugin-ice-def","./src/index.ts"]
}

在这里插入图片描述

结果:热更新时间降低到4秒左右,降低50%。

构建包大小优化

CDN资源替代项目依赖包

利用Webpack模块可视化工具,项目中的依赖是这样的:

在这里插入图片描述

在这里插入图片描述

从上图可以看到:在开发环境整个构建包体积达到了19.44MB,echartsantvmoment这些包,体积都比较大,达到了MB量级,并且在项目中前两者使用频率很低,只有引用过一次,对于这种情况,考虑将依赖包转换为CDN引入的方式,原因如下:

  • 减少打包产物大小;
  • 减少白屏时间;
  • 版本固定,使用频率低,通过CDN单独引入还会有浏览器强缓存的效益;

通过Webpackexternals,取消对于node_modules中枚举包的计算,并且在项目index.html中从CDN引入所列举到的包。

{// ..."externals": {"echarts": "echarts","moment": "moment"},
}

externals这里的keyvalue值分别对应npm中的包名和CDN引入后在window下的全局变量名,找包的CDN路径很简单,但是如何知道全局变量名是什么呢?

可以打开CDN链接,格式化代码,大概是这个样子的:

function(e, t) {"object" == typeof exports && "object" == typeof module ? //判断环境是否支持commonjs模块规范module.exports = t(require("vue")) :"function" == typeof define && define.amd ? //判断环境是否支持AMD模块规范define("ELEMENT", ["vue"], t) :"object" == typeof exports ? //判断环境是否支持CMD模块规范exports.ELEMENT = t(require("vue")) : e.ELEMENT = t(e.Vue)
} ("undefined" != typeof self ? self: this,function(e){//省略...
});

从这个JS文件可以看到,这个全局变量是ELEMENT咯~这块更详细的教程可以看一下这篇文章,这位博主总结的很全:

Webpack系列』—— externals用法详解

代码分割

这里利用Webpack现有的能力,对使用频繁的第三方库和模块进行统一抽离,这一部分可以写在上面提到的Ice中间件里去:

module.exports = ({ onGetWebpackConfig }) => {onGetWebpackConfig((config) => {config.optimization.splitChunks({cacheGroups: {vendor: {priority: 1,test: /node_modules/,chunks: 'initial',minChunks: 1,minSize: 0,name: 'vendor',filename: 'vendor.js',},common: {chunks: 'initial',name: 'common',minSize: 100,minChunks: 3,filename: 'common.js',},},});});
};

抽离出来的模块如图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-guxjcxoO-1685952375813)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/e804109b80924185bf2062f63b0c70dc~tplv-k3u1fbpfcp-watermark.image?)]

结果:优化后的构建包体积为9.1MB,降低了50%以上大小。

写在最后

本文总结了一下博主近期性能优化的一些点,对于这些点有什么处理不好的地方可以一起讨论~

如果喜欢我的文章,可以关注我的公众号「量子前端」,将不定期关注推送前端好文~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/351911.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

几句话说清楚数据库的基本范式

第一范式 1NF&#xff1a;属性不能再被拆分。 人(身份证号, 姓名, 性别, 联系方式) 不满足 1NF因为联系方式包含了电话号码、电子邮箱、微信、QQ 等人(身份证号, 姓名, 性别, 电话号码) 满足 1NF 第二范式 2NF&#xff1a;不存在非主属性对主键的部分函数依赖关系。 R(A, B,…

创新需求:台灯加装语音识别芯片,打造智能化生活方式

为了满足人们对于智能化生活的需求&#xff0c;现在有一种创新的需求——为台灯加装语音识别芯片&#xff0c;从而实现远程控制、语音操控等更为智能的功能。 科技行业的快速发展&#xff0c;使得语音识别芯片也越来越普及。它们可以使电子产品具有智能化、人性化的交互方式。…

GitHub进不去或者响应满的轻松提速教程

1.先打开记事本用管理员身份运行&#xff0c;打开hosts hosts文件路径&#xff1a;C:\Windows\System32\drivers\etc\hosts&#xff0c;选所有文件&#xff0c;选中hosts文件 打开就是这样 如果打不开&#xff0c;修改一下文件的属性为可编辑 2.通过 https://www.ipaddress.com…

AUTOSAR通信篇-CAN网络通信(三:PduR)

文章目录 PduR简介I-PDU缓存缓存区类型缓存策略缓存共享 I-PDU接收接收来自通信接口的I-PDU接收来自传输协议的I-PDU I-PDU发送通信接口型发送传输协议型发送多播传输处理未知长度I-PDU I-PDU网关通信接口网关缓存立即网关 传输协议直接网关On-the-fly网关 发送取消接收取消零损…

《从零开始学架构:照着做,你也能成为架构师》李运华 读后感

从事软件开发工作已经有一些年头了&#xff0c;架构师作为技术人员心中的第一座山&#xff0c;不免想要向这方面靠&#xff1b;之前零零散散的学过很多技术框架&#xff0c;了解过一些技术理论&#xff0c;但是不成体系&#xff0c;没法儿很好的关联起来&#xff0c;查询过不少…

玩转STM32(4)学会目录分类

前面已经知道怎么样来得到第一个嵌入式程序了&#xff0c;如果还没有下载相应的文件&#xff0c;请先要下载。下载完成之后&#xff0c;就可以把压缩文件解压出来&#xff0c;就会看到一个LED_001的目录。不过&#xff0c;仔细一些的人&#xff0c;也许会发现这个压缩包有点大&…

elasticsearch安装和使用

一、全文检索基础 1. 什么是全文检索 将⾮结构化数据中的⼀部分信息提取出来&#xff0c;重新组织&#xff0c;使其变得有⼀定结构&#xff0c;然后对此有⼀定结构的数 据进⾏搜索&#xff0c;从⽽达到搜索相对较快的⽬的。这部分从⾮结构化数据中提取出的然后重新组织的信息…

【使用指南】ComponentOne Enterprise .NET开发控件集

为方便广大 .NET开发人员更好的使用 ComponentOne Enterprise .NET开发控件集&#xff0c;葡萄城专门推出了 ComponentOne Enterprise 使用指南&#xff0c;该指南详细地介绍了如何把 ComponentOne 各种强大的功能应用到您自己的项目中&#xff0c;助您轻松掌握产品使用技巧&am…

复旦大学肖仰华教授:知识图谱与认知智能 | 附PPT下载

关于作者&#xff1a;肖仰华博士&#xff0c;复旦大学计算机科学与技术学院教授&#xff0c;博士生导师&#xff0c;知识工场实验室负责人。 报告摘要&#xff1a;人类社会已经进入智能化时代。各行各业纷纷踏上智能化升级与转型的道路&#xff0c;各类智能化应用需求大量涌现。…

读万卷书为何无用?

相信大家都听说过 “读万卷书不如行万里路&#xff0c;行万里路不如阅人无数&#xff1b;阅人无数不如名师指路 ” 这句话 。 这句话教给我们&#xff0c;最方便的成功之道是找到高人给我们指路。 很多人都已经意识到&#xff0c;现实生活中高人显然是可遇不可求的&#xff0c;…

mdx词典包_不会用医学词典?停姐手把手教你啊(内附海量医学词典词库资源下载)...

查阅外文文献是医学生必备技能,一个医学生学业生涯里不知道要查阅多少文献,所以拥有一个好用的词典工具就显得尤为重要。 前段时间有小可爱在微信后台问停姐有没有好用的医学词典推荐,停姐这段时间整理了一些分享给大家。 停姐在翻译视频的时候,用的最多的就是 欧路词典 ,…

UI 自动化测试实战(二)| 测试数据的数据驱动

【摘要】数据驱动就是通过数据的改变驱动自动化测试的执行&#xff0c;最终引起测试结果的改变。简单来说&#xff0c;就是参数化在自动化测试中的应用。测试过程中使用数据驱动的优势主要体现在以下几点&#xff1a;1.提高代码复用率&#xff0c;相同的测试逻辑只需编写一条测…

python数据可视化--matplotlib库

目录 python数据可视化--matplotlib库0、前言1、饼图2、直方图3、折线图4、散点图5、柱状图6、箱线图7、极坐标图8、步阶图9、谱图10、功率密度图11、相干谱图 python数据可视化–matplotlib库 0、前言 在进行数据分析的过程中&#xff0c;正所谓“一图胜千言”&#xff0c;一…

【文生图系列】 Stable Diffusion v1复现教程

文章目录 Stable Diffusion v1环境配置权重下载txt2imgbug超参数 Diffusers 参考 Stable Diffusion v1 stable diffusion是一个潜在的文本到图像的扩散模型&#xff0c;能够在给定任何文本输入的情况下生成照片逼真的图像。 环境配置 https://github.com/CompVis/stable-diff…

excel相同内容单元格数值等于固定值怎么做?

如下表&#xff0c;让该表格所有“苹果”内容的单价都等于D3的20元&#xff0c;怎么批量操作&#xff1f; 可以使用Excel的条件格式功能来实现该需求&#xff0c;具体步骤如下&#xff1a; 1. 选中表格中所有的“苹果”单元格&#xff0c;可以使用鼠标拖动或者按住Ctrl键单击选…

奇门遁甲

奇门遁甲应用 一&#xff1a;奇门总要 奇门是中国古代的一种兵学&#xff0c;分为高层应用和中低层应用&#xff0c;高层应用主要用在战争&#xff0c;低层主要是民用预测、风水选择等等。当然这是和当时所处时代是分不开的&#xff0c;奇门在预测方面属于阴性预测学的一种。奇…

程序猿的创业故事:一个游走于计算机编程、高中数学、高中物理、爱好木工的全栈工程师,转行做高中教学的亲生经历!

这个故事有点长 上帝视觉&#xff1a;“转行穷三年&#xff0c;不转穷一生&#xff01;” 我的视觉&#xff1a;“我命由我不由天&#xff01;这个哲理仅仅是正态分布下的一个理论&#xff0c;我是不会服从正态分布的。” 问题1&#xff1a;转不转&#xff0c;为什么转&#…

【Linux初阶】基础IO - 简易 shell添加重定向功能

&#x1f31f;hello&#xff0c;各位读者大大们你们好呀&#x1f31f; &#x1f36d;&#x1f36d;系列专栏&#xff1a;【Linux初阶】 ✒️✒️本篇内容&#xff1a;shell重定向功能的代码实现 &#x1f6a2;&#x1f6a2;作者简介&#xff1a;计算机海洋的新进船长一枚&#…

惊人的磁场定律:你是谁,就会遇见谁

作者&#xff1a;洞见ADC 生命里的磁场无法被看见&#xff0c;但它却在改变我们的人生。 点我 物理学上存在万有引力定律&#xff0c;即自然界任何两个物体&#xff0c;都是存在相互吸引的。 人与人之间&#xff0c;也不例外。 朗达拜恩在《力量》中写道&#xff1a; “每个人身…

基于RPC协议的接口自动化测试可以用Python语言实现

基于RPC协议的接口自动化测试可以用Python语言实现。下面是实现步骤&#xff1a; 1、安装依赖库&#xff0c;如protobuf、grpc。 2、编写.proto文件定义接口参数和返回值。 3、使用protoc编译.proto文件生成Python代码。 4、编写客户端代码调用远程接口进行测试。 具体实现…