H5性能优化-打开效率提升了62%

一、达成的结果

app嵌套h5 加载效率提升了62%。时间从平均2.259s 降到了0.852s

二、优化过程

思路:优化原生webview+h5 ,先测试webview点击到创建时间 120ms(无需优化)。webview 提供了 api 测试 加载url 的进度。但是没提供具体的类似pc端网络的工具。所以就通过ai搜索一些工具。发现阿里云的arms 方便引入。

测试设备 android荣耀50、华为meta9、华为p40、oppo

开发环境测试

测试样本:优化前后各测试10次。

测试移动端h5 引入了阿里云的arms arms.console.aliyun.com/ 可以查看加载某个url的时候 请求的js css、图片、网络请求 跟网页版的网络类似。

php 复制代码
import ArmsRum from '@arms/rum-browser'

ArmsRum.init({
	pid: 'ha63j3v892@efe71d242023cd5',
	endpoint: 'https://ha63j3v892-default-cn.rum.aliyuncs.com',
	// 设置环境信息,参考值:'prod' | 'gray' | 'pre' | 'daily' | 'local'
	env: 'prod',
	// 设置路由模式, 参考值:'history' | 'hash'
	spaMode: 'hash',
	collectors: {
		// 页面性能指标监听开关,默认开启
		perf: true,
		// WebVitals指标监听开关,默认开启
		webVitals: true,
		// Ajax监听开关,默认开启
		api: true,
		// 静态资源开关,默认开启
		staticResource: true,
		// JS错误监听开关,默认开启
		jsError: true,
		// 控制台错误监听开关,默认开启
		consoleError: true,
		// 用户行为监听开关,默认开启
		action: true,
	},
	// 链路追踪配置开关,默认关闭
	tracing: false,
})

export default ArmsRum

步骤一、懒加载echarts

以前的代码

javascript 复制代码
import Api from '@/api'
import * as echarts from 'echarts'
import dayjs from 'dayjs'
export default {
}

现在的代码

javascript 复制代码
async getRepairChart() {
			const echarts = await import('echarts')
			// xxx
			const chartDom = document.getElementById('repairChart')
			const myChart = echarts.init(chartDom)
			const option = {
			}
			myChart.setOption(option)
		},

通过F12查看网络 发现加载列表的时候有出现echartsxxx.js 而且有800多k ,所以就考虑加载列表不应该去加载数据看板的数据。

优化前,测试前日志打印

均是3.234s 然后 当然还测试了华为p40 、oppo机器 由于系统不一样时间有些差别

测试后日志打印

平均是1.71s


华为meta9 9年前的老手机打印log

平均也2s多

优化后

不到0.8s

步骤二、禁用预加载、路由懒加载

通过查看网络发现请求dev-haolipei.cias.cn/app/#/takeO... 超级多的js 跟css

一张图都截取不完。当时就感觉肯定请求了很多无关紧要的资源。

npm run build 执行后查看dist目录index.html 的确很触目惊心 加载了太多没必要的资源了。

go 复制代码
module.exports = {
	publicPath,
	devServer: {
		disableHostCheck: true,
		// host: 'localhost.cias.cn',
		proxy: {
			'/api': {
				target,
				changeOrigin: true,
				// 	cookieDomainRewrite在手机调试时用得上
				// cookieDomainRewrite: '',
				pathRewrite: {
					'^/api': '',
				},
			},
			'/media': {
				target,
				changeOrigin: true,
				pathRewrite: {
					'^/media': '',
				},
			},
		},
	},
	chainWebpack: config => {
		// 禁用预加载
		config.plugins.delete('preload')
		config.plugins.delete('prefetch')
	},
}
禁用它们的核心好处
1. 减少不必要的网络请求,节省带宽
  • preload 可能会强制加载一些 "非关键资源"(如配置不当的情况下,预加载了体积大但当前页面暂时用不到的资源),导致带宽浪费。
  • prefetch 会预加载未来可能访问的路由 chunk(如用户可能不会点击的低频页面),如果用户最终没有访问这些页面,预加载的资源就成了 "无效请求",尤其对移动端用户(流量有限)不友好。

