「小粋空間」さんにて、画像を遅延ロードするプラグイン、「Lazy Load」が紹介されていました。
このプラグインは、画面をスクロールしていくと、画像がじわ~んと浮き上がってくるような視覚的効果があり、また画像が画面上でVisibleになった段階でロードされるため、ページロード時のHTTPリクエストを減らすことができる、という効果があります。
以前から気になっていたのですが、実際にMT(Movable Type)に導入しようとすると、いくつかの課題があることが分かったため、この解決方法について、しばらく考えていました。
#「Lazy Load」についての具体的な導入方法については、「小粋空間」さんや、本家「Lazy Load」をご覧ください。
MTへの「Lazy Load」の導入時の課題は、以下の2点です。(この課題は、「MTに限らず」ですが)
(1) 記事を編集する際に、画像が見えなくなってしまう
「Lazy Load」では、遅延ロードさせる画像の<img>タグに対して、所定のclass設定をします。
このclass設定を目印として、画像がVisibleであるかどうかを判定して、Visibleである場合には、本来表示すべき画像(オリジナル画像)を表示(ロード)し、Visibleでない場合には、ダミー画像を表示します。
実際の<img>タグのサンプルは、以下のとおりです。
<img class="lazy" src="image/transparent.gif" data-original="image/snapshot.jpg" width="360" heigh="270" alt="Snapshot" />
ここで、MTでの編集時には、<img>タグは通常どおり認識されるので、表示される画像は、srcで指定した画像となり、白や透明などのダミー画像(この場合は、「transparent.gif」)が表示されてしまいます。(当たり前ですが)
たしかに、これで良いといえば良いのですが、編集時には、本来表示すべき画像(この場合は、「snapshot.jpg」)を表示しておかないと、日本語表現力の疎い職人には、文章のイメージが湧いてきません。
なんとか、「編集時にはオリジナル画像、公開時にはダミー画像」を表示したいものです。
(2) 過去の記事に対して適用することが難しい
これから新規に投稿する記事については、<img>タグに対してclass設定することにより、遅延ロード効果を掛けることができます。しかし、過去に投稿した記事については、再度その記事を編集して、手動で設定するしかありません。
工房には、blog開設時から数えて約900件もの記事(約2,600件もの画像)がありますが、これら一つ一つの記事にチマチマと手動で設定していたのでは、日が暮れてしまいます(年が明けてしまいます)。
なんとか、過去の記事に対しても、楽チンで自動設定させたいものです。
ということで、簡単な解決方法を考えましたので、紹介します。
当初は、MTが参照するSQLデータベースから記事(mt_entry)を抽出して、その中に含まれる<img>タグを直接改変してしまう、という方法も考えたのですが、これでは「課題(1)」は解決できないため、別の方法を採ることにしました。
といっても、特に難しいことはしておらず、以前に紹介した「PHPコードを圧縮してDLを高速化する」と同じような考え方です。
MTが生成したPHPソースを読み込んで、その中に含まれる<img>タグについて、一定条件に合致する場合にタグを改変する、という方法です。これにより、MTでの編集時には、画像が普通に見えていて、公開時には、画像にきちんと遅延ロード効果が掛かる、ということになります。(「課題(1)」の解決)
また、対象とするPHPソースについては、blogに設定されているサイトマップを読み込んで、そこに登録されているすべてのエントリに対して<img>タグの改変を適用する、という方法を採りました。これにより、過去に投稿した記事のみならず、カテゴリー別アーカイブや月別アーカイブなど、MTが生成するすべてのエントリに対して遅延ロードを適用できる、ということになります。(「課題(2)」の解決)
ということで、能書きはこれくらいにして、肝心のPHPのソースです。
ExtractSiteLinks()は、その名のとおり、サイトマップファイルからリンクを抽出し、配列として返す関数です。
ChangeImageTags()が、今回の操作のキモで、PHPソースに含まれる<img>タグを抽出し、ある一定の条件に合致する場合にタグを書き換える関数です。
“ある一定の条件”とは、ここでは、オリジナルの画像の大きさが、「MinWidth × MinHeight以上であること」としています。