=== Easy Lazy Loader ===
Contributors: iprodev
Donate link: https://www.iprodev.com/easy-lazy-loader
Tags: lazy load, images, videos, audios, iframes, front-end optimization, performance
Requires at least: 5.0
Tested up to: 6.9.1
Requires PHP: 7.4
Stable tag: 1.2.0
License: GPLv3
License URI: https://www.gnu.org/licenses/gpl.html

Lazy load images, videos, iframes and audios to improve page load times and server bandwidth. Degrades gracefully for non-js users.

== Description ==

Lazy load images, videos, iframes and audios to improve page load times. Uses the modern **IntersectionObserver API** to only load an element when it's visible in the viewport.

**Easy Lazy Loader** is the most fully featured, incredibly easy to set up lazy load plugin for *WordPress*. Use the plugins admin settings to easily define what elements are lazy loaded and when they become visible in the users browser.

You can also lazy load other images, iframes, videos and audios in your theme, by using a simple filter.

Non-javascript visitors get the original element in a noscript element.

Compatible with responsive images (srcset) introduced in WordPress 4.4.

= IMAGE LAZY LOAD =
Images are the number one element that slows page load and increases bandwidth use. **Easy Lazy Loader** works with the responsive images feature (srcset) and also adds the native `loading="lazy"` HTML attribute for browsers that support it natively — giving you a double layer of lazy loading.

