Appearance
Image
图片预加载
图片预加载是指在页面加载时提前加载图片,使其缓存在浏览器中,当用户需要查看图片时立即显示,不需要等待加载。
let image = new Image();
image.src = 'image.jpg';
.image {
background-image: url('image.jpg');
}
<link rel="preload" href="image.jpg" as="image">图片懒加载
延迟加载图片,用户滚动到页面上特定位置时才加载图片。
<img data-src="https://xxx.jpg">getBoundingClientRect
const debounceLazyLoad = debounce(imgLoadFn, 100)
window.addEventListener('scroll', debounceLazyLoad)
window.addEventListener('resize', debounceLazyLoad)
imgLoadFn() {
let that = this
let imgGroups = document.getElementsByTagName('img')
let imgGroupLen = imgGroups && imgGroups.length
// 最后一张图片还没加载出来,说明需要懒加载
if (imgGroupLen && imgGroups[imgGroupLen - 1].getAttribute('data-src')) {
for (let i = 0; i < imgGroups.length; i++) {
let imgItem = imgGroups[i] || {}
if (imgItem.getAttribute('data-src')) {
that.loadImg(imgItem)
}
}
}
},
loadImg(el) {
// 获取窗口高度
let docHeight = document.documentElement.clientHeight
let boundingClientRect = el.getBoundingClientRect()
let bottom = boundingClientRect.bottom
let top = boundingClientRect.top
/* 当元素进入窗口时,才加载真实图片
bottom: 元素的下边到窗口上边的距离
top: 元素的上边到窗口上边的距离
*/
if (top < docHeight && bottom > 0) {
el.src = el.dataset.src
el.removeAttribute('data-src')
}
// top >= docHeight || bottom <= 0 // 不可见
}IntersectionObserver
function query(selector) {
return Array.from(document.querySelectorAll(selector))
}
let observer = new IntersectionObserver(function(entries) {
entries.forEach(function(entry) {
// intersectionRatio 图片可见比例 0-1
if (entry.isIntersecting) { // 在视口
let img = entry.target
if (img.dataset.src) {
// dataset.src 就是 获取 "data-src" 属性值
img.src = img.dataset.src
img.removeAttribute('data-src')
// 图片已加载, 解除观察
observer.unobserve(img)
} else {
observer.unobserve(img)
}
}
})
}, { threshold: [0] }) // 0%可见时触发;
// rootMargin: '50px' 提前50px触发
query('img').forEach(function(item) {
// 观察每个图片对象
observer.observe(item)
})第三方插件 vue 的 vue-lazyload
import Vue from 'vue'
import VueLazyload from 'vue-lazyload'
Vue.use(VueLazyload, {
preLoad: 1.3,
error: 'dist/error.png',
loading: 'dist/loading.gif',
attempt: 3 // 默认,尝试加载次数
})
<div v-for="(item, index) in imgList" :key="index">
<img v-lazy="item">
</div>loading="lazy"
loading 是 <img> 和 <iframe>> 标签的新属性,在 <img> 标签上添加 loading="lazy",浏览器就会在图片滚动到视口附近时才开始加载。
<img src="image.jpg" loading="lazy" width="350" height="220" alt="图片">