Documentation Index Fetch the complete documentation index at: https://mintlify.com/nk-crew/visual-portfolio/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Visual Portfolio includes a sophisticated lazy loading system that defers image loading until they’re needed, significantly improving page load times and performance. The system uses the LazySizes library with custom enhancements.
Lazy Loading Modes
The plugin offers two lazy loading modes:
Visual Portfolio Images Only
Lazy loads only images within Visual Portfolio galleries.
Visual_Portfolio_Settings :: get_option ( 'lazy_loading' , 'vp_images' ); // Returns true
Full Site Lazy Loading
Lazy loads all images across your entire WordPress site.
Visual_Portfolio_Settings :: get_option ( 'lazy_loading' , 'vp_images' ); // Returns 'full'
Implementation
Initialization
Lazy loading is initialized on the wp_loaded hook:
// class-images.php:138
public static function init_lazyload () {
// Don't lazy load for feeds, previews, admin
if ( is_feed () || is_preview () || ( is_admin () && ! wp_doing_ajax () ) ) {
return ;
}
// Don't add on AMP endpoint
if ( function_exists ( 'is_amp_endpoint' ) && is_amp_endpoint () ) {
return ;
}
self :: $allow_vp_lazyload = !! Visual_Portfolio_Settings :: get_option ( 'lazy_loading' , 'vp_images' );
self :: $allow_wp_lazyload = 'full' === Visual_Portfolio_Settings :: get_option ( 'lazy_loading' , 'vp_images' );
}
Content Filtering
When full lazy loading is enabled, the plugin filters various content hooks:
// class-images.php:172
if ( self :: $allow_wp_lazyload ) {
add_filter ( 'the_content' , 'Visual_Portfolio_Images::add_image_placeholders' , 9999 );
add_filter ( 'post_thumbnail_html' , 'Visual_Portfolio_Images::add_image_placeholders' , 9999 );
add_filter ( 'get_avatar' , 'Visual_Portfolio_Images::add_image_placeholders' , 9999 );
add_filter ( 'widget_text' , 'Visual_Portfolio_Images::add_image_placeholders' , 9999 );
// WooCommerce support
add_filter ( 'woocommerce_product_get_image' , 'Visual_Portfolio_Images::add_image_placeholders' , 9999 );
}
Image Processing
Placeholder Generation
The plugin generates SVG placeholders to maintain layout dimensions:
// class-images.php:558
public static function get_image_placeholder ( $width = 1 , $height = 1 ) {
$placeholder = base64_encode (
'<svg width="' . $width . '" height="' . $height . '" ' .
'viewBox="0 0 ' . $width . ' ' . $height . '" ' .
'fill="none" xmlns="http://www.w3.org/2000/svg"></svg>'
);
return 'data:image/svg+xml;base64,' . $placeholder ;
}
Image Attribute Processing
Images are processed to add lazy loading attributes:
// class-images.php:423
public static function process_image_attributes ( $attributes ) {
// Move src to data-src
$attributes [ 'data-src' ] = $attributes [ 'src' ];
// Handle srcset
if ( ! empty ( $attributes [ 'srcset' ] ) ) {
$attributes [ 'data-srcset' ] = $attributes [ 'srcset' ];
$attributes [ 'srcset' ] = $placeholder ;
} elseif ( $placeholder ) {
$attributes [ 'src' ] = $placeholder ;
}
// Set sizes to auto
$attributes [ 'data-sizes' ] = 'auto' ;
// Prevent native lazy loading
$attributes [ 'loading' ] = 'eager' ;
// Add lazyload class
$attributes [ 'class' ] .= ' vp-lazyload' ;
return $attributes ;
}
Output Structure
Processed images include a <noscript> fallback:
// class-images.php:412
return sprintf (
'<noscript>%1$s</noscript><img %2$s>' ,
$fallback ,
$new_attributes_str
);
Exclusions and Blocking
Blocked Attributes
Images with certain attributes are excluded from lazy loading:
// class-images.php:113
public static function get_image_blocked_attributes () {
return [
'data-skip-lazy' ,
'data-no-lazy' ,
'data-src' ,
'data-srcset' ,
'data-lazy-original' ,
'fetchpriority="high"' ,
// More blocked attributes...
];
}
Blocked Classes
Images with certain CSS classes are excluded:
// class-images.php:277
$blocked_classes = [
'lazy' ,
'lazyload' ,
'lazy-load' ,
'skip-lazy' ,
'no-lazy' ,
];
Blocked Sources
Specific image sources are excluded:
// class-images.php:302
$blocked_src = [
'/wpcf7_captcha/' ,
'timthumb.php?src' ,
];
User-Defined Exclusions
Administrators can define custom exclusions in plugin settings:
// class-images.php:164
$lazyload_exclusions = Visual_Portfolio_Settings :: get_option ( 'lazy_loading_excludes' , 'vp_images' );
if ( $lazyload_exclusions ) {
self :: $lazyload_user_exclusions = explode ( " \n " , $lazyload_exclusions );
}
JavaScript Integration
No-JS Fallback
The plugin adds CSS to hide lazy images when JavaScript is disabled:
// class-images.php:650
public static function add_nojs_fallback () {
?>
< style type = "text/css" >
html : not ( . vp - lazyload - enabled ): not ( . js ) . vp - lazyload {
display : none ;
}
</ style >
< script >
document . documentElement . classList . add ( 'vp-lazyload-enabled' );
</ script >
<? php
}
LazySizes Library
The plugin uses the LazySizes library with custom configuration:
// Assets enqueued
'visual-portfolio-lazyload' => 'build/assets/js/lazyload' ,
'visual-portfolio-lazysizes-cfg' => 'build/assets/js/lazysizes-cfg' ,
WordPress Security
Allowed Protocols
The plugin allows data: URIs for placeholder images:
// class-images.php:245
public static function kses_allowed_protocols ( $protocols ) {
$protocols [] = 'data' ;
return $protocols ;
}
Allowed Attributes
Lazy loading attributes are whitelisted for wp_kses:
// class-images.php:216
public static function allow_lazy_attributes ( $allowed_tags ) {
$img_attributes = array_merge (
$allowed_tags [ 'img' ],
[
'data-src' => 1 ,
'data-sizes' => 1 ,
'data-srcset' => 1 ,
'data-no-lazy' => 1 ,
'loading' => 1 ,
]
);
return $allowed_tags ;
}
Image Size Management
Custom Image Sizes
The plugin registers custom image sizes for responsive loading:
// class-images.php:67
public static function add_image_sizes () {
add_image_size ( 'vp_sm' , $sm , 9999 );
add_image_size ( 'vp_md' , $md , 9999 );
add_image_size ( 'vp_lg' , $lg , 9999 );
add_image_size ( 'vp_xl' , $xl , 9999 );
add_image_size ( 'vp_sm_popup' , $sm_popup , 9999 );
add_image_size ( 'vp_md_popup' , $md_popup , 9999 );
add_image_size ( 'vp_xl_popup' , $xl_popup , 9999 );
}
GIF Handling
Animated GIFs always use full size to preserve animation:
// class-images.php:202
if ( $mime_type && 'image/gif' === $mime_type ) {
$size = 'full' ;
}
Hooks and Filters
Disable Lazy Loading
add_filter ( 'vpf_images_lazyload' , '__return_false' );
Modify Blocked Attributes
add_filter ( 'vpf_lazyload_images_blocked_attributes' , function ( $attributes ) {
$attributes [] = 'data-custom-lazy' ;
return $attributes ;
});
Modify Blocked Classes
add_filter ( 'vpf_lazyload_images_blocked_classes' , function ( $classes ) {
$classes [] = 'custom-no-lazy' ;
return $classes ;
});
Skip Specific Images
add_filter ( 'vpf_lazyload_skip_image_with_attributes' , function ( $skip , $attributes ) {
if ( isset ( $attributes [ 'class' ] ) && strpos ( $attributes [ 'class' ], 'hero-image' ) !== false ) {
return true ; // Skip lazy loading
}
return $skip ;
}, 10 , 2 );
Modify Image Attributes
add_filter ( 'vpf_lazyload_images_new_attributes' , function ( $attributes ) {
// Add custom data attributes
$attributes [ 'data-custom' ] = 'value' ;
return $attributes ;
});
Customize Placeholder
add_filter ( 'vpf_lazyload_image_placeholder' , function ( $placeholder ) {
// Return custom placeholder
return 'data:image/svg+xml,...' ;
});
Performance Benefits
Reduces initial page weight by 50-70%
Only loads images in viewport and near-viewport
Dramatically improves Time to Interactive (TTI)
Users only download images they view
Especially beneficial on mobile connections
Reduces server bandwidth costs
Faster perceived page load
Smooth scrolling performance
Maintains layout stability with placeholders
Best Practices
Always specify dimensions : Include width/height attributes for proper placeholder generation
Exclude critical images : Use data-skip-lazy on above-the-fold hero images
Test on mobile : Verify smooth scrolling and loading on mobile devices
Use fetchpriority : Add fetchpriority="high" to important images to exclude them
Monitor Core Web Vitals : Check Cumulative Layout Shift (CLS) improvements
Troubleshooting
Images Not Loading
Check if lazy loading is conflicting with other plugins:
add_filter ( 'vpf_images_lazyload' , '__return_false' );
Layout Shift Issues
Ensure images have width/height attributes:
< img src = "..." width = "800" height = "600" alt = "..." >
Exclude Specific Pages
add_action ( 'wp' , function () {
if ( is_page ( 'contact' ) ) {
add_filter ( 'vpf_images_lazyload' , '__return_false' );
}
});
Related Features