Vue加载优化
sq-web 人气:01、路由懒加载
问题: 项目在打包时会将首页与其他页面的资源打包到同一个资源文件,造成首页加载的资源文件过大。
解决方法: 路由懒加载:打包时会将每个路由页面拆分成单独的 js 资源,同时跳转到对应页面才会加载对应路由的 js 资源。
{ path: "/about", name: "about", component: () => import(/* webpackChunkName: "about" */ "../views/AboutView.vue"), },
2、js 资源异步加载
问题: 在开发项目的时候,可能会在入口文件加载很多的第三方 js 资源。类似下面这种:
解决方法: 为处理这种入口文件多余的js,下面介绍三种方式。
1)支持异步加载的可以将js资源设置为异步加载。
async:
异步加载js,js加载完后立即执行,多个js执行顺序不固定。
defer:
异步加载js,解析 document后,按js文件顺序以此执行。
<script type="text/javascript" src="./js/testPage.js" async></script> //或 <script type="text/javascript" src="./js/testPage.js" defer></script>
2)符合ES Module 规范的资源,可以采用import异步载入。
在需要使用的页面异步引入,就不用在入口文件加载了:
import("xxx.js").then((module) => { console.log(module); });
3)其他规范的js可以采用异步添加script
标签的方式载入。
// 异步加载js文件 function loadjs(url) { return new Promise((resolve, reject) => { let secScript = document.createElement('script') secScript.setAttribute('type', 'text/javascript') secScript.setAttribute('src', url) let loaded = false document.body.insertBefore(secScript, document.body.lastChild) try { secScript.onload = secScript.onreadystatechange = () => { if ( !loaded && (!secScript.readyState || /loaded|complete/.test(secScript.readyState)) ) { loaded = true resolve() } } } catch (error) { reject(error) } }) } // 页面调用 let url = 'http://xxx.js' loadjs(url) .then(() => { // 加载成功后的处理 }) .catch((e) => { // 加载错误 })
3、图片懒加载
问题: 首页在加载时,加载了还没有进入视野的图片资源。
解决方法: 图片懒加载原理都差不多,这里使用一个叫VueLazyComponent
组件,方便与后面的组件分包懒加载一起使用。其内部实现就是一个带插槽的公共组件,进入视野后再加载资源,有兴趣的可以自行去看源码。传送门
使用方式很简单,这样等图片进入视野后才会加载图片资源:
// main.js import VueLazyComponent from "@xunlei/vue-lazy-component"; Vue.use(VueLazyComponent);
// 业务页面内 <vue-lazy-component> <img src="../assets/test.png" alt="" /> </vue-lazy-component>
4、组件分包懒加载-在视口才加载
问题: 有时候首页可能包含很多的组件,导致打包后的页面资源过大。
解决方法: 可以考虑对组件分包,然后懒加载。
1)组件分包
其实与路由懒加载类似,就是异步引入组件,这一步操作后,每个异步引入的组件会被打包成单独的资源文件。
export default { name: "HomeView", components: { TestCom: () => import(/* webpackChunkName: "TestCom" */ `@/components/TestCom.vue`), }, };
2)组件被分包后,可以对其进行懒加载。
首页组件太多,我们希望是页面底部等一些不在视野内的组件资源,进入视野后再加载。实现原理同上面的图片懒加载。
<vue-lazy-component> <template scope="scope"> <TestCom v-if="scope.loading"></TestCom> </template> </vue-lazy-component>
加载全部内容