图片懒加载
什么是懒加载?
懒加载也叫做延迟加载或者按需加载 。在长网页中延迟加载暂时未看到的图片数据,能够优化网页性能,提高用户体验 。在较长的网页或应用中,如果图片很多,等待全部图片都被加载出来需要花费较长时间,就会降低用户体验也会导致功能使用受到阻碍,与此同时,用户只能看到可视窗口的那一部分图片数据,还浪费了性能。使用图片的懒加载就可以解决以上问题。
懒加载的优点
- 减少无用资源加载:使用懒加载能够减少服务器的压力和流量并且也减小了浏览器的负担。
- 提升用户体验:同时加载较多图片,可能需要等待的时间较长,这样影响了用户体验,使用懒加载就能减少等待时间从而提高用户体验。
- 防止加载过多图片而影响其他资源文件的加载 :会让网站功能的正常使用受到影响。
懒加载的原理:
因为图片是通过 src 属性进行的加载,所以在对应图片未出现在可视界面的时候,不将图片对应的地址赋值给 src 属性,而是将地址存储在自定义属性 data-xxx 中,当进行滚动后图片出现在可视界面时,通过获取对应图片的自定义属性 data-xxx 的值再赋值给 src 属性进行图片的加载和显示。
懒加载的三种实现方式:
html代码:
<p>
噫吁嚱,危乎高哉!蜀道之难,难于上青天!蚕丛及鱼凫,开国何茫然!尔来四万八千岁,不与秦塞通人烟。西当太白有鸟道,可以横绝峨眉巅。地崩山摧壮士死,然后天梯石栈相钩连。上有六龙回日之高标,下有冲波逆折之回川。黄鹤之飞尚不得过,猿猱欲度愁攀援。青泥何盘盘,百步九折萦岩峦。扪参历井仰胁息,以手抚膺坐长叹。
问君西游何时还?畏途巉岩不可攀。但见悲鸟号古木,雄飞雌从绕林间。又闻子规啼夜月,愁空山。蜀道之难,难于上青天,使人听此凋朱颜!连峰去天不盈尺,枯松倒挂倚绝壁。飞湍瀑流争喧豗,砯崖转石万壑雷。其险也如此,嗟尔远道之人胡为乎来哉!
剑阁峥嵘而崔嵬,一夫当关,万夫莫开。所守或匪亲,化为狼与豺。朝避猛虎,夕避长蛇;磨牙吮血,杀人如麻。锦城虽云乐,不如早还家。蜀道之难,难于上青天,侧身西望长咨嗟!</p>
<p>
噫吁嚱,危乎高哉!蜀道之难,难于上青天!蚕丛及鱼凫,开国何茫然!尔来四万八千岁,不与秦塞通人烟。西当太白有鸟道,可以横绝峨眉巅。地崩山摧壮士死,然后天梯石栈相钩连。上有六龙回日之高标,下有冲波逆折之回川。黄鹤之飞尚不得过,猿猱欲度愁攀援。青泥何盘盘,百步九折萦岩峦。扪参历井仰胁息,以手抚膺坐长叹。
问君西游何时还?畏途巉岩不可攀。但见悲鸟号古木,雄飞雌从绕林间。又闻子规啼夜月,愁空山。蜀道之难,难于上青天,使人听此凋朱颜!连峰去天不盈尺,枯松倒挂倚绝壁。飞湍瀑流争喧豗,砯崖转石万壑雷。其险也如此,嗟尔远道之人胡为乎来哉!
剑阁峥嵘而崔嵬,一夫当关,万夫莫开。所守或匪亲,化为狼与豺。朝避猛虎,夕避长蛇;磨牙吮血,杀人如麻。锦城虽云乐,不如早还家。蜀道之难,难于上青天,侧身西望长咨嗟!</p>
<p>
噫吁嚱,危乎高哉!蜀道之难,难于上青天!蚕丛及鱼凫,开国何茫然!尔来四万八千岁,不与秦塞通人烟。西当太白有鸟道,可以横绝峨眉巅。地崩山摧壮士死,然后天梯石栈相钩连。上有六龙回日之高标,下有冲波逆折之回川。黄鹤之飞尚不得过,猿猱欲度愁攀援。青泥何盘盘,百步九折萦岩峦。扪参历井仰胁息,以手抚膺坐长叹。
问君西游何时还?畏途巉岩不可攀。但见悲鸟号古木,雄飞雌从绕林间。又闻子规啼夜月,愁空山。蜀道之难,难于上青天,使人听此凋朱颜!连峰去天不盈尺,枯松倒挂倚绝壁。飞湍瀑流争喧豗,砯崖转石万壑雷。其险也如此,嗟尔远道之人胡为乎来哉!
剑阁峥嵘而崔嵬,一夫当关,万夫莫开。所守或匪亲,化为狼与豺。朝避猛虎,夕避长蛇;磨牙吮血,杀人如麻。锦城虽云乐,不如早还家。蜀道之难,难于上青天,侧身西望长咨嗟!</p>
<img data-src="1.jpg" alt="">
<img data-src="2.jpg" alt="">
<p>
噫吁嚱,危乎高哉!蜀道之难,难于上青天!蚕丛及鱼凫,开国何茫然!尔来四万八千岁,不与秦塞通人烟。西当太白有鸟道,可以横绝峨眉巅。地崩山摧壮士死,然后天梯石栈相钩连。上有六龙回日之高标,下有冲波逆折之回川。黄鹤之飞尚不得过,猿猱欲度愁攀援。青泥何盘盘,百步九折萦岩峦。扪参历井仰胁息,以手抚膺坐长叹。
问君西游何时还?畏途巉岩不可攀。但见悲鸟号古木,雄飞雌从绕林间。又闻子规啼夜月,愁空山。蜀道之难,难于上青天,使人听此凋朱颜!连峰去天不盈尺,枯松倒挂倚绝壁。飞湍瀑流争喧豗,砯崖转石万壑雷。其险也如此,嗟尔远道之人胡为乎来哉!
剑阁峥嵘而崔嵬,一夫当关,万夫莫开。所守或匪亲,化为狼与豺。朝避猛虎,夕避长蛇;磨牙吮血,杀人如麻。锦城虽云乐,不如早还家。蜀道之难,难于上青天,侧身西望长咨嗟!</p>
<p>
噫吁嚱,危乎高哉!蜀道之难,难于上青天!蚕丛及鱼凫,开国何茫然!尔来四万八千岁,不与秦塞通人烟。西当太白有鸟道,可以横绝峨眉巅。地崩山摧壮士死,然后天梯石栈相钩连。上有六龙回日之高标,下有冲波逆折之回川。黄鹤之飞尚不得过,猿猱欲度愁攀援。青泥何盘盘,百步九折萦岩峦。扪参历井仰胁息,以手抚膺坐长叹。
问君西游何时还?畏途巉岩不可攀。但见悲鸟号古木,雄飞雌从绕林间。又闻子规啼夜月,愁空山。蜀道之难,难于上青天,使人听此凋朱颜!连峰去天不盈尺,枯松倒挂倚绝壁。飞湍瀑流争喧豗,砯崖转石万壑雷。其险也如此,嗟尔远道之人胡为乎来哉!
剑阁峥嵘而崔嵬,一夫当关,万夫莫开。所守或匪亲,化为狼与豺。朝避猛虎,夕避长蛇;磨牙吮血,杀人如麻。锦城虽云乐,不如早还家。蜀道之难,难于上青天,侧身西望长咨嗟!</p>
<p>
噫吁嚱,危乎高哉!蜀道之难,难于上青天!蚕丛及鱼凫,开国何茫然!尔来四万八千岁,不与秦塞通人烟。西当太白有鸟道,可以横绝峨眉巅。地崩山摧壮士死,然后天梯石栈相钩连。上有六龙回日之高标,下有冲波逆折之回川。黄鹤之飞尚不得过,猿猱欲度愁攀援。青泥何盘盘,百步九折萦岩峦。扪参历井仰胁息,以手抚膺坐长叹。
问君西游何时还?畏途巉岩不可攀。但见悲鸟号古木,雄飞雌从绕林间。又闻子规啼夜月,愁空山。蜀道之难,难于上青天,使人听此凋朱颜!连峰去天不盈尺,枯松倒挂倚绝壁。飞湍瀑流争喧豗,砯崖转石万壑雷。其险也如此,嗟尔远道之人胡为乎来哉!
剑阁峥嵘而崔嵬,一夫当关,万夫莫开。所守或匪亲,化为狼与豺。朝避猛虎,夕避长蛇;磨牙吮血,杀人如麻。锦城虽云乐,不如早还家。蜀道之难,难于上青天,侧身西望长咨嗟!</p>
<img data-src="3.jpg" alt="">
方法一: 当目标图片的顶部到文档的顶部(包括滚动的距离)的距离小于可视界面+浏览器滚动长度时显示图片。
const imgs = document.querySelectorAll('img'); //获取全部图片元素
const winInner = window.innerHeight; //可视界面的高度
function scrollFun() {
imgs.forEach((img) => {
const imgScrollTop = img.offsetTop; //图片距离文档顶部的距离
const bodyScrollTop = document.body.scrollTop || document.documentElement.scrollTop; //浏览器滚动的长度
if (imgScrollTop < winInner + bodyScrollTop) { //当图片距离文档顶部的距离小于可视界面的高度+浏览器滚动的长度时加载对应的图片
img.setAttribute('src', img.getAttribute('data-src'));
}
})
}
window.onscroll = scrollFun;
方法二: 当目标图片的顶部到可视界面的顶部的距离小于可视界面时显示图片。
const imgs = document.querySelectorAll('img'); //获取全部图片元素
const winInner = window.innerHeight; //可视界面的高度
function scrollFun() {
imgs.forEach((img) => {
const scrollTop = img.getBoundingClientRect().top; //目标图片到可视界面顶部的距离
if (scrollTop < winInner) {
img.setAttribute('src', img.getAttribute('data-src'));
}
})
}
window.onscroll = scrollFun;
方法三: 使用 IntersectionObserver 构造函数,进行交叉观察。callback 函数在观察和不观察的时候都会触发。
//当可视界面滚动到图片区域时调用该回调函数
const imgs = document.querySelectorAll('img'); //获取全部图片元素
const callback = (entries) => { //entries是一个包含全部 img 元素的数组
entries.forEach((entry) => {
if (entry.isIntersecting) { //通过对当前的 img 元素的 isIntersecting 属性来进行判定该图片是否在可视界面区域
const img = entry.target; //通过 target 属性获取到当前的 img 对象
img.setAttribute('src', img.getAttribute('data-src'));
observer.unobserve(img); //当该图片已经加载显示后进行 unobserve 不再进行观察
}
})
}
const observer = new IntersectionObserver(callback); //创建一个 observer 对象
imgs.forEach((img) => {
observer.observe(img); //将全部的 img 都进行观察绑定
})
推荐视频:JavaScript 图片懒加载 - Web前端工程师面试题讲解
PS: 方法一和方法二只要图片经过了可视界面就会反复调用,因此性能不够优化,而方法三在经过 unobserve 解绑观察后就不会再触发,因此性能较高,但是 IntersectionObserver 构造函数具有兼容性的问题。
Vue路由懒加载
一般来说在 router 文件夹中,使用 import 来导入需要的组件,再将该组件运用到对应的路径上。这就会一进页面就加载全部的组件文件,当后续再怎么切换路径也不会再有请求发生。
import Home from '../views/Home.vue';
const routes = [
{
path: '/',
name: 'Home',
component: Home,
}
]
而Vue路由懒加载则是在跳转到指定的路径之前,该路径对应的组件是不进行加载的,也就是不直接使用 import 进行导入,当跳转该路径时再进行加载,这样能够提高用户的体验,也能够保证功能的使用不受阻碍。
const routes = [
{
path: '/about',
name: 'About',
component: () => import('../views/About.vue'),
}
]
推荐视频:什么是路由懒加载?【Vue路由】