お問い合わせ

SWELL スクリプト遅延読み込みがスマホで動かない!高速化設定の不具合原因と対処方法

SWELLの高速化設定にある『スクリプト遅延読み込み』はスマホで動かない不具合がありそうです。

SWELLの『スクリプト遅延読み込み』はflying scriptとほぼ同じ機能です。

スマホでスクロールしてもjavascriptが読み込まれてない

SWELLの『スクリプト遅延読み込み』でtwitterやinstagramなどのSNSのjavascriptを遅延読み込み指定すると、指定したscriptは指定した時間が経過するか、ユーザー操作があるまで読み込みが遅延されます。

PCだと確かにそういう動きになります。

しかし、スマホでサイトを確認すると、遅延読み込みをした埋め込みSNSまでスクロールしても全然読み込まれません。

しばらくすると、読み込まれてSNSの埋め込みが表示されます。

スマホの場合は、ユーザー操作があっても、遅延時間が経過するまでスクリプトが読み込まれないようです。

ちなみに、iOSでしか確認していません。Androidだと動くのかは知りません。

SWELLとFlying Scriptのソースの違いを確認

SWELLの遅延読み込み部分のソース

userEventsの部分でイベントを定義しています。

この部分の後半部分にある"touchmove touchend","touchstart touchend"の部分が反応していないようです。

<script type="text/javascript" id="swell-lazyloadscripts">
(function () {
	const timeout = <?php echo esc_attr( intval( $timeout ) * 1000 ); ?>;
	const loadTimer = timeout ? setTimeout(loadJs,timeout) : null;
	const userEvents = ["mouseover","keydown","wheel","touchmove touchend","touchstart touchend"];
	userEvents.forEach(function(e){
		window.addEventListener(e,eTrigger,{passive:!0})
	});
	function eTrigger(){
		loadJs();
		if(null !== loadTimer) clearTimeout(loadTimer);
		userEvents.forEach(function(e){
			window.removeEventListener(e,eTrigger,{passive:!0});
		});
	}
	function loadJs(){
		document.querySelectorAll("script[data-swldelayedjs]").forEach(function(el){
			el.setAttribute("src",el.getAttribute("data-swldelayedjs"));
		});
	}
})();
</script>

Flying Scriptの遅延読み込み部分のソース

Flying Scriptが遅延読み込みを開始するイベントは、["mouseover", "keydown", "touchstart", "touchmove", "wheel"]となっています。

< script type = "text/javascript" id = "flying-scripts" >
  const loadScriptsTimer = setTimeout(loadScripts, <?php echo $timeout ?> * 1000);
const userInteractionEvents = ["mouseover", "keydown", "touchstart", "touchmove", "wheel"];
userInteractionEvents.forEach(function (event) {
  window.addEventListener(event, triggerScriptLoader, {
    passive: !0
  })
});

function triggerScriptLoader() {
  loadScripts();
  clearTimeout(loadScriptsTimer);
  userInteractionEvents.forEach(function (event) {
    window.removeEventListener(event, triggerScriptLoader, {
      passive: !0
    })
  })
}

Flying Script側が正解なのでは?

SWELLとFlying Scriptのjavascript部分は、ほとんどソースコードが同じなのですが、ユーザー操作を検出するイベントが違いました。

Flying Scriptはスマホでもユーザー操作があれば遅延読み込みを開始しますが、SWELLのスクリプト遅延読み込みは動作しません。

Flying Script側がユーザーの意図通りに動作していますので、Flying Script側が正しいのではないかと思います。

なんでみんな気が付かないの?

スマホの実機でしか再現しないからなのか、この不具合は話題になりません。

Google AnalyticsやGoogle Tag managerとか遅延読み込みしていると、初期設定だと5秒とか読み込まれないままです。

もちろんアドセンスも同じです。アドセンスの場合は露骨に読み込まれないのがわかりますし、UXがとても悪くなります。

WP ROCKETには同じ機能があります。SWELLの上級ユーザーたちはWP ROCKETのアフィリエイターなので、そちらの機能を有効化している場合はSWELLのスクリプト遅延読み込みの不具合は見えなくなります。

不具合回避方法はあるのか?

SWELLのスクリプト遅延読み込みの不具合を回避するには3つの方法があります。

  • SWELLフォーラムで確認
  • Flying Scriptを使う
  • 不具合javascriptを差し替える

SWELLフォーラムで確認

正規の手順としては、SWELLのフォーラムに不具合として報告するのが良いと思います。

Flying Scriptを使う

SWELLの遅延読み込み機能をOFFにして、Flying Scriptを使うというのが回避策になります。

不具合javascriptを差し替える

SWELLの機能として、不具合回避するのであれば、javascriptを差し替える方法があります。

SWELLのスクリプト遅延読み込みのjavascriptを読み込む部分は、wp_print_footer_scriptsフックで読み込まれています。そのフックを解除し、javascriptを修正して自前の関数を読み込むようにフックを再度かければ回避できます。

フックの使い方については以前別の記事で説明しています。

namespace SWELL_Theme\Rewrite_Html;

if ( ! is_admin() ) {
	add_action( 'wp', function() {
		if ( \SWELL_Theme::is_use( 'delay_js' ) ) {
			remove_action( 'wp_print_footer_scripts', __NAMESPACE__ . '\scripts_inject' );
			add_action( 'wp_print_footer_scripts', __NAMESPACE__ . '\scripts_inject2' );
		}
	},11 );
}

function scripts_inject2() {
	$timeout = \SWELL_Theme::get_option( 'delay_js_time' ) ?: 0;
	?>
<script type="text/javascript" id="swell-lazyloadscripts">
(function () {
	const timeout = <?php echo esc_attr( intval( $timeout ) * 1000 ); ?>;
	const loadTimer = timeout ? setTimeout(loadJs,timeout) : null;
//	const userEvents = ["mouseover","keydown","wheel","touchmove touchend","touchstart touchend"];
	const userEvents = ["mouseover","keydown","wheel","touchmove","touchend","touchstart"];
	userEvents.forEach(function(e){
		window.addEventListener(e,eTrigger,{passive:!0})
	});
	function eTrigger(){
		loadJs();
		if(null !== loadTimer) clearTimeout(loadTimer);
		userEvents.forEach(function(e){
			window.removeEventListener(e,eTrigger,{passive:!0});
		});
	}
	function loadJs(){
		document.querySelectorAll("script[data-swldelayedjs]").forEach(function(el){
			el.setAttribute("src",el.getAttribute("data-swldelayedjs"));
		});
	}
})();
</script>
	<?php
}

まとめ

SWELLのスクリプト遅延読み込みがスマホ(iOSで確認)で動作していない件、気が付いた時には結構衝撃でした。早く修正されることを期待したいと思います。

他の人にもシェアしてね
コメントを閉じる

コメント

コメントする

コメントは日本語で入力してください。(スパム対策)

クリックできる目次