お問い合わせはコチラから

lazyloaderプラグインで先頭画像をlazyload除外する

サイト運営

Native LazyloadにWordpressが対応したこともあり、Lazyloadプラグインを有効化している人は徐々に減ってきていると思います。

Native Lazyloadは細かい部分で制御が効かないので、いまだにプラグインを使用している人も多いかもしれません。

WordPress5.9では、FCP対応で先頭の画像をLazyloadから除外する機能が追加されました。この機能は既存のLazyloadプラグインでは対応していないものが多いです。

autoptimzeのlazyload機能には先頭から何枚目までの画像をlazyload除外する機能があります。autoptimizeのlazyloadを使うのであれば今回の記事は関係ありません。

Autoptimize
Autoptimize は、以下を最適化することでサイトの反応を高速にします。JavaScript、CSS、画像 (遅延読み込みを含む)、HTML、Google フォント、非同期 JavaScript、また邪魔な Emoji の除去など。

この記事では既存のLazyloadプラグインの中でLazyloaderプラグインを使用した時に、先頭画像をlazyloadから除外する方法についてまとめています。

Lazyloadプラグインの定番は?

私が使っている定番のLazyload pluginは2つです。

  • rocket-lazy-load
  • Lazyloader

rocket-lazy-load

もし、わたしが、Lazyloadプラグインを導入するのであれば、WP RocketのLazyloadプラグインを使います。ただ、このプラグイン致命的な欠点があります。外部画像をlazyloadできません。

また、もともと有料プラグインの一部が無料で公開されているため、とてもサポートがプアです。初心者の方にはおススメできません。

LazyLoad Plugin – Lazy Load Images, Videos, and Iframes
The best free lazy load plugin for WordPress. Lazy load images, videos, and iframes to improve performance and Core Web ...

Lazyloader

外部画像が多いサイトの場合は、lazysizeを使ったLazyloaderプラグインがおススメです。

Lazy Loader
Lazy loading plugin that supports images, iFrames, video and audio elements and uses the lightweight lazysizes script. W...

lazyloaderプラグインは先頭画像のlazyload除外に未対応

lazyloaderプラグインは、地味ながらもかなり高機能なプラグインです。

しかし、FCP対応のため先頭画像をlazyloadから除外する機能は他のLazyloadプラグイン同様にまだありません。

もちろん、class指定で除外する機能はありますので、記事の先頭に必ずアイキャッチ画像があり、それを除外したい場合はclass指定で除外することも可能だと思います。ただし、決まった画像があるとも限らないのでthe_contentの先頭画像をlazyloadから除外する機能が無いのは残念です。

プラグイン作者が先頭画像をLazyload除外するスニペットを公開

プラグインの作者が先頭画像にLazyload除外のclassを追加するスニペットを公開しています。

このスニペットをfunctions.phpに張り付ければ、先頭画像をLazyloadから除外できます。

<?php
/**
 * Add skip-lazy class to first image in content.
 */
