search
HomeWeb Front-endCSS TutorialLazy Loading Images in Svelte

Lazy Loading Images in Svelte

One of the website speed optimization tips: Download images only when needed (i.e. when the image enters the viewport), which is "lazy loading". This technology has been around for a while and there are many excellent tutorials on how to implement it.

However, even with sufficient resources, lazy loading implementations will vary by project or framework. This article will use the Intersection Observer API and onLoad events to achieve lazy image loading using the Svelte JavaScript framework.

If you are not familiar with the Svelte framework, you can refer to Tristram Tokyo’s introduction to Svelte.

Practical examples

I integrated this approach when testing the speed of Shop Ireland (an application based on Svelte and Sapper). Our goal is to make it as fast as possible. The performance of the homepage was affected because the browser downloaded many images that weren't displayed on the screen at all, so we naturally turned to lazy loading.

Svelte itself is already very fast, because all the code is precompiled. However, once we added lazy loading to the image, the speed was significantly improved.

We will complete the process together. You can get the final code for this demo from GitHub and read the description of how it works.

The final effect is as follows:

Quickly start Svelte

You may already have a Svelte application, but if not, let's create a new Svelte project and run it locally. Enter:

 npx degit sveltejs/template my-svelte-project
cd my-svelte-project
npm install
npm run dev

Now you should be able to run a starter application on http://localhost:5000.

Add components folder

The initial Svelte demo only has one App.svelte file and has no components yet. Let's set up the components needed for this demo. Since there is no components folder, create one in the src folder. In this folder, create an Image folder - it will save the components of our presentation.

We will let our components do two things. First, they will check when the image enters the viewport. Then, when the image enters, the component will wait for the image file to be loaded before displaying the image.

The first component will be a<intersectionobserver></intersectionobserver> , it revolves around the second component<imageloader></imageloader> Package. The reason I like this setup is that it allows each component to focus on doing one action rather than trying to pack a bunch of actions in one component.

Let's go from<intersectionobserver></intersectionobserver> The component starts.

Observe the intersection

Our first component will be a working implementation of the Intersection Observer API. Intersection Observer is a pretty complex thing, but the point is that it monitors child elements and notifies us when they enter the bounding box of its parent element. Therefore, the image can be used as a child of some parent elements, and we can get prompts in advance when they scroll into the view.

While it's a good idea to dig deep into the ins and outs of the Intersection Observer API - Travis Almand has a good description of this - we'll use the handy Svelte component written by Rich Harris for svelte.dev.

Before we dig into its specific features, let's set it up first. Create a new IntersectionObserver.svelte file and put it into the src/components/Image folder. We will define the component here using the following code:

 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);
  }

 // Old 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>

We can use this component as a wrapper for other components, which will determine for us whether the wrapped component intersects the viewport.

If you are familiar with the structure of the Svelte component, you will see that it follows a pattern that starts with the script, goes into the style, and ends with a marker. It sets some options we can pass, including the once property, as well as the values ​​of the top, right, bottom and left distances of the edge of the screen, which define where the intersection starts.

We will ignore the distance and use the once property instead. This will ensure that the images are loaded only once, as they enter the viewport.

The main logic of the component is located in the onMount section. This will set our observer to check our element to determine if it "intersects" with the visible area of ​​the screen.

For older browsers, it also attaches a scroll event to check if the element is visible when we scroll, and then if we determine that it is available and once is true, it will remove this listener.

Loading the image

Let's use<intersectionobserver></intersectionobserver> The components are packaged in<imageloader></imageloader> The image is loaded conditionally around the component. Again, this is from<intersectionoberserver></intersectionoberserver> The component that receives notifications, so it knows it's time to load the image.

This means we need to create a new component file in components/Image. Let's name it ImageLoader.svelte. Here is the code we want to use inside it:

 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>

This component takes some image-related properties—src and alt—we will use them to create the actual markup of the image. Note that we imported two components in the script section, including the one we just created<intersectionobserver></intersectionobserver> And another named<image></image> The component we haven't created yet, but will be covered later.

<intersectionobserver></intersectionobserver> By acting as the<image></image> Component wrappers to work. Check its properties. We set once to true so the image only loads when we see it the first time.

Then we use Svelte's slot property. What are they? Let's introduce it next.

Passing values ​​using slot attribute

Like ours<intersectionobserver></intersectionobserver> Such a wrapper component is very convenient for passing properties to the subcomponents it contains. Svelte provides us with something called slot property to achieve this.

In our<intersectionobserver></intersectionobserver> In the component, you may have noticed this line:

<slot></slot>

This passes the intersecting property to any component we give it. In this case, our<imageloader></imageloader> The component receives this property when using the wrapper. We use let:intersecting={intersecting} to access the property as follows:

<intersectionobserver let:intersecting="{intersecting}" once="{true}"></intersectionobserver>

