图片懒加载学习

82 阅读3分钟

哈喽哈喽这里是小菜不拖延博主,距离博主上次更新已经好久好久,实在是懈怠,最近一定要捡起来开始新一段的前端优化之旅辣

懒加载学习

知识点

这里将会总结本文所有的陌生知识点(当然只是针对)

# 自定义属性data-***命名可以通过dataset获取该属性
<div id='test' data-test='test'>
栗子:var arr =document.getElementById('test').dataset.test

# `getBoundingClientRect()` 是一个 DOM API 方法,用于获取元素的位置和尺寸信息。它返回一个 `DOMRect` 对象,他这里的属性值都是相对于当前视图窗口,包含了以下属性:
1.  `x`(或 `left`):元素相对于视口左边缘的水平偏移量。
1.  `y`(或 `top`):元素相对于视口顶部边缘的垂直偏移量。
1.  `width`:元素的宽度。
1.  `height`:元素的高度。
1.  `right`:元素相对于视口左边缘的右侧位置。
1.  `bottom`:元素相对于视口顶部边缘的底部位置。

img自带属性loading

搜索的时候发现img标签自带loading属性,

  • "lazy"(默认):表示图像使用延迟加载。图像仅在它们进入可视区域附近时才会开始加载。这可以提高页面的加载性能和响应速度。懒加载图像通常通过滚动监听等技术来动态触发加载。
  • "eager":表示图像应立即加载,而不考虑用户是否看得到它们。这可以用于确保关键图像或重要内容的立即显示。

基础版

阅读[:](懒加载和预加载 - 掘金 (juejin.cn)l)

懒加载的逻辑就是:我请求到资源之后,我不一次性渲染,只有当图片出现在我视图的区域的时候我才进行渲染,这样可以提高用户的使用体验,不至于一次性渲染过多的资源而出现问题。

所以我需要做的是以下步骤:

  • 获取所有需要懒加载的图片元素
  • 每个图片需要判断是否在视图框内(使用getBoundingClientRect())
  • 在视图框内就赋值src,进行加载
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Lazyload</title>
    <style>
        .image-item {
            display: block;
            margin-bottom: 50px;
            height: 200px;
        }
    </style>
</head>

<body>
    <img src="" class="image-item" lazyload="true"
        data-original='https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg' />
    <img src="" class="image-item" lazyload="true"
        data-original='https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg' />
    <img src="" class="image-item" lazyload="true"
        data-original='https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg' />
    <img src="" class="image-item" lazyload="true"
        data-original='https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg' />
    <img src="" class="image-item" lazyload="true"
        data-original='https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg' />
    <img src="" class="image-item" lazyload="true"
        data-original='https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg' />

    <script>
        var viewHeight = document.body.clientHeight//获取可视区高度
        //document.body.clientHeight 
        console.log('viewHeight',viewHeight)
        function lazyload() {
            var eles = document.querySelectorAll('img[data-original][lazyload]')
            Array.prototype.forEach.call(eles, function (item, index) {
                var rect
                if (item.dataset.original === "")
                    return
                rect = item.getBoundingClientRect()// 用于获得页面中某个元素的左,上,右和下分别相对浏览器视窗的位置
                if (rect.bottom >= 0 && rect.top < viewHeight) {
                    !function () {
                        item.src=item.dataset.original
                        console.log('item',item)
                        item.removeAttribute("data-original")//移除属性,下次不再遍历
                        item.removeAttribute("lazyload")
                    }
                }
            })
        }
        lazyload()//刚开始还没滚动屏幕时,要先触发一次函数,初始化首页的页面图片
        document.addEventListener("scroll", lazyload)
    </script>
</body>

</html>

代码当中需要注意的地方:

  • 进入页面需要先加载首屏
  • 每一次遍历完图片加载之后,由于图片已经被加载过了,所以我们没有必要进行不断地遍历,在图片数量少的时候看不出来,若数量很大,这样没有处理过的不断遍历肯定会影响性能,所以注意代码当中处理的部分(我觉得挺巧妙的,利用属性选择器进行选择,同时属性也能存储图片的地址)