Lazy Image
Lazy Image is a lightweight image loading utility for FrontAlign. It keeps real image URLs out of src until the image is close to the viewport, then loads them automatically from data-src.
Use Lazy Image for:
- Gallery images and photo grids
- Blog thumbnails and article cards
- Product images and ecommerce sections
- Hero and landing page media
- Images rendered after async data fetches
- Any image that should not load before it is needed
FrontAlign Lazy Image combines native browser observers with a small runtime layer. The markup only needs an img element with data-src; the JavaScript layer handles viewport detection, preload testing, shimmer removal, loaded state, and error fallback UI.
Getting Started
Lazy Image does not need a component wrapper or fa-component attribute. When FrontAlign is started from NPM or CDN, the runtime automatically observes img[data-src] images.
The only required attribute is data-src.
<img
data-src="/images/gallery/photo-1.jpg"
alt="Mountain landscape"
width="800"
height="500"
/>
After new FrontAlign() runs, every matching image is observed automatically. When the image enters the viewport area, FrontAlign loads the real image, removes data-src, adds .fa-image-loaded, and removes the shimmer layer.
Lazy Image is intentionally attribute-first. There is no special class required for the initial markup, and there is no manual initialization required in normal usage.
Required Markup
The minimal required markup is a normal image with data-src.
| Attribute | Required | Role |
|---|---|---|
data-src | Yes | Stores the real image URL. FrontAlign reads this value and assigns it to src only when the image should load. |
alt | Recommended | Provides accessible text for screen readers and fallback context when the image cannot be displayed. |
width / height | Recommended | Reserves layout space and helps prevent layout shift before the image is loaded. |
data-error-text | No | Overrides the default fallback message shown when the image fails to load. |
<img
data-src="/images/products/headphones.jpg"
data-error-text="Product image could not be loaded"
alt="Wireless headphones"
width="640"
height="420"
/>
Loading Behavior
Lazy Image uses IntersectionObserver to load images only when they are close to the viewport.
| Step | What happens |
|---|---|
| Observe | FrontAlign finds every image matching img[data-src] and starts observing it. |
| Near viewport | When the image intersects the observer area, LazyImage.load() is called. |
| Wrap | The image is wrapped in .fa-image-wrap, then shimmer and error layers are generated. |
| Preload | A temporary Image() instance loads the URL from data-src before the real image is updated. |
| Success | The real image receives src, data-src is removed, .fa-image-loaded is added, and shimmer is removed. |
| Error | Shimmer is removed, data-src is removed, and .fa-image-error-layer.is-visible is shown. |
Observer settings
FrontAlign starts image loading slightly before the image becomes fully visible. This makes the image feel ready by the time the user scrolls to it.
| Setting | Value | Purpose |
|---|---|---|
rootMargin | 100px 0px | Starts loading around 100px before the image reaches the viewport. |
threshold | 0.1 | Triggers loading when a small part of the image intersects the observer area. |
selector | img[data-src] | The default selector used by LazyImage.observe(). |
After an image starts loading, it is unobserved so the same image is not processed again.
Dynamic Images
Lazy Image also watches the DOM with MutationObserver. Images added later are automatically observed as long as they match img[data-src].
This is useful for API-driven UIs, infinite lists, filters, tabs, modals, and components that render after the first page load.
<div id="gallery"></div>
<script>
const gallery = document.querySelector('#gallery');
gallery.insertAdjacentHTML('beforeend', `
<img
data-src="/images/gallery/new-photo.jpg"
alt="New gallery photo"
width="800"
height="500"
/>
`);
</script>
You do not need to call LazyImage.observe() again for dynamically inserted images when the FrontAlign runtime is already active.
Error Fallback
If the image cannot be loaded, Lazy Image displays a generated fallback layer.
<img
data-src="/images/missing-image.jpg"
data-error-text="Preview unavailable"
alt="Preview"
width="640"
height="420"
/>
The error layer includes:
- A default inline SVG image icon
- A fallback text message
- The
.is-visiblestate class after failure
If data-error-text is not provided, the default message is Image failed to load.
| State | Class / attribute | Result |
|---|---|---|
| Initial | data-src | The real image URL is waiting to be loaded. |
| Loading | .fa-image-shimmer | Generated shimmer layer is visible. |
| Loaded | .fa-image-loaded | The image is loaded successfully and can be animated with CSS. |
| Error | .fa-image-error-layer.is-visible | The fallback icon and message are displayed. |
Accessibility
Lazy loading must not remove the meaning of the image. Treat every lazy image like a normal image.
Recommended practices:
- Always provide meaningful
alttext for content images. - Use empty
alt=""only for decorative images. - Add
widthandheightto reduce layout shift. - Do not put important text only inside an image.
- Use
data-error-textwhen a failed image needs clear context. - Keep error text short and understandable.
<img
data-src="/images/team/founder.jpg"
alt="Founder speaking at a product launch"
data-error-text="Founder photo could not be loaded"
width="720"
height="480"
/>
For decorative images:
<img
data-src="/images/patterns/soft-gradient.png"
alt=""
width="1200"
height="600"
/>
Class Reference
| Class / selector | Role |
|---|---|
img[data-src] | Default target selector. Any image with this attribute is automatically observed by FrontAlign. |
.fa-image-wrap | Generated wrapper around the image. Provides the positioning context for shimmer and error layers. |
.fa-image-shimmer | Generated loading layer shown while the real image is being loaded through a temporary Image() instance. |
.fa-image-error-layer | Generated fallback layer containing the default SVG icon and error text. |
.is-visible | Added to .fa-image-error-layer when loading fails. |
.fa-image-loaded | Added to the image after it loads successfully. Useful for fade-in or loaded-state styling. |
Notes
Lazy Image is designed to be invisible in daily use. In most projects, the complete setup is:
<img data-src="/images/photo.jpg" alt="Photo description" width="800" height="500" />
and one FrontAlign runtime on the page:
const faApp = new FrontAlign();
That is enough for automatic lazy loading, dynamic image detection, shimmer state, loaded state, and error fallback.