投稿記事内の画像を自動でwebp形式に変換するために色々と調べていましたが、結論としては画像データが読み込まれる前に変換する方法はない!ということでした。変換自体はできるのですが、どうしてもデータの二重読み込みになってしまう。もしかしたらLazyloadで遅延読み込みしている画像に関しては読み込まれる前の変換が可能なのかもしれませんが。方法がないならないでいいのですけどね。別に僕の過去記事の画像形式を苦労してまで変換する意味はないですし。ただ今後のためにも方法があるのかどうか調べたかっただけで。

では僕の悪戦苦闘を少し紹介します。Bloggerで記事のコードは<data.post.body/>の中に入っているわけなので、なんとかしてJavaScriptで中身を読み込めないか試行錯誤していました。一旦display:none;で非表示にしておいてコードだけ取得する…のは意味がないので却下。どうもdisplay:none;で非表示にしていてもデータは読み込まれているみたいなので。画像データを二重読み込みしては意味がないですからね。僕はOGP画像をdisplay:none;で非表示にしてコードに記載していることが多々あったので反省。これからはちゃんとサイズをs1に変えておこう(s0だとオリジナルサイズになる)。次に<noscript>で囲って非表示(ブラウザがJavaScript対応のときだけですが)にするのはどうだろうか?と試してみましたが、それをするとタグで囲まれた要素自体を取得できなかったので断念。JavaScriptで<data.post.body/>のタグデータを使用できれば話は早いのに!

次に試したのはイベントのタイミング。HTMLの初期文書が解釈された時点で発生して画像などの読み込み完了をまたずに実行できるDOMContentLoadedを勧めている記事が多かったので試してみました。が、画像データの読み込みの方が早かった。Lazyloadで遅延読み込みをしている部分に関してはもしかしたら書き換えができるのかもしれませんが、僕の求めている答えじゃなかった。その後も検索を続ける。海外の掲示板などで僕と同じ疑問に対する返答があったので確認してみると…これも違った。そうじゃない…そういうことじゃないんだ!スティーブ!と心の中で叫んでました。そしてさらに試行錯誤しながら検索を続けていると興味深い情報が。
これか?これが僕の求めている情報なのか?と期待が膨らみました。ですが知識の少ない僕はパッと見ですぐにコードを理解できません。なので少し時間をかけて解読。内容としてはsrc属性にurlをセットしちゃうと画像データが読み込まれちゃうのでデータ属性でオリジナル属性を作成してそこにurlの情報を入れておこう。そうすれば画像データが読み込まれないので後から情報を取り出して好きなタイミングで処理・表示できますよ!ということでした。これも違った…。まぁここまで探して見つからないのなら方法がない可能性が高いということで一旦諦める。しかし↑の情報は求めていたものではありませんでしたが使い勝手の良さそうなテクニックでした。ということで少し前に作成したアイキャッチ画像のwebp形式への変換コードを修正。以下のようになりました。
<script>
var imgReWebp = document.querySelectorAll('[data-originalsrc1]');
Array.prototype.forEach.call(imgReWebp, function(elem){
if (!elem) return;
let wsrc = elem.getAttribute('data-originalsrc1');
if (!wsrc) return elem;
elem.removeAttribute('data-original-src1');
elem.setAttribute('src', wsrc);
elem.style.display = ""
let topthumrerw1 = wsrc.replace( /(https:\/\/1.bp.blogspot.com\/[\w-]+\/[\w-]+\/[\w-]+\/[\w-]+)\/([a-z]\d+[\w-]*)\//, '$1/$2-rw/' );
elem.insertAdjacentHTML('beforebegin', '<picture><source srcset="'+topthumrerw1+'" type="image/webp"/>'+elem.outerHTML+'</picture>');
elem.remove();});
</script>
前回はBlogger独自タグと混在するコードだったので多少は見た目的にもマシになったかと思います。使用方法としてはこのコードを</body>より前かつ画像表示HTMLコードより後に設置すれば動きま…せん。先に画像表示コードのsrc属性を↑コードで使用しているオリジナル属性であるdata-originalsrc1に変更する必要があります。具体例としては以下のように。
<a expr:href='data:post.url'>
<img class='list-item-img' expr:data-originalsrc1='resizeImage(data:post.firstImageUrl, 144)' style='display:none;' loading='lazy'/>
<noscript>
<img class='list-item-img' expr:src='resizeImage(data:post.firstImageUrl, 144)' loading='lazy'/>
</noscript>
</a>
え~とid='post'関数内の画像表示コード部分です。そこのsrcの部分を↑のようにdata-originalsrc1に変更するだけです。ブラウザがJavaScript非対応の場合でも画像を表示したい方は↑のようにnoscriptタグで囲ったimgタグを設置しておいてください。そこはお好みで。ただその場合は↑のようにimgタグ内にdisplay:noneを設置しておいてください。ブラウザがJavaScript非対応の場合に画像の表示枠が二つにならないように。JavaScript非対応なんてどうでもいい!という方はsrc属性の書き換えだけで大丈夫です。よく見られているガジェットの方も同じように画像表示コード部分を書き換えてください。投稿記事の画像に関してもsrc属性を書き換えておけば自動でwebpに変換できる…とは思いますが未確認です。この投稿記事で試してみます。まぁこのコードを消したくなったときに困るので投稿記事は自分でwebpに書き換えるのがベストだと思います。JavaScript非対応用にnoscriptを設置したりと手間も変わりませんからね。Modernizrでブラウザのwebp対応判別をすればもう少し簡易なコードになるのですが、自分なりに少しでも汎用性を高いものにするためにmodernizr導入なしで動くコードにしてみました。使用しているうちに不具合を発見することが多いので今回のコードも何かあるかもしれませんが…。ちなみにコードを</body>の前に設置すると投稿記事一覧の画像表示が遅くなるかも。回避するには投稿記事一覧のオリジナル属性だけ変えてスクリプトを記事一覧表示コード直下にもう一つ設置するとか。でわ今回はこのあたりで。↓に画像が表示されていなければ投稿記事の画像では使えなかったんだなぁ、と苦笑でもしてやってください…と書こうとしてましたが、普通にプレビューで表示されているのが確認できました。

追記
すみません。↑のコードはpicture閉じタグがimgの前に挿入されていてwebpに変換できていませんでした。記事書きながらコードに変更加えていたのがあだになった…。使用するひとはいないと思いますが修正するまで絶対に使わないでください。Modernizrなら早いんだけどなぁ。さてどうやったら修正できるのか…。
とりあえず修正しておきました。JavaScriptの知識が乏しくかなり妥協した形での修正になりましたが…。気が向いたらまた修正しよう…。
0 件のコメント:
コメントを投稿
認証キャプチャは指示された画像を全てチェック後に確認ボタンを押すと公開できるようになります。