Native Lazyload とは?
WordPress のプラグインで Google が作成した Native Lazyload というものがあります。
Chrome ではブラウザ側で Lazyloading 機能に対応しているので、Chrome の場合はこれを有効に、それ以外のブラウザはフォールバックスクリプトを動かして、WordPress 内の画像、iframeの遅延読み込みを有効にさせるプラグインです。
とても便利。でもページ内アンカーがあると・・・・・・
プラグインを有効にするだけで Lazy loading が有効になるのでお手軽便利なプラグインなのですが、ページ内アンカーがあり、ページ内に画像を使っていると、アンカーポイントがずれてしまいます。
原理として、スクロールに応じて画像を読み込むため、ブロック内に画像の高さが計算されていません。
何も表示されていないところに、スクロールされて初めて画像読み込みが開始されるので、読み込み完了後に画像の高さ分、ブロックが作られます。そのため、一気にページ内を移動するアンカーとの相性が悪いです。
(実際の操作感として、一気に移動後、画像読み込みに応じて画面が下にずれていく感じです)
ページ内アンカーがある場合のみ無効にしたい
アンカーで目的の項目に移動したつもりなのに、実際に移動できないのは、とてもストレスです。UI として失格です。
そのため、ページ内アンカーがあるページのみ無効にしたくなります。
functions.php に以下記述で対応します。
define('SKIP_LAZY_PAGE', ['menu', 'price']);
/**
* 特定のページでNative Lazyload を無効に
* Native Lazyload に用意されているフォールバックを特定のページに適用
*/
function disable_per_page_plugin() {
if(is_page(SKIP_LAZY_PAGE)){
add_filter( 'native_lazyload_fallback_script_enabled', '__return_false' );
}
}
add_action( 'parse_query', 'disable_per_page_plugin' );
/**
* 特定のページでNative Lazyload を無効に
* マッチしたら、 add_action で the_content に skip-lazy を適用
*/
function skip_lazyload()
{
if(!is_page(SKIP_LAZY_PAGE)) return false;
add_action( 'the_content', 'content_add_class_skip_lazy');
}
add_action( 'wp', 'skip_lazyload' );
/**
* 本文内から画像タグを見つけて skip-lazy クラスを付与
*/
function content_add_class_skip_lazy($content) {
if(strpos($content, "<img ") === false) return $content;
return str_replace('<img ','<img class="skip-lazy" ', $content);
}
native_lazyload_fallback_script_enabled
というフォールバックが用意されているので、これをページ単位でまず適用させます。
これを実行すると、他ブラウザで適用させるためのスクリプト展開が止まります。
実行タイミングは is_page
が実行される早めのタイミングで行います。
init
とかだと早すぎたです。
これだけだと Chrome 用のネイティブなのが動いてしまうので( loading="lazy" )、これに対応する方法をいろいろ探していましたが、class="skip-lazy"
を付与すると無効になるようだったので、これに対応させるため、本文内の画像タグに対して加工します。
ただ、固定ページ、なおかつ class 付与のされていないことを前提にしているので、 class 付与されている事を考慮する場合は丁寧な正規表現の記述が必要です。。