news 2026/5/11 4:18:24

Vue——Vue3 首屏加载优化

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Vue——Vue3 首屏加载优化

背景问题:
需要优化首屏加载速度。

方案思考:
通过资源优先级、代码分割等方式优化首屏加载。

具体实现:
首屏加载优化工具:

// utils/first-screen-optimizer.js// 首屏优化工具exportclassFirstScreenOptimizer{constructor(){this.resourcePriorities=newMap()this.loadTimes={}}// 设置资源优先级setResourcePriority(url,priority='high'){this.resourcePriorities.set(url,priority)// 根据优先级预加载资源if(priority==='high'){this.preloadResource(url)}}// 预加载资源preloadResource(url){if('connection'innavigator&&navigator.connection.effectiveType.includes('2g')){// 在慢速网络中不预加载return}constlink=document.createElement('link')link.rel='preload'link.as=this.getResourceType(url)link.href=url document.head.appendChild(link)}// 根据URL判断资源类型getResourceType(url){if(url.endsWith('.js'))return'script'if(url.endsWith('.css'))return'style'if(url.match(/\.(png|jpg|jpeg|gif|svg|webp)$/))return'image'if(url.match(/\.(woff|woff2|ttf|otf)$/))return'font'return'fetch'}// 延迟非关键资源加载deferNonCriticalResources(){// 延迟非关键CSSconstnonCriticalStyles=document.querySelectorAll('link[rel="stylesheet"][media="print"]')nonCriticalStyles.forEach(link=>{setTimeout(()=>{link.media='all'},3000)// 3秒后加载非关键CSS})}// 优化图片加载optimizeImages(){// 为图片添加 loading="lazy" 属性constimages=document.querySelectorAll('img[data-src]:not([loading])')images.forEach(img=>{img.setAttribute('loading','lazy')img.setAttribute('decoding','async')})}// 资源加载时间追踪trackResourceLoad(resource,startTime){this.loadTimes[resource]=performance.now()-startTime}// 获取首屏加载报告getFirstScreenReport(){constnavigation=performance.getEntriesByType('navigation')[0]constpaintMetrics=performance.getEntriesByType('paint')constfirstPaint=paintMetrics.find(entry=>entry.name==='first-paint')constfirstContentfulPaint=paintMetrics.find(entry=>entry.name==='first-contentful-paint')return{dnsTime:navigation.domainLookupEnd-navigation.domainLookupStart,connectTime:navigation.connectEnd-navigation.connectStart,responseTime:navigation.responseEnd-navigation.responseStart,domContentLoaded:navigation.domContentLoadedEventEnd,firstPaint:firstPaint?.startTime,firstContentfulPaint:firstContentfulPaint?.startTime,loadComplete:navigation.loadEventEnd,resourceLoadTimes:this.loadTimes}}// 执行首屏优化asyncoptimize(){// 1. 优化图片this.optimizeImages()// 2. 延迟非关键资源this.deferNonCriticalResources()// 3. 预加载关键资源constcriticalResources=['/api/config',// 关键配置'/fonts/main.woff2'// 关键字体]criticalResources.forEach(resource=>{this.setResourcePriority(resource,'high')})}}exportconstfirstScreenOptimizer=newFirstScreenOptimizer()

首屏骨架屏:

<!-- components/SkeletonScreen.vue --> <template> <div v-if="loading" class="skeleton-screen"> <div class="skeleton-header"> <div class="skeleton-avatar skeleton-item" /> <div class="skeleton-title skeleton-item" /> <div class="skeleton-subtitle skeleton-item" /> </div> <div class="skeleton-content"> <div class="skeleton-line skeleton-item" v-for="i in 5" :key="i" /> </div> <div class="skeleton-actions"> <div class="skeleton-button skeleton-item" /> <div class="skeleton-button skeleton-item" /> </div> </div> <slot v-else /> </template> <script setup> import { defineProps } from 'vue' defineProps({ loading: { type: Boolean, default: true } }) </script> <style scoped> .skeleton-screen { padding: 20px; } .skeleton-item { background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%); background-size: 200% 100%; animation: loading 1.5s infinite; } @keyframes loading { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } } .skeleton-header { display: flex; align-items: center; margin-bottom: 20px; } .skeleton-avatar { width: 40px; height: 40px; border-radius: 50%; margin-right: 12px; } .skeleton-title { height: 24px; width: 120px; margin-right: 8px; } .skeleton-subtitle { height: 18px; width: 80px; } .skeleton-content { margin-bottom: 20px; } .skeleton-line { height: 16px; margin-bottom: 12px; width: 100%; } .skeleton-line:last-child { width: 70%; margin-bottom: 0; } .skeleton-actions { display: flex; gap: 12px; } .skeleton-button { height: 32px; width: 60px; border-radius: 4px; } </style>