add_filter( 'the_content', function( $content ) {
	// Check if we have no content.
	if ( empty( $content ) ) {
		return $content;
	}

	// Check if content contains caption shortcode.
	if ( has_shortcode( $content, 'caption' ) ) {
		return $content;
	}

	if ( ! class_exists( '\Masterminds\HTML5' ) || ! class_exists( '\FlorianBrinkmann\LazyLoadResponsiveImages\Helpers' ) ) {
		return $content;
	}

	// Disable libxml errors.
	libxml_use_internal_errors( true );

	// Create new HTML5 object.
	$html5 = new \Masterminds\HTML5( array(
		'disable_html_ns' => true,
	) );

	// Preserve html entities and conditional IE comments.
	// @link https://github.com/ivopetkov/html5-dom-document-php.
	$content = preg_replace( '/&([a-zA-Z]*);/', 'lazy-loading-responsive-images-entity1-$1-end', $content );
	$content = preg_replace( '/&#([0-9]*);/', 'lazy-loading-responsive-images-entity2-$1-end', $content );
	$content = preg_replace( '/<!--\[([\w ]*)\]>/', '<!--[$1]>-->', $content );
	$content = str_replace( '<![endif]-->', '<!--<![endif]-->', $content );

	// Load the HTML.
	$dom = $html5->loadHTML( $content );

	$xpath = new \DOMXPath( $dom );

	// Get all image nodes.
	// @link https://stackoverflow.com/a/19348287/7774451.
	$nodes = $xpath->query( "//img[not(ancestor-or-self::noscript)]" );

	$is_modified = false;

	$counter = 0;

	foreach ( $nodes as $node ) {
		$counter++;
		if ( $counter > 1 ) {
			break;
		}

		// Check if it is an element that should not be lazy loaded.
		// Get the classes as an array.
		$node_classes = explode( ' ', $node->getAttribute( 'class' ) );

		if ( in_array( 'skip-lazy', $node_classes ) ) {
			continue;
		}

		// Check if it is one of the supported elements and support for it is enabled.
		if ( 'img' === $node->tagName ) {
			// Get the classes.
			$classes = $node->getAttribute( 'class' );

			// Add lazyload class.
			$classes .= ' skip-lazy';

			// Set the class string.
			$node->setAttribute( 'class', $classes );
			$is_modified = true;
		}
	}

	if ( true === $is_modified ) {
		$helpers = new \FlorianBrinkmann\LazyLoadResponsiveImages\Helpers();
		$content = $helpers->save_html( $dom, $html5 );
	}

	// Restore the entities and conditional comments.
	// @link https://github.com/ivopetkov/html5-dom-document-php/blob/9560a96f63a7cf236aa18b4f2fbd5aab4d756f68/src/HTML5DOMDocument.php#L343.
	if ( strpos( $content, 'lazy-loading-responsive-images-entity') !== false || strpos( $content, '<!--<script' ) !== false ) {
		$content = preg_replace('/lazy-loading-responsive-images-entity1-(.*?)-end/', '&$1;', $content );
		$content = preg_replace('/lazy-loading-responsive-images-entity2-(.*?)-end/', '&#$1;', $content );
		$content = preg_replace( '/<!--\[([\w ]*)\]>-->/', '<!--[$1]>', $content );
		$content = str_replace( '<!--<![endif]-->', '<![endif]-->', $content );
	}

	return $content;
}, 99 );
functions.php
GitHub Gist: instantly share code, notes, and snippets.

このスニペットは、the_contentフィルターを通った先頭画像が対象になります。アイキャッチ画像などthe_contentフィルターを通らないものは対象になりません。

アイキャッチ画像はclassで除外して、アイキャッチ画像が無い場合はこのスニペットで除外するというのが正しい運用かと思います。

アイキャッチ画像がある場合と無い場合の判断は、has_post_thumbnail関数で出来ますので、スニペットの先頭で、判定してreturnすればよろしいかと思います。

LazyloaderプラグインでpictureタグをLazyload除外するには?

pictureタグで囲まれたimgタグなどをlazyloadから丸ごと除外するには、skip-lazyクラスを追加するのではなく、data-skip-lazy属性をpictureタグに追加する必要があります。

<picture data-skip-lazy>
<source>
<img>
</picture>

まとめ

今後はNativeLazyloadが主流になっていき、Lazyloadプラグインの需要はますます下がっていくと思います。しかし、いままでLazyloadプラグインが積み重ねた歴史がありますので、NativeLazyloadで対応していない便利なlazyload機能はまだまだ有効です。

この記事を書いた人
ブーン

はるばる日本よりオランダ王国へやってまいりました。
自分の経験が少しでも参考になれば嬉しいです。
お問い合わせは、『こちら』からお願い致します。

\ブーンをフォロー/
スポンサーリンク
サイト運営
\シェアお願いします!/
\ブーンをフォロー/
こんな記事も読まれています

失敗しないレンタルサーバーランキング

mixhost

不正アクセスに強くて使いやすいおススメサーバー
\本サイトで利用中/
メリット①:自動ウィルス駆除対応
メリット②:サイトの表示速度が速い!
メリット③:転送量の上限が多い!
メリット④:自由にプラン変更ができ、アクセス増にも対応できる!
メリット⑤:バックアップデータが無料で復元できる!
メリット⑥:Wordpressが簡単にインストールできる!
メリット⑦:どのプランでも初期費用が無料!
メリット⑧:10日間の無料お試し期間と30日の返金保証!

Conoha Wing

国内Wordpress最速の最強サーバー
メリット①:圧倒的な表示速度
メリット②:レンタルサーバーと独自ドメインがセットでお得◎
メリット③:プラン変更はすべてのプランで自由自在
メリット④:一か月の利用転送量の制限が緩い(9TB~)
メリット⑤:WordPresサイトの移行が簡単

エックスサーバー

国内シェアNo1の安定性と実績が魅力。ALL SSDで死角なしの万能サーバー。
メリット①:サイトの表示速度が安定して速い!
メリット②:アクセス負荷に強くて安定性が高い!
メリット③:24時間365日の充実サポートで安心!電話サポートもあり!
メリット④:転送量が多い!
メリット⑤:自動バックアップ機能付き!
メリット⑥:WordPressが簡単にインストールできる!
メリット⑦:10日の無料お試し期間がある!

タイトルとURLをコピーしました