javascript加载
When building a web application, we are always looking for the best performance in order not to impact user experience.
在构建Web应用程序时,我们一直在寻找最佳性能,以便不影响用户体验。
Among all the techniques to improve web performance of a website, lazy loading of images allows us to defer image retrieval. Indeed, according to the dimensions, the compression, and the quality of the images, it may impact the size of the bundle downloaded by the user’s device. Therefore, deferring these downloads offers several advantages:
在改善网站Web性能的所有技术中,图像的延迟加载使我们可以推迟图像检索。 实际上,根据图像的尺寸,压缩率和质量,它可能会影响用户设备下载的捆绑包的大小。 因此,推迟这些下载具有几个优点:
- Bundle size reduced 捆绑尺寸减小
- User experience improved (bundle is ready more quickly) 改善了用户体验(捆绑包的准备速度更快)
- Controlled data consumption (only the visible images are downloaded) 受控的数据消耗(仅下载可见图像)
In this article, I will introduce an HTML attribute to lazy load images. To go further, I will show how to use this attribute in a wider application with the three main JavaScript frameworks: Angular, React, and Vue.js
在本文中,我将介绍一个HTML属性来延迟加载图像。 更进一步,我将展示如何在具有三个主要JavaScript框架的更广泛的应用程序中使用此属性:Angular,React和Vue.js
<img>HTML属性 (An HTML Attribute for <img>)
It’s as simple as this: a single attribute named loading
. You can find its documentation here:
就这么简单:一个名为loading
属性。 您可以在这里找到其文档:
The loading
attribute accepts three values:
loading
属性接受三个值:
eager
: loads the image immediatelyeager
:立即加载图像lazy
: defers the loading of the image until scroll progress reaches a calculated distance from the viewportauto
: applies the default behavior provided by the browserauto
:应用浏览器提供的默认行为
How to use it? It’s just below:
如何使用它? 在下面:
<img src="http://my-awesome-img.com/photo.png" alt="Alternative text" loading="lazy" />
警告 (Caveat)
However, be careful when using this attribute. Indeed, the documentation explains that this feature is only available when JavaScript is enabled; otherwise, it leads to tracking concerns:
但是,使用此属性时要小心。 实际上,文档解释说,只有在启用JavaScript的情况下,此功能才可用。 否则,将导致跟踪问题:
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/b8c35323b209eafa5913495395a2feeb.png)
Moreover, this feature flag is not enabled on every browser, or even supported. Fortunately, caniuse.com is very handy:
此外,并非在所有浏览器上都启用此功能标志,甚至不支持。 幸运的是, caniuse.com非常方便:
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/b3e40b255cd0ab2e958777fcff364bc0.png)
Since this attribute is not supported by specific or the oldest browsers, we can use a polyfill:
由于特定或最早的浏览器不支持此属性,因此我们可以使用polyfill:
正在加载属性 (Loading attribute in action)
![Demo of loading HTML attribute on img markup](https://i-blog.csdnimg.cn/blog_migrate/ec2d7066f99bdbfd95a777c77dcb6d35.png)
在更大范围内使用Loading属性 (Using the Loading Property at a Wider Scale)
角度的 (Angular)
For this first version, Angular offers a powerful way to handle this behavior to every single <img>
of your solution: a directive.
对于第一个版本,Angular提供了一种强大的方式来处理解决方案的每个<img>
行为:指令。
I won’t steal the job of Netanel Basal, who describes how to easily achieve the task in his article:
我不会偷走Netanel Basal的工作,他在他的文章中描述了如何轻松完成任务:
React (React)
As React promotes component reusability, we will need to create a nesting component.
随着React提升组件的可重用性,我们将需要创建一个嵌套组件。
import React from "react";
export const LazyImage = ({ src, alt }) => {
const lazyLoadingSupported = 'loading' in HTMLImageElement.prototype;
const attributes = lazyLoadingSupported ? { loading: 'lazy' } : {}
return (
<Image
src={src}
alt={alt}
{ ...attributes }
/>
);
};
If loading
is not supported, we can use the Intersection Observer API. You can find out how to integrate it in a React component here:
如果不支持loading
,则可以使用Intersection Observer API 。 您可以在此处找到如何将其集成到React组件中:
Vue.js (Vue.js)
Finally, Vue.js follows the steps of Angular by using a directive too.
最后,Vue.js也通过使用指令来遵循Angular的步骤。
import { DirectiveOptions } from 'vue'
export default {
inserted: function (el) {
const img = el as HTMLImageElement
const lazyLoadingSupported = 'loading' in HTMLImageElement.prototype
if (lazyLoadingSupported) {
img.setAttribute('loading', 'lazy')
} else {
// Otherwise use IntersectionObserver API
}
}
} as DirectiveOptions
Even though I’m using TypeScript here, it’s not mandatory. As you can see, we just check if the loading
property is available (L6). Then, if supported, we set the attribute; otherwise, using the Intersection Observer API will be necessary.
即使我在这里使用TypeScript,也不是必须的。 如您所见,我们仅检查loading
属性是否可用(L6)。 然后,如果支持,我们设置属性; 否则,将需要使用Intersection Observer API 。
Then let’s register the directive globally:
然后让我们在全局注册指令:
import ImgLazyLoading from '@/directives/img-lazy-loading'
Vue.directive('img-lazy', ImgLazyLoading)
Finally, we can use our directive ImgLazyLoading
with the v-img-lazy
attribute:
最后,我们可以将指令ImgLazyLoading
与v-img-lazy
属性一起使用:
<template>
<div class="empty-space">
<img
src="https://images.unsplash.com/photo-1598524614143-5a706112a2b7?auto=format&fit=crop&w=2853&q=80"
v-img-lazy
/>
<img
src="https://images.unsplash.com/photo-1598389332468-2591a323393e?auto=format&fit=crop&w=2853&q=80"
v-img-lazy
/>
<img
src="https://images.unsplash.com/photo-1598342546843-aec32a8af54b?auto=format&fit=crop&w=2853&q=80"
v-img-lazy
/>
</div>
</template>
<script>
export default {}
</script>
<style lang="scss" scoped>
.empty-space {
margin-top: 2900px;
display: flex;
flex-direction: column;
> * {
width: 600px;
margin-bottom: 900px;
object-fit: cover;
}
}
</style>
Unlike Angular, we can’t apply a directive on a selector. Therefore, we will need to add v-img-lazy
manually to every <img>
. Fortunately, the IDEs have a “replace in entire solution” functionality!
与Angular不同,我们不能在选择器上应用指令。 因此,我们需要手动将v-img-lazy
添加到每个<img>
。 幸运的是,IDE具有“替换整个解决方案”的功能!
翻译自: https://medium.com/better-programming/lazy-loading-images-made-easy-in-javascript-37b0ff91974c
javascript加载