目录
实战示例
快速启动Svelte
添加components文件夹
观察交叉点
加载图像
使用slot属性传递值
在加载时显示图像
首页 web前端 css教程 懒惰的图像在Svelte中

懒惰的图像在Svelte中

Apr 04, 2025 am 09:18 AM

Lazy Loading Images in Svelte

网站速度优化技巧之一:仅在需要时(即图像进入视口时)下载图像,这就是“懒加载”。此技术已存在一段时间,并且有很多关于如何实现它的优秀教程。

然而,即使资源充足,懒加载的实现方式也会因项目或框架而异。本文将结合使用Intersection Observer API和onLoad事件,利用Svelte JavaScript框架实现图像懒加载。

如果您不熟悉Svelte框架,可以参考Tristram Tolliday的Svelte入门介绍。

实战示例

我在测试Shop Ireland(一个基于Svelte和Sapper的应用程序)的速度时,整合了这种方法。我们的目标是使其尽可能快。首页的性能受到影响,因为浏览器下载了许多屏幕上根本没有显示的图像,因此我们自然而然地转向懒加载。

Svelte本身已经非常快,因为所有代码都是预编译的。但是,一旦我们为图像添加了懒加载,速度得到了显着提升。

我们将一起完成这个过程。您可以从GitHub获取此演示的最终代码,并阅读其工作原理说明。

最终效果如下:

快速启动Svelte

您可能已经有了一个Svelte应用程序,但如果没有,让我们创建一个新的Svelte项目并在本地运行它。在命令行中输入:

 npx degit sveltejs/template my-svelte-project
cd my-svelte-project
npm install
npm run dev
登录后复制

现在,您应该可以在http://localhost:5000上运行一个入门应用程序。

添加components文件夹

初始的Svelte演示只有一个App.svelte文件,还没有组件。让我们设置此演示所需的组件。由于没有components文件夹,所以在src文件夹中创建一个。在这个文件夹中,创建一个Image文件夹——它将保存我们此演示的组件。

我们将让我们的组件做两件事。首先,它们将检查图像何时进入视口。然后,当图像进入时,组件将在显示图像之前等待图像文件加载完成。

第一个组件将是一个<intersectionobserver></intersectionobserver>,它围绕第二个组件<imageloader></imageloader>进行包装。我喜欢这种设置的原因是,它允许每个组件专注于执行一项操作,而不是尝试在一个组件中打包一堆操作。

让我们从<intersectionobserver></intersectionobserver>组件开始。

观察交叉点

我们的第一个组件将是Intersection Observer API的一个工作实现。 Intersection Observer是一个相当复杂的东西,但其要点是它监视子元素,并在子元素进入其父元素的边界框时通知我们。因此,图像可以作为某些父元素的子元素,当它们滚动到视图中时,我们可以提前得到提示。

虽然深入了解Intersection Observer API的来龙去脉是一个好主意——Travis Almand对此有一个很好的描述——但我们将使用Rich Harris为svelte.dev编写的方便的Svelte组件。