首屏优化组合函数:

// composables/useFirstScreenOptimization.jsimport{onMounted}from'vue'import{firstScreenOptimizer}from'@/utils/first-screen-optimizer'exportfunctionuseFirstScreenOptimization(){// 在组件挂载时执行首屏优化onMounted(()=>{firstScreenOptimizer.optimize()})// 返回报告方法return{getReport:()=>firstScreenOptimizer.getFirstScreenReport()}}
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/4 18:23:42

Qwen3-4B手把手教学:没技术背景也能玩转AI,2块钱体验

Qwen3-4B手把手教学&#xff1a;没技术背景也能玩转AI&#xff0c;2块钱体验 你是不是也对AI很好奇&#xff1f;看到别人用AI写诗、画画、回答问题觉得很神奇&#xff0c;但自己一想到“代码”“命令行”“部署”这些词就头大&#xff1f;别担心&#xff0c;这篇文章就是为你写…

作者头像 李华
网站建设 2026/5/7 9:16:06

抖音批量下载助手:5分钟掌握海量视频自动化采集终极方案

抖音批量下载助手&#xff1a;5分钟掌握海量视频自动化采集终极方案 【免费下载链接】douyinhelper 抖音批量下载助手 项目地址: https://gitcode.com/gh_mirrors/do/douyinhelper 还在为手动保存抖音视频而烦恼&#xff1f;抖音批量下载助手正是你需要的智能解决方案&a…

作者头像 李华
网站建设 2026/5/9 1:56:50

视觉智能图像识别自动化终极指南:完美解决方案解放你的双手

视觉智能图像识别自动化终极指南&#xff1a;完美解决方案解放你的双手 【免费下载链接】Smart-AutoClicker An open-source auto clicker on images for Android 项目地址: https://gitcode.com/gh_mirrors/smar/Smart-AutoClicker 你是否曾经因为重复点击游戏按钮而手…

作者头像 李华
网站建设 2026/5/1 0:31:04

MAA明日方舟助手深度体验:智能游戏伴侣的全面解析

MAA明日方舟助手深度体验&#xff1a;智能游戏伴侣的全面解析 【免费下载链接】MaaAssistantArknights 一款明日方舟游戏小助手 项目地址: https://gitcode.com/GitHub_Trending/ma/MaaAssistantArknights 在快节奏的现代生活中&#xff0c;游戏爱好者常常面临时间管理的…

作者头像 李华
网站建设 2026/4/22 22:16:59

ReTerraForged终极指南:快速上手Minecraft地形生成模组

ReTerraForged终极指南&#xff1a;快速上手Minecraft地形生成模组 【免费下载链接】ReTerraForged a 1.19 port of https://github.com/TerraForged/TerraForged 项目地址: https://gitcode.com/gh_mirrors/re/ReTerraForged 还在为Minecraft千篇一律的地形感到乏味吗&…

作者头像 李华
网站建设 2026/5/9 4:05:13

Qwen多模态体验:5块钱玩5小时,免去配置烦恼

Qwen多模态体验&#xff1a;5块钱玩5小时&#xff0c;免去配置烦恼 你是不是也遇到过这种情况&#xff1a;作为自媒体小编&#xff0c;每天要产出图文内容&#xff0c;想用AI来帮忙写文案、配图&#xff0c;提升效率。但公司发的商务本性能一般&#xff0c;IT部门又严格管控&a…

作者头像 李华