面试官:前端实现图片懒加载怎么做?这不是撞我怀里了嘛!

2024-06-10 00:36

本文主要是介绍面试官:前端实现图片懒加载怎么做?这不是撞我怀里了嘛!,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前端懒加载(也称为延迟加载或按需加载)是一种网页性能优化的技术,主要用于在网页中延迟加载某些资源,如图片、视频或其他媒体文件,直到它们实际需要被用户查看或交互时才进行加载。这种技术特别适用于长页面或包含大量媒体资源的页面,因为它可以显著提高页面加载速度,减少用户等待时间,并降低服务器负载。

懒加载的原理为基于视口(viewport)的概念,即用户当前在屏幕上可见的区域。当页面加载时,只有视口内的资源会被立即加载,而视口外的资源则会被延迟加载。当用户滚动页面或触发其他交互行为时,视口外的资源才会根据需要被加载。

懒加载的优点:

  • 提高页面加载速度:由于只加载视口内的资源,页面初始加载时间大大减少。
  • 节省带宽和服务器资源:减少不必要的资源加载,降低服务器负载和带宽消耗。
  • 提升用户体验:减少用户等待时间,使页面更加流畅和响应迅速。

那么实现懒加载的方式有哪些呢?本文主要从原生、vue、react角度来说一下实现懒加载的常见方法!

一、原生的loading属性

loading 属性指定浏览器是应立即加载图像还是延迟加载图像。现代浏览器已经开始支持img标签的loading属性。设置 loading=“lazy” 只有鼠标滚动到该图片所在位置才会显示。

loading的属性值有eager和lazy,默认值为eager,表示图像立即加载;lazy表示图像延迟加载,只有鼠标滚动到该图片所在位置才会显示。

<img src="/images/paris.jpeg" alt="Paris" loading="lazy">
<img src="/images/nature.jpeg" alt="Nature" loading="lazy">

这是实现懒加载最简单的方法,无需额外的JavaScript代码。

二、Intersection Observer API

Intersection Observer API(交叉观察器 API)提供了一种异步检测目标元素与祖先元素或顶级文档的视口相交情况变化的方法。

过去,要检测一个元素是否可见或者两个元素是否相交并不容易,很多解决办法不可靠或性能很差。然而,随着互联网的发展,这种需求却与日俱增,比如,在页面滚动时“懒加载”图像或其他内容这些情况都需要用到相交检测。

const io = new IntersectionObserver(callback, option);

IntersectionObserver是浏览器原生提供的构造函数,接受两个参数:callback是可见性变化时的回调函数,option是配置对象(该参数可选)。

构造函数的返回值是一个观察器实例。实例的observe方法可以指定观察哪个 DOM 节点。

// 开始观察
io.observe(document.getElementById('example'));// 停止观察
io.unobserve(element);// 关闭观察器
io.disconnect();

上面代码中,observe的参数是一个 DOM 节点对象。如果要观察多个节点,就要多次调用这个方法。

io.observe(elementA);
io.observe(elementB);

**callack参数:**目标元素的可见性变化时,就会调用观察器的回调函数callback。

一般会触发两次:(1)目标元素刚刚进入视口(开始可见);(2)完全离开视口(开始不可见)。

callback函数的参数是一个数组,每个成员都是一个IntersectionObserverEntry对象。

**IntersectionObserverEntry 对象:**提供目标元素的信息,一共有六个属性。

  • time:可见性发生变化的时间,是一个高精度时间戳,单位为毫秒。
  • target:被观察的目标元素,是一个 DOM 节点对象。
  • rootBounds:根元素的矩形区域的信息,getBoundingClientRect()方法的返回值,如果没有根元素(即直接相对于视口滚动),则返回null。
  • boundingClientRect:目标元素的矩形区域的信息。
  • isIntersecting: 布尔值,目标元素与交集观察者的根节点是否相交(常用)。
  • intersectionRect:目标元素与视口(或根元素)的交叉区域的信息。
  • intersectionRatio:目标元素的可见比例,即intersectionRect占boundingClientRect的比例,完全可见时为1,完全不可见时小于等于0。

所以可以通过判断isIntersecting属性是否为true来判断元素的可见性。

对于需要懒加载的图片,使用data-src代替src。