禁用后,资源仅在明确需要时才会加载(如用户进入对应路由时),避免 "提前加载但用不上" 的浪费。

2. 避免阻塞关键资源加载,提升首屏速度
  • 浏览器对同一域名的并发请求数有限制(HTTP/1.1 通常为 6 个)。preload 加载的资源会占用并发名额,可能阻塞当前页面真正需要的关键资源(如核心 JS/CSS),导致首屏渲染延迟。
  • 例如:若 preload 预加载了一个 2MB 的非关键 chunk,可能会挤占首屏 JS 的加载带宽,导致页面 "白屏时间" 变长。

禁用后,浏览器的并发资源会优先分配给当前页面的核心资源,减少阻塞。

3. 避免缓存资源被 "无效资源" 占用

浏览器缓存空间有限,prefetch 预加载的大量 "未来可能用到" 的 chunk 会占用缓存空间,可能导致真正需要长期缓存的核心资源(如 chunk-vendors.js)被挤出缓存,下次访问时需要重新加载。

禁用后,缓存可优先保留关键资源,提升二次访问速度。

4. 适配低网速 / 弱网环境

在 3G、偏远地区等弱网环境下,preload/prefetch 的预加载行为会加剧网络拥堵:

  • 预加载的资源可能耗时过长,导致当前页面的核心资源加载超时。
  • 禁用后,资源加载更 "轻量化",优先保证当前页面可用,符合弱网环境的用户体验需求。
5. 减少开发环境的冗余加载

在开发环境中,Webpack 会频繁编译资源,preload/prefetch 可能导致每次热更新时加载大量无关资源,拖慢开发服务器响应速度,影响开发体验。禁用后可简化开发环境的资源加载逻辑,提升热更新效率。

注意:并非所有场景都适合禁用

preload/prefetch 本身是性能优化手段,若项目存在以下情况,可能需要保留或部分配置:

  • 首屏依赖的关键资源(如核心 CSS、字体)体积大,preload 可加速其加载。
  • 高频访问的路由(如首页→列表页),prefetch 可提前加载列表页 chunk,提升跳转速度。

因此,禁用的合理性取决于项目场景:资源体积大、用户网络不稳定、低频路由多的项目(如移动端 H5)更适合禁用;高频路由明确、网络环境好的项目可选择性保留

路由懒加载

必须写上 /* webpackChunkName: "system-setting" */

以前的代码

css 复制代码
	{
				path: '/takeOrder',
				name: 'HomeTakeOrder',
				component: () =>
					import(
						'@/views/baosi/orderList.vue'
					),
				meta: {
					title: '推返修列表',
					keepAlive: true,
				},
  }

懒加载路由模式

javascript 复制代码
const HomeTakeOrder = () =>
	import(/* webpackChunkName: "take-order" */ '@/views/baosi/orderList.vue')

  {
				path: '/takeOrder',
				name: 'HomeTakeOrder',
				component: HomeTakeOrder,
				meta: {
					title: '推返修列表',
					keepAlive: true,
				},
			},

这样的好处 打包后 会有路由名称

对比

继续测试打印log

可以看看网络请求 就只有5个js文件 总体积不到300k

平均是0.852,基本达成要求

通过npm run build 本地打包看看文件对比大小。

1、体积巨减!!!

2、加载的文件名称是路由名称+hash值

优化前

优化后

三、内部项目具体实践

(增值移动端h5项目可以参考以下操作)

1、禁用预加载

go 复制代码
module.exports = {
	publicPath,
	devServer: {
		disableHostCheck: true,
		// host: 'localhost.cias.cn',
		proxy: {
			'/api': {
				target,
				changeOrigin: true,
				// 	cookieDomainRewrite在手机调试时用得上
				// cookieDomainRewrite: '',
				pathRewrite: {
					'^/api': '',
				},
			},
			'/media': {
				target,
				changeOrigin: true,
				pathRewrite: {
					'^/media': '',
				},
			},
		},
	},
	chainWebpack: config => {
		// 禁用预加载
		config.plugins.delete('preload')
		config.plugins.delete('prefetch')
	},
}

