レ点腫瘍学ノート

2021-06-23

画像をref.inc.phpで貼り付ける時に少し速く

Top > pukiwikiカスタマイズ箇所 > 2021 > 画像をref.inc.phpで貼り付ける時に少し速く

pukiwikiのrefプラグイン(ref.inc.php)はページに画像を貼り付ける時に重宝します。このプラグインに少し手を入れることでwebp fallbackを実現したりしていました。

しかし、画像のサイズを取得する設定にしているとこのプラグインは若干重いので、ローカルサーバーの画像を表示するときは相対パスに変換することで若干速くしています。差はそれほど大きくは無さそうですが…

27行目付近

これは当然TRUEにしておきます。画像ファイルを取得しておかないとlazyloadingがうまく動作しません。

// URL指定時に画像サイズを取得するか
define('PLUGIN_REF_URL_GET_IMAGE_SIZE', TRUE); // FALSE, TRUE

しかしこのサイズを取得する設定をTRUEにするとrefプラグインがかなり重くなるのが考え物です。240行目付近で画像のサイズを取得する場所がありますが、$size = @getimagesize($namesize);の1行で画像サイズを取得しに行くところが意外に重い。特に外部のサーバーの場合はなおさらです。絶対パス(URL)で記載しているが指し示すURL自体はローカルサーバーである場合にはこれを相対パスに書き換えることでいくらかでもpukiwiki全体およびrefプラグインを軽くします。

40行目付近

各種設定項目の下にこのような設定項目も新設しておきます。TRUEにすれば(jpegやpngと同名のwebpファイルがある場合に限り)webp fallbackが動作します。

.htaccessでwebpの振り分けを行うサイトではファイル名はimage.jpg.webpやimage.png.webpとしているところもあるようですが、ここでは普通にimage.webpとしています。

// フォルダにWEBP画像を探してみてファイルがなければfallbackするか
define('PLUGIN_REF_WEBP_FALLBACK', TRUE); // FALSE, TRUE

240行目付近

$nameがpukiwikiの設置されているURL($script)を含むとき、相対パス化したファイルで@getimagesizeをしています。絶対パスより少し速いんじゃないかと…

if ($is_image && PLUGIN_REF_URL_GET_IMAGE_SIZE && (bool)ini_get('allow_url_fopen')) {
 if(strpos($name,$script) !== false){
  $namesize = str_replace($script, '', $name);
 } else {
  $namesize = $name;
 }
 $size = @getimagesize($namesize);
 if (is_array($size)) {
  $width  = $size[0];
  $height = $size[1];
  $info   = $size[3];
 }
}

350行目付近

下記のようにしてwebp fallbackを実現しています。なお、lazyloadにはlazysizes.jsプラグインではなくnativeのloading="lazy"を使っています。pagespeed insightのスコアは、このnativeのloading="lazy"のほうがわずかに良さそう。

if ($is_image) { // 画像
 if ( PLUGIN_REF_WEBP_FALLBACK ) {
  if(strpos($url,$script) !== false){
   $url = str_replace($script, '', $url); //ローカルサーバーでは相対パスにする
  }
  $urlwebp = pathinfo($url, PATHINFO_DIRNAME ) . '/' . pathinfo($url, PATHINFO_FILENAME ) . '.webp'; //同じディレクトリにwebp画像があるか探す
 }
 if ( PLUGIN_REF_WEBP_FALLBACK && file_exists($urlwebp) ) {
  $params['_body'] = "<picture><source type=\"image/webp\" srcset=\"$urlwebp\"><img class=\"refimg\" loading=\"lazy\" src=\"$url\" alt=\"\" $info></picture>"; //webp画像fallback
 } else {
  $params['_body'] = "<img class=\"refimg\" loading=\"lazy\" src=\"$url\" alt=\"\" $info>";
 }
 if (! $params['nolink'] && $url2) {
  $params['_body'] = "<a href=\"$url2\" title=\"$title\">{$params['_body']}</a>";
 }
} else {
 $icon = $params['noicon'] ? '' : FILE_ICON;
 $params['_body'] = "<a href=\"$url\" title=\"$info\">$icon$title</a>";
}

あるいは、safariがnativeのloading="lazy"に未対応なのが気になるという方でlazysizes.jsを使う場合は下記のようになります。

if ($is_image) { // 画像
 if ( PLUGIN_REF_WEBP_FALLBACK ) {
  if(strpos($url,$script) !== false){
   $url = str_replace($script, '', $url); //ローカルサーバーでは相対パスにする
  }
  $urlwebp = pathinfo($url, PATHINFO_DIRNAME ) . '/' . pathinfo($url, PATHINFO_FILENAME ) . '.webp'; //同じディレクトリにwebp画像があるか探す
 }
 if ( PLUGIN_REF_WEBP_FALLBACK && file_exists($urlwebp) ) {
  $params['_body'] = "<picture><source type=\"image/webp\" data-srcset=\"$urlwebp\"><img class=\"lazyload refimg\" src=\"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"$url\" alt=\"\" $info></picture>"; //webp画像fallback
 } else {
  $params['_body'] = "<img class=\"lazyload refimg\" src=\"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"$url\" alt=\"\" $info>";
 }
 if (! $params['nolink'] && $url2) {
  $params['_body'] = "<a href=\"$url2\" title=\"$title\">{$params['_body']}</a>";
 }
} else {
 $icon = $params['noicon'] ? '' : FILE_ICON;
 $params['_body'] = "<a href=\"$url\" title=\"$info\">$icon$title</a>";
}

さらに、これだとCLSがわずかに発生してしまいます。なのでwebpのみdata-srcsetを使わずsrcsetとしておくという逃げ道を取ることもできます…(実はpictureタグの中のwebpはlazyloadしなくてもjpgやpngさえlazyloadしていればCore Web Vitalに悪影響がないっぽい)。

プラグインの改造は必ずバックアップを取ってから行います。

親要素のDIVボックス全体にリンク範囲を広げる方法(改良版)親要素全体をリンクのクリック範囲とするのはタイルデザインなどのウェブサイトでは多用する技術です。しかしタイルデザイン全体のどこをクリックしてもリンクにつながるようにするには一工夫が必要で、ネットを見てもいくつかの方法があるようです。方法1 当サイトで始めに使ってい
以前に「Lazysizes.jsを使うとCLSが発生する問題」の記事を書いていました。画像の遅延読み込みを可能にするJavaScriptであるlazysizes.jsを使うと、CLSが生じてpagespeed insightの評価スコアが下がってしまうという問題です。より具体的には、1x1ピクセルのサイズのスペースホルダ画像を使って