WordPress图片延迟加载LazyLoading

前言

WordPress原生功能Lazy Loading支持懒加载功能,应用场景:首页图片及内容量较大,可以缓冲加载,滚动条滚到的地方进行加载,没有显示的地方不进行加载,这样可以大大的节省服务器和带宽资源,更快的加载首页。

代码示例

/**
 * Initialise filters and actions.
 */
function _wp_lazy_loading_initialize_filters() {
	// The following filters would be merged into core.
	foreach ( array( 'the_content', 'the_excerpt', 'widget_text_content' ) as $filter ) {
		add_filter( $filter, 'wp_filter_content_tags' );
	}
	// The following filters are only needed while this is a feature plugin.
	add_filter( 'wp_get_attachment_image_attributes', '_wp_lazy_loading_add_attribute_to_attachment_image' );
	add_filter( 'get_avatar', '_wp_lazy_loading_add_attribute_to_avatar' );
	// The following relevant filter from core should be removed when merged.
	remove_filter( 'the_content', 'wp_make_content_images_responsive' );
}
add_action( 'plugins_loaded', '_wp_lazy_loading_initialize_filters', 1 );
/**
 * Adds loading attribute to an avatar image tag.
 */
function _wp_lazy_loading_add_attribute_to_avatar( $avatar ) {
	if ( wp_lazy_loading_enabled( 'img', 'get_avatar' ) && false === strpos( $avatar, ' loading=' ) ) {
		$avatar = str_replace( '<img ', '<img loading="lazy" ', $avatar );
	}
	return $avatar;
}
/**
 * Adds loading attribute to an attachment image tag.
 */
function _wp_lazy_loading_add_attribute_to_attachment_image( $attr ) {
	if ( wp_lazy_loading_enabled( 'img', 'wp_get_attachment_image' ) && ! isset( $attr['loading'] ) ) {
		$attr['loading'] = 'lazy';
	}
	return $attr;
}
/**
 * Determine whether to add the `loading` attribute to the specified tag in the specified context.
 */
function wp_lazy_loading_enabled( $tag_name, $context ) {
	// By default add to all 'img' tags.
	// See https://html.spec.whatwg.org/multipage/embedded-content.html#attr-img-loading
	$default = ( 'img' === $tag_name );
	/**
	 * Filters whether to add the `loading` attribute to the specified tag in the specified context.
	 */
	return (bool) apply_filters( 'wp_lazy_loading_enabled', $default, $tag_name, $context );
}
/**
 * Filters specific tags in post content and modifies their markup.
 */
function wp_filter_content_tags( $content, $context = null ) {
	if ( null === $context ) {
		$context = current_filter();
	}
	$add_loading_attr = wp_lazy_loading_enabled( 'img', $context );
	if ( false === strpos( $content, '<img' ) ) {
		return $content;
	}
	if ( ! preg_match_all( '/<img\s[^>]+>/', $content, $matches ) ) {
		return $content;
	}
	// List of the unique `img` tags found in $content.
	$images = array();
	foreach ( $matches[0] as $image ) {
		if ( preg_match( '/wp-image-([0-9]+)/i', $image, $class_id ) ) {
			$attachment_id = absint( $class_id[1] );
			if ( $attachment_id ) {
				/*
				 * If exactly the same image tag is used more than once, overwrite it.
				 * All identical tags will be replaced later with 'str_replace()'.
				 */
				$images[ $image ] = $attachment_id;
				continue;
			}
		}
		$images[ $image ] = 0;
	}
	// Reduce the array to unique attachment IDs.
	$attachment_ids = array_unique( array_filter( array_values( $images ) ) );
	if ( count( $attachment_ids ) > 1 ) {
		/*
		 * Warm the object cache with post and meta information for all found
		 * images to avoid making individual database calls.
		 */
		_prime_post_caches( $attachment_ids, false, true );
	}
	foreach ( $images as $image => $attachment_id ) {
		$filtered_image = $image;
		// Add 'srcset' and 'sizes' attributes if applicable.
		if ( $attachment_id > 0 && false === strpos( $filtered_image, ' srcset=' ) ) {
			$filtered_image = wp_img_tag_add_srcset_and_sizes_attr( $filtered_image, $context, $attachment_id );
		}
		// Add 'loading' attribute if applicable.
		if ( $add_loading_attr && false === strpos( $filtered_image, ' loading=' ) ) {
			$filtered_image = wp_img_tag_add_loading_attr( $filtered_image, $context );
		}
		if ( $filtered_image !== $image ) {
			$content = str_replace( $image, $filtered_image, $content );
		}
	}
	return $content;
}
/**
 * Adds `loading` attribute to an existing `img` HTML tag.
 */
function wp_img_tag_add_loading_attr( $image, $context ) {
	/**
	 * Filters the `loading` attribute value. Default `lazy`.
	 */
	$value = apply_filters( 'wp_img_tag_add_loading_attr', 'lazy', $image, $context );
	if ( $value ) {
		if ( ! in_array( $value, array( 'lazy', 'eager' ), true ) ) {
			$value = 'lazy';
		}
		return str_replace( '<img', '<img loading="' . $value . '"', $image );
	}
	return $image;
}
/**
 * Adds `srcset` and `sizes` attributes to an existing `img` HTML tag.
 */
function wp_img_tag_add_srcset_and_sizes_attr( $image, $context, $attachment_id ) {
	/**
	 * Filters whether to add the `srcset` and `sizes` HTML attributes to the img tag. Default `true`.
	 */
	$add = apply_filters( 'wp_img_tag_add_srcset_and_sizes_attr', true, $image, $context, $attachment_id );
	if ( true === $add ) {
		$image_meta = wp_get_attachment_metadata( $attachment_id );
		return wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id );
	}
	return $image;
}

使用方法

代码示例放在主题模板中的函数文件中(functions.php),清除服务器缓存或浏览器缓存再试