在本教程中,我将向您展示如何通过使用in-view.js来提高网页的性能。 当某些内容滚动到视口中时,此JavaScript库会向您返回报告,并将帮助我们根据需要动态加载图像。
绩效问题
Web性能很重要,特别是如果您的网站针对连接速度慢且数据计划昂贵的发展中国家。 我们通常承担的改善网站性能的一些基本任务包括缩小JavaScript文件和样式表,“压缩”资产,压缩图像大小,然后我们几乎完成了所有工作。 但是我们呢?
上面的检查器示例显示了一个页面,该页面以固定的3G速度在移动大小的视口中加载24张图像。 正如我们所看到的,页面加载大约在十一秒钟完成! 鉴于我们正在处理一个仅包含少量图像和样式表的简单页面,这确实很慢。 该页面尚未被广告污染,也没有跟踪脚本,这些脚本通常会在页面上添加更多的镇流器。
同样值得记住的是,这仅仅是一个模拟。 它甚至没有考虑服务器设置,延迟和其他技术障碍。 在现实中,性能可能会变差。
那么如何改善页面加载性能呢?
瓶颈
首先,我们有很多图像。 我们页面加载缓慢的原因是,在初始页面加载时所有图像都一起泛滥。 如果您仔细查看上一张图像,您会发现并不会并行发生:只有在渲染了其他图像之后,才开始加载几个图像,这会使整个页面陷入瘫痪。
如果单个页面上有大量图像,则可以考虑异步加载这些图像,并且仅在用户需要它们时才加载。 这使浏览器可以完成加载可见页面,而无需等待所有图像都被渲染,最终节省了用户带宽。
入门
要继续学习,请从repo中获取index-starter.html 。 还有一个随附的css / styles-starter.css,您也可以使用。
首先,我们需要用非常小的图像替换图像源, 最好将其编码为base64以避免任何额外的HTTP请求。 在提供实际图像之前,我们将此图像用作占位符。 话虽如此,我们还必须将实际图像源存储在名为data-src的自定义属性中。
<figure class="post__image">
<img src="https://img-blog.csdnimg.cn/2022010702040617771.gif" data-src="./images/image-24.jpg" alt="" width="800" height="554">
</figure>
完成此操作并刷新页面后,您应该发现图像当前为空白,并且其尺寸不一定就是最终图像应具有的尺寸。
因此,让我们修复样式。
保持图像比例
我们要使用的图像设置为800 x 550像素。 我们将图像高度( 800px )除以图像宽度( 500px ),然后乘以100% 。 使用结果来设置图像容器的伪元素的padding top 。 最后,我们需要将图像位置设置为absolute位置,并将最大高度设置为100% ,这样就不会增加高度。
figure {
position: relative;
}
figure img {
top: 0;
left: 0;
position: absolute;
max-height: 100%;
}
figure:before {
padding-top: 69.25%; // ( 554 / 800 ) * 100%
}
此时,图像尺寸应该正确。 但是,真实的图像源仍然位于自定义属性中,因此浏览器实际上还无法获取任何图像。
我们的下一步将添加一些将加载图像JavaScript。
加载图像
首先,我们需要将in-view.js加载到页面中。 如前所述,此轻量级库(不依赖jQuery或Waypoints等核心库)可检测元素是在浏览器视口内还是在视口外。
现在创建一个新JavaScript文件,我们将在其中编写我们JavaScript并将其加载到in-view.js中,如下所示:
<script src="./js/in-view.min.js"></script>
<script src="./js/scripts.js"></script>
方法与功能
in-view.js库公开了inView()函数,该函数以选择器作为参数。 在这种情况下,我们将传递figure元素; 包装图片的元素。 选择wrapper元素的原因是因为我们将添加几个类来执行样式转换-当类位于wrapper元素而不是图像本身上时,这更容易实现,因此:
inView('figure')
接下来,我们使用.on()方法将元素与enter事件绑定,以检查元素是否在视口内。 另外,in-view.js还公开了exit事件,其作用与此相反。 这将检测元素何时不在视口中。
inView( 'figure' ).on( 'enter', function( figure ) {
var img = figure.querySelector( 'img' ); // 1
if ( 'undefined' !== typeof img.dataset.src ) { // 2
figure.classList.add( 'is-loading' ); // 3
// 4
newImg = new Image();
newImg.src = img.dataset.src;
newImg.addEventListener( 'load', function() {
figure.innerHTML = ''; // 5
figure.appendChild( this );
// 6
setTimeout( function() {
figure.classList.remove( 'is-loading' );
figure.classList.add( 'is-loaded' );
}, 300 );
} );
}
} );
enter事件将触发一个函数,该函数将执行以下操作:
- 在
figure选择图像。 - 确保它具有
data-src属性。 - 将
is-loading添加到包装器figure元素。 - 使用从
data-src属性检索到的源加载新图像。 - 加载后,将图像添加到容器中。
- 最后,将
is-loading类替换为is-loaded类。
我们想加载
从上面的代码中可以看到,我们引入了两个新的类is-loading和is-loaded 。 我们使用is-loading类在图像加载时添加微调器动画。 顾名思义,然后使用is-loaded类在图像完全加载后向图像添加过渡效果。
figure.is-loaded img {
animation: fadeIn 0.38s linear 1s forwards;
}
figure.is-loading {
position: relative;
}
figure.is-loading:after {
content: '';
display: block;
color: #ddd;
font-size: 30px;
text-indent: -9999em;
overflow: hidden;
width: 1em;
height: 1em;
border-radius: 50%;
margin: auto;
position: absolute;
top: 50%;
left: 50%;
margin-left: -0.5em;
margin-top: -0.5em;
transform: translateZ(0);
animation: loading 1.7s infinite ease;
}
@keyframes loading {
0% {
transform: rotate(0deg);
box-shadow: 0 -0.83em 0 -0.4em, 0 -0.83em 0 -0.42em, 0 -0.83em 0 -0.44em, 0 -0.83em 0 -0.46em, 0 -0.83em 0 -0.477em;
}
5%,
95% {
box-shadow: 0 -0.83em 0 -0.4em, 0 -0.83em 0 -0.42em, 0 -0.83em 0 -0.44em, 0 -0.83em 0 -0.46em, 0 -0.83em 0 -0.477em;
}
10%,
59% {
box-shadow: 0 -0.83em 0 -0.4em, -0.087em -0.825em 0 -0.42em, -0.173em -0.812em 0 -0.44em, -0.256em -0.789em 0 -0.46em, -0.297em -0.775em 0 -0.477em;
}
20% {
box-shadow: 0 -0.83em 0 -0.4em, -0.338em -0.758em 0 -0.42em, -0.555em -0.617em 0 -0.44em, -0.671em -0.488em 0 -0.46em, -0.749em -0.34em 0 -0.477em;
}
38% {
box-shadow: 0 -0.83em 0 -0.4em, -0.377em -0.74em 0 -0.42em, -0.645em -0.522em 0 -0.44em, -0.775em -0.297em 0 -0.46em, -0.82em -0.09em 0 -0.477em;
}
100% {
transform: rotate(360deg);
box-shadow: 0 -0.83em 0 -0.4em, 0 -0.83em 0 -0.42em, 0 -0.83em 0 -0.44em, 0 -0.83em 0 -0.46em, 0 -0.83em 0 -0.477em;
}
}
@keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
倒退
希望有最好的,但要有最坏的打算。 因此,以防万一JavaScript被禁用(一种罕见的情况,但完全有可能),我们需要确保图像仍会显示。 在图像源立即指向真实图像源的情况下使用<noscript>元素。
<figure>
<img src="https://img-blog.csdnimg.cn/2022010702040617771.gif" data-src="./images/image-24.jpg" alt="" width="800" height="554">
<noscript>
<img src="./images/image-24.jpg" alt="" width="800" height="554">
</noscript>
</figure>
我们都准备好了! 刷新页面,如果我们在DevTools中检查网络时间轴,则可以看到页面速度现在得到了显着提高,因为我们只加载了用户可见的内容。
现在,以常规3G速度完成的页面加载仅需1.95秒。 速度提高了500%以上!
结语
在本教程中,我们研究了如何仅在用户看到图像时才渲染图像来改善页面加载。 这种方法俗称“延迟加载”,可以极大地帮助您提高网站性能。
有许多JavaScript库和jQuery插件可以执行此操作,那么为什么选择in-view.js? 就个人而言,in-view.js一直是我一直在寻找的脚本,因为它不会做太多事情。 它只会处理一件事,并且做得很好。 这种库提供了更多的控制权和更大的灵活性。
举例来说,我们不仅可以在-view.js用于执行延迟加载,但是我们也可以用它的东西,如进行无限滚动 ,或许显示浮动当用户到达页面的最后认购表格( 起飞观看演示以了解实际效果),或者创建垂直时间轴而无需引入另一个JavaScript库。 让我们知道您如何使用它!
514



被折叠的 条评论
为什么被折叠?



