2026/4/17 21:23:34
网站建设
项目流程
微网站免费软件,服务器图片,温州 网站建设公司,福州网站制作培训在 Vue 应用开发过程中#xff0c;通过合理使用框架特性、避免性能陷阱、优化组件设计等方式#xff0c;从代码层面提升应用性能。
优化实践
使用内置 API 完成需求 JIT 是浏览器中的 JavaScript 引擎在运行时#xff0c;把热点 JavaScript 代码即时编译为机器码#xff…在 Vue 应用开发过程中通过合理使用框架特性、避免性能陷阱、优化组件设计等方式从代码层面提升应用性能。优化实践使用内置 API 完成需求JIT 是浏览器中的 JavaScript 引擎在运行时把热点 JavaScript 代码即时编译为机器码从而提高执行性能的一种机制。Chrome 浏览器 JIT 指内置的 JavaScript 引擎 V8 的即时编译机制。使用 DOM API / BOM API / Vue API 完成开发DOM API / BOM API / Vue API 通常有对应的优化算法必要时或节约开发成本时再使用第三方工具类库辅助。API 底层都是基于 V8 引擎相比 JS 层 JIT 编译执行而言基于 C 的 V8 会更快。sort会根据情况采用归并或者插入排序小数组采用插入大数组采用归并或者是归并 插入的混合排序方案相比手动实现的 JS 排序功能更优。遍历时使用for...of/for代替for...in。for...in语义需要收集对象自身的枚举属性然后再去遍历原型链上的属性过滤掉不可枚举的属性值然后处理属性遮蔽问题最终动态决定遍历结果这个无法预测的枚举流程是无法被跳过的在数组遍历时只能执行慢路径查找。// 推荐使用 for...of 或 for 循环constarr[1,2,3,4,5];for(constitemofarr){console.log(item);}// 或使用传统 for 循环for(leti0;iarr.length;i){console.log(arr[i]);}// 避免使用 for...in 遍历数组性能较差for(constindexinarr){console.log(arr[index]);}避免非必要响应式避免将非响应式实例声明为响应式尤其注意不要将插件实例声明为响应式在 Vue2 中会由于深度递归响应导致大量内存被占用严重会出现假死的情况。在 Vue3 中可以使用shallowRef和shallowReactive来避免非必要的响应逻辑。// ❌ 将插件实例声明为响应式exportdefault{data(){return{// Vue2 会深度递归处理导致性能问题echart:null,moment:moment,};},mounted(){this.echartechart.init();}};// ✅ 使用 Object.freeze 或直接挂载到 thisexportdefault{data(){return{// 使用 Object.freeze 冻结对象避免响应式处理// Vue 处理响应式之前会去判断 configurable 描述符是否可用不可用不会进行响应式处理axios:Object.freeze(axios),};},created(){// 或直接挂载到实例上不放入 datathis.axiosaxios;},};Keepalive 缓存使用keep-alive缓存组件根据需求进行缓存小型项目可以直接进行RouterView级别缓存大型项目指定对大型组件的缓存同时通过max指定最大缓存组件数注意要在activated和deactivated中完成组件的唤醒和卸载处理。!-- 小型项目RouterView 级别缓存 --templatekeep-alive:max10router-view//keep-alive/template!-- 大型项目指定组件缓存 --templatekeep-alive:include[ComponentA,ComponentB]:max5component:iscurrentComponent//keep-alive/templatescriptexportdefault{name:ComponentA,activated(){// 组件被激活时执行// 完成定时器、事件、数据请求this.setTimers();this.refreshData();},deactivated(){// 组件被停用时执行// 销毁定时器事件避免内存泄漏和逻辑冲突this.clearTimers();},};/scriptv-if 和 v-show频繁切换避免使用v-if使用v-show由于v-show会导致代码不太美观可以的话通过component :isbindComponent或者v-if结合keep-alive实现类似的逻辑。template!-- ❌ v-if 会销毁和重建组件 --divv-ifshowComponent组件内容/div!-- ✅ v-show 只切换 display 样式 --divv-showshowComponent组件内容/div!-- ✅ 使用 component 动态组件 keep-alive 组合保持代码美观配合异步组件优化首次渲染体积基于 keep-alive 实现异步组件缓存策略 --keep-alivecomponent:iscurrentComponent//keep-alive/templatescriptexportdefault{components:{// Vue3 用 defineAsyncComponent 封装引入ComponentA:()import(./components/componentA),ComponentB:()import(./components/componentB),},data(){return{showComponent:true,currentComponent:ComponentA,};},};/scriptComputed 缓存计算内容可以用computed计算属性去缓存computed会在依赖属性更新触发视图更新时才会根据dirty标志位判断依赖属性是否更新决定计算新值还是获取缓存值。templatedivp总价{{ totalPrice }}/pp折扣价{{ discountPrice }}/p/div/templatescriptexportdefault{data(){return{items:[{price:10,quantity:2},{price:20,quantity:3},],discount:0.8,};},computed:{// ✅ 依赖变化时才重新计算否则使用缓存totalPrice(){returnthis.items.reduce((sum,item)sumitem.price*item.quantity,0);},// 依赖 totalPrice 计算结果totalPrice 缓存时 discount 不会重复计算discountPrice(){returnthis.totalPrice*this.discount;},},// ❌ 不推荐使用 methods 每次都会重新计算methods:{getTotalPrice(){returnthis.items.reduce((sum,item)sumitem.price*item.quantity,0);},},};/script内部创建和销毁销毁监听器、定时器、实例避免出现内存泄漏影响性能问题。scriptexportdefault{data(){return{timer:null,resizeHandler:null,};},mounted(){// 创建定时器this.timersetInterval((){console.log(定时任务);},1000);// 小技巧通过 AbortController 可以同时销毁多个事件监听器this.controllernewAbortController();window.addEventListener(scroll,this.scrollHandler,{signal:this.controller.signal,});window.addEventListener(resize,this.resizeHandler,{signal:this.controller.signal,});// 三方插件初始化this.thirdPluginplugin.init();},methods:{resizeHandler(){// resize 事件},scrollHandler(){// scroll 事件},},beforeDestroy(){// ✅ 销毁定时器if(this.timer){clearInterval(this.timer);this.timernull;}// ✅ 销毁事件监听if(this.controller){this.controller.abort();this.controllernull;}// ✅ 销毁插件实例if(this.thirdPlugin){// 先看三方插件内部是否有销毁 API 主动执行避免插件内部引用未销毁导致泄漏this.thirdPlugin.destroy();this.thirdPluginnull;}},};/script异步组件Vue-Router 和 Vue 通过异步组件方式按需引入必要时再进行加载。但是要避免过度拆分当组件拆分前请求成本请求耗时、请求体积、是否重复 组件拆分后的请求成本时再考虑进行拆分。importHomefrom/views/Home.vue;// Vue Router 异步组件constroutes[{path:/home,// 首页不推荐异步逻辑避免首页加载白屏component:Home,},{path:/large-page,// ✅ 使用 webpackChunkName 指定 chunk 名称避免过渡拆包可以把同个页面下的子路由都集中在webpackChunk中加载也可以按需拆分component:()import(/* webpackChunkName: large-page *//views/LargePage.vue),},];// Vue 组件异步加载exportdefault{components:{// ✅ 异步组件按需加载HeavyComponent:()import(/components/HeavyComponent.vue),// ✅ 带加载状态和错误处理, Vue3 使用 defineComponent APIAsyncComponent:()({component:import(/components/AsyncComponent.vue),loading:LoadingComponent,error:ErrorComponent,delay:200,// 延迟显示 loadingtimeout:3000,// 超时时间}),},};Vue 官方优化实践Vue.js 官方文档 - 性能优化提供关于 v-once 和函数式组件的优化方案等。Vue2 Cookbook关于 Vue2 的最佳实践。总结使用内置 API优先使用 DOM API / BOM API / Vue API 完成开发这些 API 基于 V8 引擎优化性能优于手动实现的 JavaScript 代码。遍历时使用for...of/for代替for...in避免慢路径查找。避免非必要响应式避免将插件实例等非响应式对象声明为响应式在 Vue2 中会由于深度递归响应导致性能问题。使用Object.freeze冻结对象或直接挂载到实例上避免响应式处理。组件缓存使用keep-alive缓存组件小型项目可以直接进行RouterView级别缓存大型项目指定对大型组件的缓存同时通过max指定最大缓存组件数。注意要在activated和deactivated中完成组件的唤醒和卸载处理。条件渲染优化频繁切换避免使用v-if使用v-show。可以通过component :isbindComponent或者v-if结合keep-alive实现类似的逻辑保持代码美观的同时优化性能。计算属性缓存使用computed计算属性缓存计算结果computed会在依赖属性更新触发视图更新时根据dirty标志位判断是否重新计算否则使用缓存值。资源清理及时销毁监听器、定时器、实例避免内存泄漏。可以使用AbortController同时销毁多个事件监听器对于三方插件需要主动调用销毁 API。异步组件通过异步组件方式按需引入优化首屏加载速度。但要避免过度拆分需要权衡组件拆分前后的请求成本请求耗时、请求体积、是否重复。