懒加载
路由懒加载
const routes = [
{
path: "/",
name: "Home",
// 使用 const 的动态 import 语法进行懒加载
component: () =>
import(/* webpackChunkName: "home" */ "../components/Home.vue"),
},
// 其他路由定义
];
异步组件加载
在 Vue.js@3 中,可以使用异步组件来实现按需加载。异步组件是通过 defineAsyncComponent
函数创建的,该函数接受一个返回 Promise
的函数。当组件需要渲染时,Vue.js 将执行该函数并等待 Promise
解析,然后加载组件。
// 异步加载的组件
const AsyncComponent = () => import("./AsyncComponent.vue");
// 使用 defineAsyncComponent 创建异步组件
const MyAsyncComponent = defineAsyncComponent(AsyncComponent);
// 在组件定义中使用异步组件
export default {
components: {
MyAsyncComponent,
},
// 其他组件配置
};
此外,可以在 defineAsyncComponent
中请求数据,再渲染组件:
const AsyncComp = defineAsyncComponent(() => {
return new Promise((resolve, reject) => {
// ...从后端获取组件
resolve(/* 获取到的组件 */);
});
});
甚至还可以使用高级配置去自定义:
const AsyncComp = defineAsyncComponent({
// 加载函数
loader: () => import("./Component.vue"),
// 加载异步组件时使用的组件
loadingComponent: LoadingComponent,
// 展示加载组件前的延迟时间,默认为 200ms
delay: 2000,
// 加载失败后展示的组件
errorComponent: ErrorComponent,
// 如果提供了一个 timeout 时间限制,超时也会显示这里配置的 error 组件,默认值是:Infinity
timeout: 3000,
});
// 在加载组件显示之前有一个默认的 200ms 延迟——这是因为在网络状况较好时,加载完成得很快,加载组件和最终组件之间的替换太快可能产生闪烁,反而影响用户感受。
// 如果提供了一个报错组件,则它会在加载器函数返回的 Promise 抛错时被渲染。
异步组件也可以同时与路由懒加载结合使用。在路由定义中,使用 component: () => import(/* chunkName: "chunk-name" */ './YourComponent.vue')
进行异步加载。
图片懒加载
图片懒加载可以推迟加载页面上的图片,只有在它们进入可视区域时才加载。getBoundingClientRect
是一个用于获取元素在视口中位置信息的方法,利用这个方法可以实现图片的懒加载。
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Lazy Loading Images</title>
<style>
img {
width: 100%;
height: auto;
display: block;
margin-bottom: 20px;
transition: opacity 0.5s;
}
img.loading {
opacity: 0;
}
</style>
</head>
<body>
<div style="height: 1000px;"></div>
<!-- Placeholder for scrolling -->
<img data-src="image1.jpg" class="lazy-load" alt="Lazy Loaded Image 1" />
<img data-src="image2.jpg" class="lazy-load" alt="Lazy Loaded Image 2" />
<img data-src="image3.jpg" class="lazy-load" alt="Lazy Loaded Image 3" />
<img data-src="image4.jpg" class="lazy-load" alt="Lazy Loaded Image 4" />
<script>
document.addEventListener("DOMContentLoaded", function () {
const lazyImages = document.querySelectorAll(".lazy-load");
function lazyLoad() {
lazyImages.forEach(image => {
if (isInViewport(image) && image.classList.contains("loading")) {
image.src = image.dataset.src;
image.classList.remove("loading");
}
});
}
function isInViewport(element) {
const rect = element.getBoundingClientRect();
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <=
(window.innerHeight || document.documentElement.clientHeight) &&
rect.right <=
(window.innerWidth || document.documentElement.clientWidth)
);
}
window.addEventListener("scroll", lazyLoad);
document.addEventListener("DOMContentLoaded", lazyLoad);
// Optional: Add a fade-in effect when images are loaded
lazyImages.forEach(image => {
image.addEventListener("load", () => {
image.style.opacity = 1;
});
});
});
</script>
</body>
</html>
此外,还有浏览器提供的 decoding="async"
和 loading="lazy"
这两个属性。decoding
属性用于指定浏览器在解码图片时的行为。具体来说,decoding="async"
告诉浏览器异步解码图像,即在图像下载完成后,浏览器会在后台进行解码,而不会阻塞页面渲染;
<img src="image.jpg" alt="Description" decoding="async" />
而loading
属性用于控制图像的加载行为,其中 loading="lazy"
表示懒加载。当设置为 lazy
时,浏览器会推迟加载图像,直到它们进入可视范围内。
<img src="image.jpg" alt="Description" loading="lazy" />
<!-- 可以同时使用 -->
<img src="image.jpg" alt="Description" decoding="async" loading="lazy" />
不过,目前这两个属性存在着浏览器的兼容性问题,不同的浏览器对其支持程度有所不同。
资源预加载
- prefetch
prefetch 是一种让浏览器在空闲时间内预加载资源的指令,用于在浏览器空闲时提前加载未来可能会被导航到的资源,例如页面、脚本或样式文件。它会在浏览器后台异步地下载指定的资源,并存储在浏览器缓存中,以备将来使用。
<link rel="prefetch" href="next-page.html" />
- preload
preload
是一种在当前页面加载时立即加载指定资源的指令。它将关键资源放置在浏览器下载队列的优先级较高位置,以便尽早下载并应用于当前页面。通过在页面头部添加 preload
标签,可以确保重要的资源,如首屏所需的关键 CSS 文件、JavaScript 文件、字体文件等,会在页面渲染之前就被下载并准备就绪,从而提高页面加载性能。这样,当浏览器开始渲染页面时,这些关键资源已经存在,可以更快地完成页面渲染。
<link rel="preload" href="font.woff2" as="font" type="font/woff2" />
- preconnect
preconnect
通过指示浏览器在后续请求中预先建立到特定域名的连接,从而减少了实际资源请求时建立连接所需的时间。通过在页面中添加 preconnect
标签,能够告诉浏览器哪链接是重要的,从而提前建立连接,加速后续资源的加载过程。
值得注意的是,由于浏览器对同时保持的连接数量有限制,因此 preconnect
设置并不会一直保持,而是在必要时进行。只有在确实需要使用某个域名加载资源时,浏览器才会执行预连接操作。这样可以更有效地利用网络资源,提高页面加载速度。
<link rel="preconnect" href="https://example.com" />
- 在 vue-router 中使用
<template>
<router-link to="/page_1" prefetch>page_1</router-link>
<router-link to="/page_2" preload>page_2</router-link>
</template>