Laravel+Vue项目如何根据访问页面按需懒加载元素以优化性能?
Laravel+Vue项目按需加载优化方案
核心问题拆解
当前代码存在三个关键问题:
- 循环创建不存在的Vue实例,导致"Cannot find element"报错
- 全局引入Vuetify等非通用依赖,增加页面加载体积
- 所有页面都触发
fetchProducts请求,造成不必要的资源消耗
优化步骤
1. 给页面容器添加配置标记
修改Blade模板,为每个Vue容器添加自定义属性,标记当前页面的依赖需求:
page1.blade.php
<body> <div id="app0" class="my-component-class-wrapper" data-required-components="info" data-use-vuetify="false" data-fetch-products="false"> <info></info> </div> <script defer src="{{ mix('js/app.js') }}"></script> </body>
page2.blade.php
<body> <div id="app1" class="my-component-class-wrapper" data-required-components="addToCart" data-use-vuetify="true" data-fetch-products="true"> <add-to-cart></add-to-cart> </div> <script defer src="{{ mix('js/app.js') }}"></script> </body>
2. 修改app.js实现按需加载逻辑
重构代码,只针对页面实际存在的容器创建实例,并按需引入依赖、注册组件、触发请求:
import './bootstrap'; require('@fortawesome/fontawesome-free/js/all.js'); import Vue from "vue"; import store from './Store/index' import Vuelidate from 'vuelidate' import BTabs from 'bootstrap-vue' import datePicker from "vue-bootstrap-datetimepicker"; // 全局注册通用依赖(所有页面都需要的) Vue.use(Vuelidate) Vue.use(datePicker) Vue.use(BTabs) // 获取页面中实际存在的Vue容器 const vueContainers = document.querySelectorAll(".my-component-class-wrapper"); vueContainers.forEach(container => { const containerId = container.id; // 读取页面配置的自定义属性 const requiredComponents = container.dataset.requiredComponents.split(','); const useVuetify = container.dataset.useVuetify === 'true'; const needFetchProducts = container.dataset.fetchProducts === 'true'; // 动态构建当前页面需要的组件 const components = {}; requiredComponents.forEach(compName => { switch(compName.trim()) { case 'cartComponent': components.cartComponent = () => import(/* webpackPrefetch: true */"./components/cartComponent"); break; case 'addToCart': components.addToCart = () => import('./components/addToCart'); break; case 'cart': components.cart = () => import('./components/Cart'); break; case 'info': components.info = () => import('./components/Info'); break; } }); // 基础Vue实例配置 const vueOptions = { el: `#${containerId}`, store, components, data: {}, validations: {} }; // 按需加载Vuetify if (useVuetify) { import('./vuetify.js').then(({ default: vuetify }) => { vueOptions.vuetify = vuetify; import('vuetify/dist/vuetify.min.css'); initVue(vueOptions, needFetchProducts); }); } else { initVue(vueOptions, needFetchProducts); } }); // 通用Vue实例初始化函数 function initVue(options, fetchProducts) { // 按需添加数据请求逻辑 if (fetchProducts) { options.created = async function() { try { await store.dispatch('fetchProducts'); } catch (error) { console.error(error); } }; } new Vue(options); }
3. 优化效果说明
- 不再创建不存在的Vue实例,彻底解决"Cannot find element"报错
- Vuetify仅在需要的页面异步加载,减少初始加载的JS/CSS体积
- 仅在需要的页面触发
fetchProducts请求,降低服务器和前端资源消耗 - 组件按需注册,配合webpack懒加载,进一步优化页面加载速度
内容的提问来源于stack exchange,提问作者Naim R.
相关产品推荐
相关产品推荐