We can then use the intersecting value to determine when to load<image></image> Components. In this case, we use if condition to check when it is loading:

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

If a cross occurs, load<image></image> and receive alt and src attributes. You can learn more about slot properties in this Svelte tutorial.

We have now prepared the code for display when the image scrolls to the screen<image></image> Components. Let's finally start building the component.

Display image when loading

Yes, you guessed it: let's add an Image.svelte file to the components/Image folder for our<image></image> Components. This is the component that takes our alt and src attributes and sets them on the img element.

The following is the component code:

 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/imghwm/default1.png" data-src="https://img.php.cn/?x-oss-process=image/resize,p_40" class="lazy" alt="Lazy Loading Images in Svelte">

Check out the demo again:

Remember that you can download the full code for this demo from GitHub. If you want to see how it works on a production site, check out my Shop Ireland project. Lazy loading is used for homepages, category pages, and search pages to help speed up. I hope you can use it for your own Svelte project!

The above is the detailed content of Lazy Loading Images in Svelte. For more information, please follow other related articles on the PHP Chinese website!

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
@keyframes vs CSS Transitions: What is the difference?@keyframes vs CSS Transitions: What is the difference?May 14, 2025 am 12:01 AM

@keyframesandCSSTransitionsdifferincomplexity:@keyframesallowsfordetailedanimationsequences,whileCSSTransitionshandlesimplestatechanges.UseCSSTransitionsforhovereffectslikebuttoncolorchanges,and@keyframesforintricateanimationslikerotatingspinners.

Using Pages CMS for Static Site Content ManagementUsing Pages CMS for Static Site Content ManagementMay 13, 2025 am 09:24 AM

I know, I know: there are a ton of content management system options available, and while I've tested several, none have really been the one, y'know? Weird pricing models, difficult customization, some even end up becoming a whole &

The Ultimate Guide to Linking CSS Files in HTMLThe Ultimate Guide to Linking CSS Files in HTMLMay 13, 2025 am 12:02 AM

Linking CSS files to HTML can be achieved by using elements in part of HTML. 1) Use tags to link local CSS files. 2) Multiple CSS files can be implemented by adding multiple tags. 3) External CSS files use absolute URL links, such as. 4) Ensure the correct use of file paths and CSS file loading order, and optimize performance can use CSS preprocessor to merge files.

CSS Flexbox vs Grid: a comprehensive reviewCSS Flexbox vs Grid: a comprehensive reviewMay 12, 2025 am 12:01 AM

Choosing Flexbox or Grid depends on the layout requirements: 1) Flexbox is suitable for one-dimensional layouts, such as navigation bar; 2) Grid is suitable for two-dimensional layouts, such as magazine layouts. The two can be used in the project to improve the layout effect.

How to Include CSS Files: Methods and Best PracticesHow to Include CSS Files: Methods and Best PracticesMay 11, 2025 am 12:02 AM

The best way to include CSS files is to use tags to introduce external CSS files in the HTML part. 1. Use tags to introduce external CSS files, such as. 2. For small adjustments, inline CSS can be used, but should be used with caution. 3. Large projects can use CSS preprocessors such as Sass or Less to import other CSS files through @import. 4. For performance, CSS files should be merged and CDN should be used, and compressed using tools such as CSSNano.

Flexbox vs Grid: should I learn them both?Flexbox vs Grid: should I learn them both?May 10, 2025 am 12:01 AM

Yes,youshouldlearnbothFlexboxandGrid.1)Flexboxisidealforone-dimensional,flexiblelayoutslikenavigationmenus.2)Gridexcelsintwo-dimensional,complexdesignssuchasmagazinelayouts.3)Combiningbothenhanceslayoutflexibilityandresponsiveness,allowingforstructur

Orbital Mechanics (or How I Optimized a CSS Keyframes Animation)Orbital Mechanics (or How I Optimized a CSS Keyframes Animation)May 09, 2025 am 09:57 AM

What does it look like to refactor your own code? John Rhea picks apart an old CSS animation he wrote and walks through the thought process of optimizing it.

CSS Animations: Is it hard to create them?CSS Animations: Is it hard to create them?May 09, 2025 am 12:03 AM

CSSanimationsarenotinherentlyhardbutrequirepracticeandunderstandingofCSSpropertiesandtimingfunctions.1)Startwithsimpleanimationslikescalingabuttononhoverusingkeyframes.2)Useeasingfunctionslikecubic-bezierfornaturaleffects,suchasabounceanimation.3)For

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

VSCode Windows 64-bit Download

VSCode Windows 64-bit Download

A free and powerful IDE editor launched by Microsoft

PhpStorm Mac version

PhpStorm Mac version

The latest (2018.2.1) professional PHP integrated development tool

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Integrate Eclipse with SAP NetWeaver application server.

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.