在深入了解它的具体功能之前,我们先设置它。创建一个新的IntersectionObserver.svelte文件,并将其放入src/components/Image文件夹中。我们将在这里使用以下代码定义组件:

 import { onMount } from 'svelte';


 export let once = false;
 export let top = 0;
 export let bottom = 0;
 export let left = 0;
 export let right = 0;


 let intersecting = false;
 let container;


 onMount(() => {
  if (typeof IntersectionObserver !== 'undefined') {
   const rootMargin = `${bottom}px ${left}px ${top}px ${right}px`;


   const observer = new IntersectionObserver(entries => {
    intersecting = entries[0].isIntersecting;
    if (intersecting && once) {
     observer.unobserve(container);
    }
   }, {
    rootMargin
   });


   observer.observe(container);
   return () => observer.unobserve(container);
  }

 // Older browser fallback
  function handler() {
   const bcr = container.getBoundingClientRect();


   intersecting = (
    (bcr.bottom bottom) > 0 &&
    (bcr.right right) > 0 &&
    (bcr.top - top)  window.removeEventListener('scroll', handler);
 });




 div {
  width: 100%;
  height: 100%;
 }



<div bind:this="{container}">
<slot></slot>
</div>
登录后复制

我们可以将此组件用作其他组件的包装器,它将为我们确定包装的组件是否与视口相交。

如果您熟悉Svelte组件的结构,您会看到它遵循一个模式,该模式从脚本开始,进入样式,然后以标记结束。它设置了一些我们可以传递的选项,包括once属性,以及屏幕边缘的顶部、右侧、底部和左侧距离的数值,这些数值定义了交叉点开始的位置。

我们将忽略距离,而是使用once属性。这将确保图像只加载一次,因为它们进入了视口。

组件的主要逻辑位于onMount部分。这将设置我们的观察者,用于检查我们的元素以确定它是否与屏幕的可见区域“相交”。

对于旧版浏览器,它还会附加一个滚动事件来检查我们滚动时元素是否可见,然后如果我们确定它可用且once为true,它将删除此侦听器。

加载图像

让我们使用<intersectionobserver></intersectionobserver>组件通过将其包装在<imageloader></imageloader>组件周围来有条件地加载图像。同样,这是从<intersectionoberserver></intersectionoberserver>接收通知的组件,因此它知道该加载图像了。

这意味着我们需要在components/Image中创建一个新的组件文件。让我们将其命名为ImageLoader.svelte。以下是我们想要在其内使用的代码:

 export let src
 export let alt


 import IntersectionObserver from './IntersectionObserver.svelte'
 import Image from './Image.svelte'
 



<intersectionobserver let:intersecting="{intersecting}" once="{true}">
 {#if intersecting}
<image src="%7Bsrc%7D" alt="{alt}"></image>
 {/if}
</intersectionobserver>
登录后复制

此组件采用一些与图像相关的属性——src和alt——我们将使用它们来创建图像的实际标记。请注意,我们在脚本部分导入了两个组件,包括我们刚刚创建的<intersectionobserver></intersectionobserver>和另一个名为<image></image>的组件,我们还没有创建它,但稍后会介绍。

<intersectionobserver></intersectionobserver>通过充当即将创建的<image></image>组件的包装器来发挥作用。查看其属性。我们将once设置为true,因此图像只在我们第一次看到它时加载。

然后我们使用Svelte的slot属性。它们是什么?我们接下来介绍。

使用slot属性传递值

像我们的<intersectionobserver></intersectionobserver>这样的包装组件对于将属性传递给它包含的子组件非常方便。 Svelte为我们提供了名为slot属性的东西来实现这一点。

在我们的<intersectionobserver></intersectionobserver>组件中,您可能注意到了这一行:

<slot></slot>
登录后复制

这将intersecting属性传递给任何我们给它的组件。在这种情况下,我们的<imageloader></imageloader>组件在使用包装器时接收该属性。我们使用let:intersecting={intersecting}访问该属性,如下所示:

<intersectionobserver let:intersecting="{intersecting}" once="{true}"></intersectionobserver>
登录后复制

然后,我们可以使用intersecting值来确定何时加载<image></image>组件。在这种情况下,我们使用if条件来检查何时是加载时机:

<intersectionobserver let:intersecting="{intersecting}" once="{true}">
 {#if intersecting}
<image src="%7Bsrc%7D" alt="{alt}"></image>
 {/if}
</intersectionobserver>
登录后复制

如果发生交叉,则加载<image></image>并接收alt和src属性。您可以在此Svelte教程中了解更多关于slot属性的信息。

我们现在已经准备好代码,以便在图像滚动到屏幕上时显示<image></image>组件。让我们最终开始构建该组件。

在加载时显示图像

是的,您猜对了:让我们向components/Image文件夹添加一个Image.svelte文件,用于我们的<image></image>组件。这是接收我们的alt和src属性并在img元素上设置它们的组件。

以下是组件代码:

 export let src
 export let alt


 import { onMount } from 'svelte'


 let loaded = false
 let thisImage


 onMount(() => {
  thisImage.onload = () => {
   loaded = true
  }
 }) 






 img {
  height: 200px;
  opacity: 0;
  transition: opacity 1200ms ease-out;
 }
 img.loaded {
  opacity: 1;
 }



<img src="/static/imghw/default1.png" data-src="https://img.php.cn/" class="lazy" alt="Lazy Loading Images in Svelte">
登录后复制

再次查看演示:

请记住,您可以从GitHub下载此演示的完整代码。如果您想在一个生产网站上看到它的运行效果,请查看我的Shop Ireland项目。懒加载用于首页、类别页面和搜索页面,以帮助提高速度。我希望您能将其用于您自己的Svelte项目!

以上是懒惰的图像在Svelte中的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Java教程
1662
14
CakePHP 教程
1418
52
Laravel 教程
1311
25
PHP教程
1261
29
C# 教程
1234
24
Google字体可变字体 Google字体可变字体 Apr 09, 2025 am 10:42 AM

我看到Google字体推出了新设计(Tweet)。与上一次大型重新设计相比,这感觉更加迭代。我几乎无法分辨出区别

如何使用HTML,CSS和JavaScript创建动画倒计时计时器 如何使用HTML,CSS和JavaScript创建动画倒计时计时器 Apr 11, 2025 am 11:29 AM

您是否曾经在项目上需要一个倒计时计时器?对于这样的东西,可以自然访问插件,但实际上更多

HTML数据属性指南 HTML数据属性指南 Apr 11, 2025 am 11:50 AM

您想了解的有关HTML,CSS和JavaScript中数据属性的所有信息。

使Sass更快的概念证明 使Sass更快的概念证明 Apr 16, 2025 am 10:38 AM

在一个新项目开始时,Sass汇编发生在眼睛的眨眼中。感觉很棒,尤其是当它与browsersync配对时,它重新加载

我们如何创建一个在SVG中生成格子呢模式的静态站点 我们如何创建一个在SVG中生成格子呢模式的静态站点 Apr 09, 2025 am 11:29 AM

格子呢是一块图案布,通常与苏格兰有关,尤其是他们时尚的苏格兰语。在Tar​​tanify.com上,我们收集了5,000多个格子呢

如何在WordPress主题中构建VUE组件 如何在WordPress主题中构建VUE组件 Apr 11, 2025 am 11:03 AM

内联式模板指令使我们能够将丰富的VUE组件构建为对现有WordPress标记的逐步增强。

php是A-OK用于模板 php是A-OK用于模板 Apr 11, 2025 am 11:04 AM

PHP模板通常会因促进Subpar代码而变得不良说唱,但这并不是这样的情况。让我们看一下PHP项目如何执行基本的

编程SASS创建可访问的颜色组合 编程SASS创建可访问的颜色组合 Apr 09, 2025 am 11:30 AM

我们一直在寻求使网络更容易访问。颜色对比只是数学,因此Sass可以帮助涵盖设计师可能错过的边缘案例。

See all articles