<img data-src="image.jpg" alt="description">
document.addEventListener("DOMContentLoaded", function() {const images = document.querySelectorAll('img[data-src]');const loadImage = function(image) {image.setAttribute('src', image.getAttribute('data-src'));image.onload = function() {image.removeAttribute('data-src');}}//使用IntersectionObserver监听元素是否进入可视区域if ('IntersectionObserver' in window) {var observer = new IntersectionObserver(function(items, observer) {items.forEach(function(item) {if (item.isIntersecting) {loadImage(item.target);observer.unobserve(item.target);}});}, {threshold: 0.01});images.forEach(function(img) {observer.observe(img);});} else {//不支持IntersectionObserver,直接加载所有图片images.forEach(function(img) {loadImage(img);});}
});

四、事件监听+getBoundingClientReact()

旧版本的浏览器可能不支持Intersection ObserverAPI,此时可以用 getBoundingClientRect 和事件监听结合来实现。

Element.getBoundingClientRect() 方法返回一个 DOMRect 对象,其提供了元素的大小及其相对于视口的位置。

返回值是一个 DOMRect 对象,是包含整个元素的最小矩形(包括 padding 和 border-width)。该对象使用 left、top、right、bottom、x、y、width 和 height 这几个以像素为单位的只读属性描述整个矩形的位置和大小。除了 width 和 height 以外的属性是相对于视图窗口的左上角来计算的。

在这里插入图片描述

const rectObject = object.getBoundingClientRect()

因此,当rectObject.top的值处于0-视口高度,则元素处于可视区。即

getBoundingClientRect(ele).top >= 0 && getBoundingClientRect(ele).top <= offsetHeight

实现如下:

function isElementInviewport(el) {const rect = el.getBoundingClientRect();return (rect.bottom >= 0 &&rect.right >= 0 &&rect.top <= (window.innerHeight || document.documentElement.clientHeight) && rect.left <= (window.innerwidth || document.documentElement.clientWidth);)
}function checkLazyLoad() {const lazyImages = Array.prototype.slice.call(document.querySelectorAll('img[data-src]'));lazyImages.forEach(function(img) {if (isElementInViewport(img)) {img.src = img.getAttribute('data-src');img.removeAttribute('data-src');}});if (lazyImages.length === 0) { //如果所有懒加载图片都已加载,移除滚动监听window.removeEventListener('scroll', checkLazyLoad);window.removeEventListener('resize', checkLazyLoad);}
}//监听事件
window.addEventListener('scroll', checkLazyLoad);
window.addEventListener('resize', checkLazyLoad);
window.addEventListener('DOMContentLoaded', checkLazyLoad);

五、使用第三方库

许多第三方库可以实现懒加载,例如lazysizes 和lozad.js。

以下是使用 lazysizes 库的示例:

首先,你需要引入lazysizes 库。

<script src="lazysizes.min.js" async=""></script>

然后修改你的标签,增加lazyload 类和data-src 属性来取代 src即可。

<img data-src="image.jpg" class="lazyload" alt="image" />

Iazysizes 库会自动处理剩下的工作。

六、vue中使用vue-lazyload

在Vue中vue-lazyload插件用的比较多。

首先,安装vue-lazyload:

npm install vue-lazyload--save

接着在你的Vue项目中引入并使用vue-lazyload:

// main.js
import Vue from 'vue'
import App from './App.vue'
import VueLazyload from 'vue-lazyload'
Vue.use(VueLazyload)

//或者添加选项,例如加载时的占位图或加载失败时的图像

Vue.use(VueLazyload, {preLoad: 1.3,error: 'error.png',loading: 'loading.gif',attempt: 1
})
new Vue({render: h => h(App)
}).$mount('#app')

然后在组件中使用v-lazy指令来替换src属性:

<img v-lazy="imgUrl" alt="image">

七、React中的lazy函数

React项目中,你可以使用React自带的lazy函数结合Suspense组件来实现图片懒加载。

React.lazy目前仅支持默认导出(default exports)如果要加载的组件使用了命名导出,你需要一个中间模块来重新导出它为默认模块。

首先,你需要创建一个懒加载组件来包装图片:

// LazyImage.jsx
import React from'react';
const LazyImage = ({ src, alt }) => {return(<img src={src} alt={alt} />);
};
export default LazyImage;

然后使用React.lazy来动态导入这个组件:

// App.js 或者其他父组件
import React, { Suspense } from 'react';
const LazyImage = React.lazy(() => import('./LazyImage'));
// 懒加载组件
const App = () =>{return (<div><Suspense fallback={<div>Loading...</div>}>{/* 在Suspense组件中渲染懒加载的组件 */}<LazyImage src="image.jpg" alt="图片描述"/></Suspense></div>);
};
export default App;

Suspense 组件允许你在等待加载时显示一个加载指示器(例如上面的

Loading…
)。

总结

注意事项

  • 兼容性:不同的浏览器和设备对懒加载的支持程度不同,需要确保所选用的懒加载方案具有良好的兼容性。
  • 用户体验:懒加载不应该影响用户的正常浏览和操作。例如,在图片加载过程中,可以显示占位符或加载提示,以增加用户的等待体验。
  • SEO优化:虽然懒加载可能会对SEO造成一定影响,但可以通过合理的策略来优化。例如,确保关键内容和链接在初始加载时即可被搜索引擎索引。

应用场景

  • 长页面和图片密集型网站:如新闻网站、社交媒体、电商网站等,这些网站通常包含大量的图片和长页面,采用懒加载可以显著提高页面性能和用户体验。
  • 视频和音频资源丰富的网站:如视频分享网站、音乐平台等,这些网站的视频和音频资源占用大量带宽和服务器资源,采用懒加载可以有效降低服务器负载和带宽消耗。
  • 移动设备优化:移动设备的网络环境通常较差,采用懒加载可以减少用户的流量消耗和等待时间,提升用户体验。

总之,懒加载技术广泛应用于各类网站和应用中,特别是长页面、图片密集的网站、电商网站、新闻网站等。在这些场景中,懒加载技术可以显著提高页面性能和用户体验。

这篇关于面试官:前端实现图片懒加载怎么做?这不是撞我怀里了嘛!的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1046752

相关文章

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉,那么对 shallowRef 和 shallowReactive 是否了解呢? 在编程和数据结构中,“shallow”(浅层)通常指对数据结构的最外层进行操作,而不递归地处理其内部或嵌套的数据。这种处理方式关注的是数据结构的第一层属性或元素,而忽略更深层次的嵌套内容。 1. 浅层与深层的对比 1.1 浅层(Shallow) 定义

AI绘图怎么变现?想做点副业的小白必看!

在科技飞速发展的今天,AI绘图作为一种新兴技术,不仅改变了艺术创作的方式,也为创作者提供了多种变现途径。本文将详细探讨几种常见的AI绘图变现方式,帮助创作者更好地利用这一技术实现经济收益。 更多实操教程和AI绘画工具,可以扫描下方,免费获取 定制服务:个性化的创意商机 个性化定制 AI绘图技术能够根据用户需求生成个性化的头像、壁纸、插画等作品。例如,姓氏头像在电商平台上非常受欢迎,

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

W外链微信推广短连接怎么做?

制作微信推广链接的难点分析 一、内容创作难度 制作微信推广链接时,首先需要创作有吸引力的内容。这不仅要求内容本身有趣、有价值,还要能够激起人们的分享欲望。对于许多企业和个人来说,尤其是那些缺乏创意和写作能力的人来说,这是制作微信推广链接的一大难点。 二、精准定位难度 微信用户群体庞大,不同用户的需求和兴趣各异。因此,制作推广链接时需要精准定位目标受众,以便更有效地吸引他们点击并分享链接

【 html+css 绚丽Loading 】000046 三才归元阵

前言:哈喽,大家好,今天给大家分享html+css 绚丽Loading!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦 💕 目录 📚一、效果📚二、信息💡1.简介:💡2.外观描述:💡3.使用方式:💡4.战斗方式:💡5.提升:💡6.传说: 📚三、源代码,上代码,可以直接复制使用🎥效果🗂️目录✍️

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

电脑桌面文件删除了怎么找回来?别急,快速恢复攻略在此

在日常使用电脑的过程中,我们经常会遇到这样的情况:一不小心,桌面上的某个重要文件被删除了。这时,大多数人可能会感到惊慌失措,不知所措。 其实,不必过于担心,因为有很多方法可以帮助我们找回被删除的桌面文件。下面,就让我们一起来了解一下这些恢复桌面文件的方法吧。 一、使用撤销操作 如果我们刚刚删除了桌面上的文件,并且还没有进行其他操作,那么可以尝试使用撤销操作来恢复文件。在键盘上同时按下“C

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象