レ点腫瘍学ノート

pukiwikiカスタマイズ箇所/2021/画像をref.inc.phpで貼り付ける時に少し速く の履歴の現在との差分(No.3)


#author("2021-06-23T03:34:16+09:00;2021-06-23T00:10:11+09:00","default:tgoto","tgoto")
#ref(https://oncologynote.com/img/88619a062d.jpg,nolink)
#author("2024-04-19T17:25:53+09:00;2024-03-29T18:08:28+09:00","default:tgoto","tgoto")
#ref(https://oncologynote.jp/img/88619a062d.jpg,eager,nolink)

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

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

*27行目付近 [#c51b191e]

これは当然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行目付近 [#t11999d6]

各種設定項目の下にこのような設定項目も新設しておきます。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行目付近 [#l65149c6]
$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行目付近 [#z4edd7d8]

下記のようにして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に悪影響がないっぽい)。

* ネイティブの遅延読み込みでeagerも選択できるようにする(2024.3.29追記) [#gbba4847]

全てのrefで読み込む画像にloading="lazy"を付けているとPagespeed inshightでのスコアが下がり、トップに表示される画像はむしろ遅延読み込みしないようにするように注意されます。そこで、引数にeagerを付けた場合はloading="lazy"ではなくloading="eager"を付けるようにします。

使い方としては、下記のような書き方になります。

 #ref(https://oncologynote.jp/img/88619a062d.jpg,eager,nolink)

** 126行目付近 [#we85a35d]

下記のパラメータを追加

 'eager'  => FALSE, // 画像を遅延読み込みしない

** 365行目付近 [#g39dc5fa]

遅延読み込みしたくない画像は、eagerと追加することにより遅延読み込みを回避できるようにしておきます。

 if ( $params['eager']) {
 $lazy = "eager";
 } else {
 $lazy = "lazy";
 }
 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=\"$title\" width=\"$width\" height=\"$height\" ></picture>"; //webp画像fallback
 } else {
 $params['_body'] = "<img class=\"refimg\" loading=\"$lazy\" src=\"$url\" alt=\"$title\" width=\"$width\" height=\"$height\" >";
 }

この遅延や見込み回避を使うときは、以下のように評価します。

 #ref(xxxx.jpg,eager)

プラグインの改造は必ずバックアップを取ってから行います。
なお、当サイトのref.inc.phpは適宜修正しながら使っていますので色々と改装していますが、2024.3.29時点のものを置いておきます。

#ogpi(https://oncologynote.com/?59a15c9237)
#ogpi(https://oncologynote.com/?0323aec317)
&attachref(ref.inc.php);

#ogpi(https://oncologynote.jp/?59a15c9237)
#ogpi(https://oncologynote.jp/?0323aec317)
#pcomment