资讯专栏INFORMATION COLUMN

每日 30 秒 ⏱ 巧用可视区域

DevYK / 552人阅读

简介
可视区域、页面优化、DOM节点多、图片懒加载、性能

可视区域是一个前端优化经常出现的名词,不管是显示器、手机、平板它们的可视区域范围都是有限。在这个 有限可视区域 区域里做到完美显示和响应,而在这个区域外少做一些操作来减少渲染的压力、网络请求压力。在 每日 30 秒之 对海量数据进行切割 中的使用场景,我们就是利用了 有限可视区域 只渲染一部分 DOM 节点来减少页面卡顿。

既然 可视区域 这么重要是否有什么速成秘籍来帮我们?

控制住每一个元素在可视区域的出现,就可以扼住命运的后颈为所欲为:

// 该源码来自于 https://30secondsofcode.org
const inViewport = (el, partiallyVisible = false) => {
    const { top, left, bottom, right } = el.getBoundingClientRect();
    const { innerHeight, innerWidth } = window;
    return partiallyVisible
        ? ((top > 0 && top < innerHeight) || (bottom > 0 && bottom < innerHeight)) &&
        ((left > 0 && left < innerWidth) || (right > 0 && right < innerWidth))
        : top >= 0 && left >= 0 && bottom <= innerHeight && right <= innerWidth;
};
代码分析

使用 Element.getBoundingClientRect 方法返回元素的大小及其相对于视口的位置,可以得到当前元素相对 可视区域 的坐标:

const { top, left, bottom, right } = el.getBoundingClientRect();

得到元素的坐标信息后,就需要获得 可视区域 的宽高来帮助我们确定是否在范围内:

const { innerHeight, innerWidth } = window;

先判断是否需要整个元素都出现在 可视区域

if (partiallyVisible) {
    // 只需要出现在可视区域 
} else {
    // 需要整个元素都在可视区域内
}

判断元素头部或者底部是否在 可视区域 出现:

(top > 0 && top < innerHeight) || (bottom > 0 && bottom < innerHeight)

判断元素左部或者右部是否在 可视区域 出现:

(left > 0 && left < innerWidth) || (right > 0 && right < innerWidth)

当需要整个元素都出现在屏幕的时候,需要同时判断四个相对坐标:

top >= 0 && left >= 0 && bottom <= innerHeight && right <= innerWidth
使用场景

现在网页中经常会出现大量的图片,然而加载大量图片会影响网页加载速度,我们可以利用 可视区域 来实现图片的懒加载。为什么要懒加载图片:

大量的图片请求会增加服务器的压力。

使用 CDN 加速来缓解服务器压力例如 七牛云

加速用户的网页加载速度,当图片数量巨大需要占用请求资源和显示速度。

HTTP1 文件限制会对同一个域名限制文件请求数 可以通过 影子域名 来绕过这个限制。

利用 可视区域 当移动到某个 标志元素 时再进行更多数据和图片的加载。

利用占位图片来防止页面塌陷。

用户访问页面有时候只是粗略的一撇。

利用 可视区域 加载部分数据图片节省网络流量。

结构
样式
.img-box {
    width: 200px;
    height: 200px;
    margin: 10px 0 10px 10px;
    background: #eee;
    display: inline-block;
}

.img-box > img {
    width: 100%;
    height: 100%;
}
脚本
document.addEventListener("scroll", lazyLoading)
window.onload = () => lazyLoading()

function lazyLoading() {
    const boxs = document.querySelectorAll(".img-placeholder")

    Array.from(boxs).map(box => {
        if (!inViewport(box, true)) return;

        // 获取图片地址并清除数据记录 
        const src = box.getAttribute("data-src");
        box.removeAttribute("data-src");

        // 插入图片 DOM
        box.innerHTML = ``;

        // 去除占位 class
        box.className = box.className.replace("img-placeholder", "")
    })
}
一起成长
在困惑的城市里总少不了并肩同行的 伙伴 让我们一起成长。

如果您想让更多人看到文章可以点个 点赞

如果您想激励小二可以到 Github 给个 小星星

如果您想与小二更多交流添加微信 m353839115

本文原稿来自 PushMeTop

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/102572.html

相关文章

  • 每日 30 ⏱ 终极等于

    简介 字符串、数字、数组、对象、时间、类型、等于 科学家发现,人脑中会分泌多种能让人感到快乐、安全和成就感的物质,这些物质统称为快乐素。通常情况下,快乐素的释放水平很低,维持我们心情平静。只有当我们完成了预设目标,作为奖励,大脑才会增加快乐素的分泌,让人感受到满足和成功的喜悦。 这是之前看到的一篇关于 大脑奖励机制 文章的一段话,为了要获得奖励我们需要有预设目标,而是每日 30 秒系列也是为了帮助...

    lakeside 评论0 收藏0
  • 每日 30 ⏱ 判断是否为页面底部

    showImg(https://segmentfault.com/img/remote/1460000018771130?w=900&h=500); 简介 分页、优化、可视区域、无限加载 写前端页面时最经常遇到的开发需求之一就是 渲染后端数据返回的数据对象,当数据对象数量极多的时候便需要进行分页。 常见的分页方式有三种: 在页面底部生成 上一页、下一页、页面列表 按钮。 用户可以很直接的选择...

    callmewhy 评论0 收藏0
  • 巧用 Img / JavaScript 采集页面数据

    摘要:日志服务提供就是为解决以上轻量级埋点采集场景而生,我们可以在分钟时间内完成埋点和数据上报工作。服务功能包括实时采集与消费。 摘要: 当我们有一个新内容时(例如新功能、新活动、新游戏、新文章),作为运营人员总是迫不及待地希望能尽快传达到用户,因为这是获取用户的第一步、也是最重要的一步。 点此查看原文:http://click.aliyun.com/m/40929/ 我们发送重要邮件时为...

    sunny5541 评论0 收藏0
  • 巧用 Img / JavaScript 采集页面数据

    摘要:日志服务提供就是为解决以上轻量级埋点采集场景而生,我们可以在分钟时间内完成埋点和数据上报工作。服务功能包括实时采集与消费。 摘要: 当我们有一个新内容时(例如新功能、新活动、新游戏、新文章),作为运营人员总是迫不及待地希望能尽快传达到用户,因为这是获取用户的第一步、也是最重要的一步。 点此查看原文:http://click.aliyun.com/m/40929/ 我们发送重要邮件时为...

    WrBug 评论0 收藏0
  • 每日 30 ⏱ JSON对象数组转换 CSV 表格数据

    简介 数组、对象、CSV、表格、工具 我们在 每日 30 秒之 arrayToCSV 中一起学习了将数组数据转化为 csv 表格数据并导出,那如果是对象数组怎么办呢?小脑袋瓜转得快的同学肯定会说:使用 Array.prototype.map 把需要导出的字段先遍历取出,再使用 arrayToCSV 将其导出为 CSV 数据表格。 可是你有没有想过如果一个对象数组数据非常之大时,使用 Array.p...

    Ajian 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<