173 lines
4.7 KiB
PHP
173 lines
4.7 KiB
PHP
<?php
|
|
/**
|
|
* Lazy Loader Class
|
|
*
|
|
* Handles lazy loading for images and iframes
|
|
*/
|
|
|
|
if (!defined('ABSPATH')) {
|
|
exit;
|
|
}
|
|
|
|
class OptiCore_Lazy_Loader {
|
|
|
|
private static $instance = null;
|
|
|
|
public static function get_instance() {
|
|
if (null === self::$instance) {
|
|
self::$instance = new self();
|
|
}
|
|
return self::$instance;
|
|
}
|
|
|
|
private function __construct() {
|
|
}
|
|
|
|
public function init() {
|
|
// Add lazy loading to images
|
|
add_filter('the_content', array($this, 'add_lazy_loading'), 999);
|
|
add_filter('post_thumbnail_html', array($this, 'add_lazy_loading'), 999);
|
|
add_filter('get_avatar', array($this, 'add_lazy_loading'), 999);
|
|
|
|
// Add loading attribute to images (native lazy loading)
|
|
add_filter('wp_get_attachment_image_attributes', array($this, 'add_loading_attribute'), 10, 3);
|
|
|
|
// Enqueue lazy load script if needed
|
|
add_action('wp_enqueue_scripts', array($this, 'enqueue_scripts'));
|
|
}
|
|
|
|
/**
|
|
* Add lazy loading to content
|
|
*/
|
|
public function add_lazy_loading($content) {
|
|
if (is_admin() || is_feed() || is_preview()) {
|
|
return $content;
|
|
}
|
|
|
|
// Add loading="lazy" to images
|
|
$content = preg_replace_callback(
|
|
'/<img([^>]+)>/i',
|
|
array($this, 'add_lazy_to_image'),
|
|
$content
|
|
);
|
|
|
|
// Add lazy loading to iframes
|
|
$content = preg_replace_callback(
|
|
'/<iframe([^>]+)>/i',
|
|
array($this, 'add_lazy_to_iframe'),
|
|
$content
|
|
);
|
|
|
|
return $content;
|
|
}
|
|
|
|
/**
|
|
* Add lazy loading to image tag
|
|
*/
|
|
public function add_lazy_to_image($matches) {
|
|
$img = $matches[0];
|
|
|
|
// Skip if already has loading attribute
|
|
if (strpos($img, 'loading=') !== false) {
|
|
return $img;
|
|
}
|
|
|
|
// Skip if it's a data URI
|
|
if (strpos($img, 'src="data:') !== false) {
|
|
return $img;
|
|
}
|
|
|
|
// Add loading="lazy"
|
|
$img = str_replace('<img', '<img loading="lazy"', $img);
|
|
|
|
// Add decoding="async"
|
|
if (strpos($img, 'decoding=') === false) {
|
|
$img = str_replace('<img', '<img decoding="async"', $img);
|
|
}
|
|
|
|
return $img;
|
|
}
|
|
|
|
/**
|
|
* Add lazy loading to iframe tag
|
|
*/
|
|
public function add_lazy_to_iframe($matches) {
|
|
$iframe = $matches[0];
|
|
|
|
// Skip if already has loading attribute
|
|
if (strpos($iframe, 'loading=') !== false) {
|
|
return $iframe;
|
|
}
|
|
|
|
// Add loading="lazy"
|
|
$iframe = str_replace('<iframe', '<iframe loading="lazy"', $iframe);
|
|
|
|
return $iframe;
|
|
}
|
|
|
|
/**
|
|
* Add loading attribute to images
|
|
*/
|
|
public function add_loading_attribute($attr, $attachment, $size) {
|
|
if (!isset($attr['loading'])) {
|
|
$attr['loading'] = 'lazy';
|
|
}
|
|
|
|
if (!isset($attr['decoding'])) {
|
|
$attr['decoding'] = 'async';
|
|
}
|
|
|
|
return $attr;
|
|
}
|
|
|
|
/**
|
|
* Enqueue scripts
|
|
*/
|
|
public function enqueue_scripts() {
|
|
// Native lazy loading is supported in modern browsers
|
|
// No additional JS needed for basic functionality
|
|
|
|
// Optional: Add intersection observer polyfill for older browsers
|
|
if ($this->needs_polyfill()) {
|
|
wp_enqueue_script(
|
|
'opticore-lazy-polyfill',
|
|
OPTICORE_PLUGIN_URL . 'assets/js/lazy-load-polyfill.js',
|
|
array(),
|
|
OPTICORE_VERSION,
|
|
true
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if polyfill is needed
|
|
*/
|
|
private function needs_polyfill() {
|
|
// Check user agent for older browsers
|
|
$user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';
|
|
|
|
// Check for old browsers that don't support native lazy loading
|
|
if (preg_match('/MSIE|Trident|Edge\/([0-9]{2})\./i', $user_agent)) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Preload critical images
|
|
*/
|
|
public function preload_critical_images() {
|
|
// Get the featured image of the current post/page
|
|
if (is_singular()) {
|
|
$thumbnail_id = get_post_thumbnail_id();
|
|
if ($thumbnail_id) {
|
|
$thumbnail_url = wp_get_attachment_image_url($thumbnail_id, 'large');
|
|
if ($thumbnail_url) {
|
|
echo '<link rel="preload" as="image" href="' . esc_url($thumbnail_url) . '">';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|