JS 图片延迟加载/懒加载
图片延迟加载/懒加载
作用:
保证页面打开的速度(1s之内如果首页打不开就已经算是死亡页面了)
原理:
1.对于首屏内容中的图片:
首先给对应的区域一张默认图片占着位置(默认图需要非常的小, 一般可以维持在5kb以内, 1kb是最好的), 当首屏内容都加载完成后(或者也可以给一个延迟的时间), 我在开始加载真实的图片
2.对于其他屏的图片
也是给一张默认的图片占位, 当滚动条滚动到对应区域的时候, 我们再开始加载真实的图片
数据的异步加载
开始只把前两屏的数据加载绑定出来, 后面的数据不进行处理, 当页面滚动到对应区域的时候在重新请求数据然后绑定渲染数据
单图片懒加载
<!--
* @Author: lemon
* @Date: 2020-09-13 21:44:05
* @LastEditTime: 2020-09-13 22:37:33
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: \React前端准备\CSS基础\异步编程\图片延迟加载.html
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
#box {
margin: 100px;
padding: 30px;
width: 200px;
height: 200px;
border: 10px solid green;
}
img {
display: block;
border: none;
}
.banner {
margin: 10px auto;
width: 300px;
height: 150px;
border: 1px solid green;
background: url("../../img/default.gif") no-repeat center center;
}
.banner img {
display: none; /*在开始的时候IMG的SRC属性没有地址, 这样的话再IE浏览器中容器中会显示一张碎图,不美观, 所以我们让其默认隐藏, 当真实图片加载的时候我们再让它显示*/
width: 100%;
height: 100%;
}
</style>
<body>
<div class="banner">
<img id="e" src="" alt="" trueImg="../../img/1.png" />
</div>
</body>
<script>
var timer = window.setInterval(function () {
var img = document.getElementsByTagName("img");
var e = document.getElementById("e");
// e.src = e.getAttribute("trueImg");
// e.style.display = "block";
// 以上处理还是不完整的: 如果我们获取的真实图片地址是错误的, 当赋值给IMG的SRC属性的时候, 不仅控制会报错, 而且页面中也会出现碎图/叉图, 影响视觉效果
// 获取图片的地址, 验证地址的有效性, 是有效的才赋值, 不是有效的是不进行赋值处理的
var oImg = document.createElement("img"); //创建一个临时的IMG标签
oImg.src = e.getAttribute("trueImg");
oImg.onload = function () {
e.src = this.src;
e.style.display = "block";
oImg = null;
console.log("图片加载完成....");
var nowTime = new Date();
console.log("用了", nowTime - time, "毫秒");
};
console.log("图片正在加载中....");
window.clearInterval(timer);
var time = new Date();
}, 1000);
</script>
</html>
网络性能优化
- 尽量减少向服务器请求的次数"减少HTTP请求"
- CSS/JS文件进行合并
- ICON图片进行合并 -> 雪碧图/ css sprite
- 图片的延迟加载
- 数据的异步加载
- 在移动端, 如果是一个"简单的"宣传页, 尽量把CSS和JS写成内嵌式
多张图片懒加载
多张图片懒加载, 当视图窗口第一次移动置图片时图片才开始加载
代码
<!--
* @Author: your name
* @Date: 2020-09-14 08:54:43
* @LastEditTime: 2020-09-14 10:41:40
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: \React前端准备\CSS基础\异步编程\多张图片懒加载.html
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<!-- 做移动端响应式布局页面, 必须要加META标签: viewport -->
<meta
name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scal=1.0, minimum-scale=1.0,initial-scale=1.0"
/>
<title>Document</title>
</head>
<style type="text/css">
* {
margin: 0;
padding: 0;
font-family: "\5FAE\8F6F\96C5\9ED1", Helvetica, sans-serif;
font-size: 14px;
}
ul,
li {
list-style: none;
}
img {
display: block;
border: none;
}
/*最外层容器是不设定固定的宽高的*/
.news {
padding: 10px;
}
.news li {
position: relative;
padding: 10px 0;
height: 60px;
border-bottom: 1px dashed #ccc;
}
.news li > div:nth-child(1) {
position: absolute;
top: 10px;
left: 0;
width: 75px;
height: 60px;
background: url("../../img/default.gif") no-repeat center center;
background-size: 100% 100%;
}
.news li > div:nth-child(1) img {
width: 100%;
height: 100%;
visibility: hidden;
}
.news li > div:last-child {
margin-left: 80px;
height: 60px;
}
.news li > div:last-child h2 {
height: 20px;
line-height: 20px;
/* 实现文字超出一行自动裁切 */
overflow: hidden;
text-overflow: ellipsis; /*裁切的部分以三个省略号代表*/
white-space: nowrap; /*强制不换行*/
}
.news li > div:last-child p {
line-height: 20px;
font-size: 12px;
color: #616161;
}
</style>
<body>
<ul class="news" id="news">
<li>
<div>
<img src="" trueImg="../../img/1.png" alt="" />
</div>
<div>
<h2>要得到你必须要付出,要付出你放弃公平的,,去决定自己生活的样</h2>
<p>要得到你必须要付出,要付出你放弃公平的,,去决定自己生活的样子</p>
</div>
</li>
<li>
<div>
<img src="" trueImg="../../img/2.png" alt="" />
</div>
<div>
<h2>要得到你必须要付出,要付出你放弃公平的,,去决定自己生活的样</h2>
<p>要得到你必须要付出,要付出你放弃公平的,,去决定自己生活的样子</p>
</div>
</li>
<li>
<div>
<img src="" trueImg="../../img/3.png" alt="" />
</div>
<div>
<h2>要得到你必须要付出,要付出你放弃公平的,,去决定自己生活的样</h2>
<p>要得到你必须要付出,要付出你放弃公平的,,去决定自己生活的样子</p>
</div>
</li>
<li>
<div>
<img src="" trueImg="../../img/3.png" alt="" />
</div>
<div>
<h2>要得到你必须要付出,要付出你放弃公平的,,去决定自己生活的样</h2>
<p>要得到你必须要付出,要付出你放弃公平的,,去决定自己生活的样子</p>
</div>
</li>
<li>
<div>
<img src="" trueImg="../../img/3.png" alt="" />
</div>
<div>
<h2>要得到你必须要付出,要付出你放弃公平的,,去决定自己生活的样</h2>
<p>要得到你必须要付出,要付出你放弃公平的,,去决定自己生活的样子</p>
</div>
</li>
<li>
<div>
<img src="" trueImg="../../img/3.png" alt="" />
</div>
<div>
<h2>要得到你必须要付出,要付出你放弃公平的,,去决定自己生活的样</h2>
<p>要得到你必须要付出,要付出你放弃公平的,,去决定自己生活的样子</p>
</div>
</li>
<li>
<div>
<img src="" trueImg="../../img/3.png" alt="" />
</div>
<div>
<h2>要得到你必须要付出,要付出你放弃公平的,,去决定自己生活的样</h2>
<p>要得到你必须要付出,要付出你放弃公平的,,去决定自己生活的样子</p>
</div>
</li>
<li>
<div>
<img src="" trueImg="../../img/3.png" alt="" />
</div>
<div>
<h2>要得到你必须要付出,要付出你放弃公平的,,去决定自己生活的样</h2>
<p>要得到你必须要付出,要付出你放弃公平的,,去决定自己生活的样子</p>
</div>
</li>
<li>
<div>
<img src="" trueImg="../../img/3.png" alt="" />
</div>
<div>
<h2>要得到你必须要付出,要付出你放弃公平的,,去决定自己生活的样</h2>
<p>要得到你必须要付出,要付出你放弃公平的,,去决定自己生活的样子</p>
</div>
</li>
</ul>
</body>
<script>
var imgList = document.getElementsByTagName("img");
function lazyImg(curImg) {
var oImg = document.createElement("img");
oImg.src = curImg.getAttribute("trueImg");
oImg.onload = function () {
curImg.src = this.src;
curImg.style.visibility = "visible";
oImg = null;
};
curImg.isLoad = true;
}
var A = 0;
// 循环处理每一张图片
function handleAllImg() {
for (var i = 0, len = imgList.length; i < len; i++) {
var curImg = imgList[i];
// 当前的图片处理过的话, 就不需要在重新的进行处理了
if (curImg.isLoad) {
continue;
}
// 只有A<B的时候在进行处理: 当前图片是隐藏的, 我们计算的A的值其实是计算它父亲(容器)的值
var curImgPar = curImg.parentNode;
var win = document.documentElement;
// console.log(curImg.offsetHeight, curImgPar.offsetHeight);
var A = curImg.parentNode.parentNode.offsetTop + curImgPar.offsetHeight;
var B = win.clientHeight + win.scrollTop;
if (A < B) {
lazyImg(curImg);
}
}
}
// 开始的时候(过500ms加载第一屏幕的图片), 滚动条滚动的时候加载其他图片
window.setTimeout(handleAllImg, 500);
window.onscroll = handleAllImg;
</script>
</html>