= VIDEO LAZY LOAD =
**Easy Lazy Loader** supports all WordPress video Embeds including Youtube, Vimeo and HTML5 video - for a full list see the [WordPress Codex Embeds](https://codex.wordpress.org/Embeds) list. The WordPress embed method of copying and pasting the video url into posts and pages content area is fully supported.

= AUDIO LAZY LOAD =
**Easy Lazy Loader** supports all WordPress audio Embeds including SoundCloud, Spotify and HTML5 audio - for a full list see the [WordPress Codex Embeds](https://codex.wordpress.org/Embeds) list. The WordPress embed method of copying and pasting the audio url into posts and pages content area is fully supported.

= iFRAME LAZY LOAD =
**Easy Lazy Loader** has built in support for content that is added by iframe from any source in content and widgets examples

* WordPress embedded media
* Facebook Like boxes with profiles, Like buttons, Recommend
* Google Maps
* Any third-party iframe embed


= PLACEHOLDERS =
Several strategies to fill the area of an image before it loads.

* **Keeping the space empty for the image:** In a world of responsive design, this prevents content from jumping around. Those layout changes are bad from a user's experience point of view, but also for performance. The browser is forced to do layout re calculations every time it fetches the dimensions of an image, leaving space for it.
* **Placeholder:** Imagine that we are displaying a user's profile image. We might want to display a silhouette in the background. This is shown while the main image is loaded, but also when that request failed or when the user didn't set any profile picture at all. These images are usually vector-based, and due to their small size are a good candidate to be inlined.
* **Solid colour:** Take a colour from the image and use it as the background colour for the placeholder. This can be the dominant colour, the most vibrant… The idea is that it is based on the image you are loading and should help making the transition between no image to image loaded smoother.
* **Blurry image:** Also called blur-up technique. You render a tiny version of the image and then transition to the full one. The initial image is tiny both in pixels and kBs. To remove artifacts the image is scaled up and blurred.


= PLUGIN COMPATIBILITY =
* Works with any WordPress theme that follows the WordPress Theme Codex
* Fully compatible with WPTouch plugin
* Fully compatible with MobilePress plugin
* Fully compatible with WP-Print plugin
* Fully compatible with Opera Mini browser
* Will not conflict with any plugin that has lazy load built in
* Plugin Developers: the `easy_lazy_loader_html` filter allows them to apply lazy loading to their plugin's output
* Tested 100% compatible with WP Super Cache and W3 Total Cache plugins
* Tested 100% compatible with Amazon CloudFront
* Fully compatible with CDN architecture.

= FEATURES =
* Lazy load images, iframes, videos, and audios.
* Native HTML `loading="lazy"` attribute added automatically for modern browser support.
* Uses modern **IntersectionObserver API** — no extra JavaScript library required.
* **Zero jQuery dependency** — pure vanilla JavaScript on both frontend and admin panel.
* MutationObserver support for content loaded via infinite scroll or AJAX.
* Custom image placeholder.
* Low-res preview image placeholder.
* Color preview placeholder.
* Skip classes to ignore specific elements by class name.
* WordPress Multisite ready.
* Backend support for RTL display.
* Translation ready.
* No external requests — your site data stays private.

= Localization =
* Persian (fa_IR) - [Hemn Chawroka](https://www.iprodev.com/author/admin/) (plugin author)
* German (de_DE) - [Hemn Chawroka](https://www.iprodev.com/author/admin/) (plugin author)
* French (fr_FR) - [Hemn Chawroka](https://www.iprodev.com/author/admin/) (plugin author)
* Spanish (es_ES) - [Hemn Chawroka](https://www.iprodev.com/author/admin/) (plugin author)
* Kurdish Sorani (ckb) - [Hemn Chawroka](https://www.iprodev.com/author/admin/) (plugin author)
* Kurdish Kurmanji (kmr) - [Hemn Chawroka](https://www.iprodev.com/author/admin/) (plugin author)

== Installation ==
1. Download and unzip plugin
2. Upload the 'easy-lazy-loader' folder to the '/wp-content/plugins/' directory
3. Activate the plugin through the 'Plugins' menu in WordPress

For detailed documentation on how you can configure these options please visit the [Easy Lazy Loader](https://www.iprodev.com/easy-lazy-loader/) plugin page

== Frequently Asked Questions ==

= Whoa, this plugin is using JavaScript. What about visitors without JS? =
No worries. They get the original element in a noscript element. No Lazy Loading for them, though.

= I'm using a CDN. Will this plugin interfere? =
Lazy loading works just fine. The images will still load from your CDN.

= Does the plugin support modern browsers? =
Yes. Version 1.2.0 uses the native IntersectionObserver API which is supported by all modern browsers (Chrome, Firefox, Safari, Edge). For older browsers without IntersectionObserver support, the plugin falls back to loading all elements immediately. The plugin requires no external JavaScript libraries.

= Does the plugin send any data externally? =
No. Since version 1.2.0, the plugin makes no external requests whatsoever. Your site data remains completely private.

= How do I prevent specific images from being lazy loaded? =
Add the class `no-lazy` to any image you want to exclude. You can also configure additional skip classes in the plugin settings.

= How do I change the placeholder image =

`
add_filter( 'ell_placeholder_url', 'my_custom_placeholder_image' );
function my_custom_placeholder_image( $image ) {
	return 'https://url/to/image';
}
`

= How do I lazy load other images in my theme? =

If you have images output in custom templates or want to lazy load other images in your theme, you may pass the HTML through a filter:

`<?php
$html = '<img src="myimage.jpg" alt="">';
$html = apply_filters( 'easy_lazy_loader_html', $html );
echo $html;
?>`

Or, you can add an attribute called "data-lazy-src" and "data-lazy-type" with the source of the image URL and set the actual image URL to a transparent 1x1 pixel.

== Changelog ==

= 1.2.0 =

* **Security:** Fixed SQL Injection vulnerability in attachment ID lookup — now uses `$wpdb->prepare()`.
* **Security:** Removed external data transmission — the plugin no longer sends site information to any external server.
* **Security:** Added whitelist validation for `placeholder_type` and `placeholder_image_size` settings.
* **Security:** Replaced `@$_POST` error suppression with proper `isset()` checks.
* **Performance:** Replaced jQuery.sonar scroll-based detection with native **IntersectionObserver API** — more efficient, no extra library.
* **Performance:** Removed all jQuery dependencies — both frontend and admin scripts are now pure vanilla JavaScript.
* **Performance:** Admin form submission now uses `fetch()` instead of `$.ajax()`.
* **Performance:** Added MutationObserver support to detect and lazy-load content injected dynamically (infinite scroll, AJAX, etc.).
* **Privacy:** Removed daily cron that transmitted plugin and site data to api.iprodev.com.
* **Improvement:** Added native `loading="lazy"` HTML attribute to lazy-loaded images for dual-layer browser support.
* **Improvement:** Removed Google Fonts external CDN request from admin panel — system fonts used instead.
* **Improvement:** Color picker fields in admin now use native `<input type="color">` — no jQuery UI dependency.
* **Improvement:** Color placeholder type no longer requires WordPress Gallery Extra plugin — works standalone using the default color settings.
* **Bug Fix:** Fixed undefined variable `$placeholder_color` in default placeholder mode.
* **Bug Fix:** Fixed `wp_get_attachment_image_src()` return value not checked before use.
* **Bug Fix:** Fixed deprecated dynamic property creation (`$OPTIONS`) — now declared explicitly.
* **Code Quality:** Replaced `json_encode()` with `wp_json_encode()`.
* **Code Quality:** Replaced `_e()` with `esc_html_e()` throughout admin output.
* **Code Quality:** Version number mismatch between plugin header and class constant resolved (both now 1.2.0).

= 1.1.3 =

* **Optimized:** creating placeholder image.

= 1.1.2 =

* **Fixed:** some bugs and stability improvements.

= 1.1.1 =

* **Optimized:** attachment identifier, now identify images from their URL better.

= 1.1.0 =

* **Optimized:** attachment identifier, now identify images from their URL.
* **Optimized:** placeholders to preserve their ratio as possible.
* **Fixed:** some bugs and stability improvements.

= 1.0.0 =

* Initial working version