2、将路由全部改成懒加载

并且路由需要/* webpackChunkName:"take-order" */

css 复制代码
	{
				path: '/takeOrder',
				name: 'HomeTakeOrder',
				component: () =>
					import(
						/* webpackChunkName:"take-order" */ '@/views/baosi/orderList.vue'
					),
				meta: {
					title: '推返修列表',
					keepAlive: true,
				},
  }

3、组件懒加载

以前常见写法 就是一进来 把所有组件的都加载进来

比如这个车牌号组件有120k 对于比较大一点的组件可以用懒加载 。

arduino 复制代码
	<van-popup v-model="showPlatePopup" position="bottom" :overlay="false">
			<keyboard
				v-model="baseInfo.plateNumber"
				:show.sync="showPlatePopup"
				@input="handlePlateInput"
			></keyboard>


      import Keyboard from '@/components/numberplate/vnp-keyboard.vue'

      export default {
  	name: 'CreateOrder',
  	components: {
  		MultiSelectPopup,
  		DispatchingPopup,
  		DispatchFailPopup,
  		DispatchFinishPopup,
  		Keyboard,
  	},
    
    }

懒加载代码

用这个方式可以直接在网络中查看到对应组件的名称和大小

ini 复制代码
<van-popup
			v-if="showPlatePopup"
			v-model="showPlatePopup"
			position="bottom"
			:overlay="false"
		>
			<keyboard
				v-model="baseInfo.plateNumber"
				:show.sync="showPlatePopup"
				@input="handlePlateInput"
			></keyboard>
		</van-popup>

    export default {
	name: 'CreateOrder',
	components: {
		MultiSelectPopup,
		DispatchingPopup,
		DispatchFailPopup,
		DispatchFinishPopup,
		Keyboard: () =>
			import(
				/* webpackChunkName: "keyboard" */
				'@/components/numberplate/vnp-keyboard.vue'
			),
	},
}

还有 特别大的第三方库 echart 懒加载 按需引入

四、总结

目前通过禁用预加载、路由懒加载、和第三方组件懒加载使用方式 基本能达到很大程度的优化效果。

但是看图 每次加载前面2个文件一个683k 另外一个285k 还是压缩了的文件 ,

我猜应该是main.js 引入了很多东西,后续还可以有优化空间。移动端的h5 入口文件尽量简洁。

(自己写的页面 一定多注意看一下 网络 有多少个js 和css 图片) 资源过大就要考虑优化了。

性能优化一定要多测试验证、多测试验证、多测试验证,保证业务正常情况下优化性能。

性能优化参考。

juejin.cn/post/718889...

相关推荐
鹏北海2 小时前
TypeScript 类型工具与 NestJS Mapped Types
前端·后端·typescript
烟袅2 小时前
一文搞懂 CSS 定位:relative、absolute、fixed、sticky
前端·css
孟祥_成都2 小时前
你离前端动画高手只差这个秘籍!GSAP ScrollTrigger 动画完全指南!(第一章)
前端·动效
小小前端_我自坚强2 小时前
React 18 新特性深度解析
前端·javascript·react.js
BBB努力学习程序设计2 小时前
Canvas绘图基础:坐标、线条与圆形的艺术
前端·html
小小前端_我自坚强2 小时前
前端性能优化实战:打造极致用户体验
前端·性能优化
BBB努力学习程序设计2 小时前
不只是设计师的工具:Photoshop在前端开发中的高频操作指南
前端·html
烟袅2 小时前
Trae 推出 Solo 模式:AI 开发的“一人一项目”时代来了?
前端·人工智能·solo
zwq写js2 小时前
VSCode定制开发——内置中文翻译插件
javascript·visual studio code