Hexoでnative-lazy-loadingに対応する

  1. 🏷️
  2. プログラミング
  3. Hexo
  4. Hexo時代の記事
No hero image

この記事はHexo時代の記事です。 現在のブログとは見た目や機能が異なる可能性があります。

フィギュアレビュー記事の表示速度が遅いので、 ブラウザnativeのlazy-loading(遅延読み込み) に対応する。 自前のscriptでloading, width, height属性を付与する作戦。

長くなっちゃったので、記事は折りたたんである↓。

手順

まず、image-sizeを使うので、npm install image-sizeしておく。

次に、↓のscriptをthemes/***/scriptsに置く。 scriptsフォルダに置いたjsファイルはhexoのgenerate時に自動で実行される。

// This script refers to `hexo-native-lazy-load`.
// <https://github.com/fengkx/hexo-native-lazy-load>

// require
const sizeOf = require("image-size");
const path = require("path");
const fs = require("fs");
const log = hexo.log;

// config
const regex = /<img[^>]+src=\"(.+?)\"[^>]*>/gm;

// function
const mylog = (...args) => {
  log.debug(path.basename(__filename), ": ", ...args);
};

const replace = (html, rootPath) => {
  return html.replace(regex, (s, relativePath) => {
    mylog('s: "' + s + '".');

    if (s.indexOf('loading="lazy"') !== -1) {
      mylog('Already added `loading="lazy"`. Do nothing.');

      return s;
    }

    const imagePath = path.join(rootPath, relativePath);
    mylog("image path: " + imagePath);

    if (rootPath !== "" && fs.existsSync(imagePath)) {
      const dimensions = sizeOf(imagePath);
      mylog("width: " + dimensions.width + ", height: " + dimensions.height);

      return (
        s.substring(0, 4) +
        ' loading="lazy"' +
        ` width="${dimensions.width}"` +
        ` height="${dimensions.height}"` +
        s.substring(4, s.length)
      );
    } else {
      mylog("Not found image.");

      return s.substring(0, 4) + ' loading="lazy"' + s.substring(4, s.length);
    }
  });
};

// main
hexo.extend.filter.register("after_post_render", function (data) {
  mylog('replace: "' + data.title + '".');
  data.content = replace(data.content, hexo.source_dir);
  return data;
});

次に、css(stylus)の修正もいる。↓のファイルをいじる。 (landscape以外を使ってる人は適宜読み替えてね。)

  • themes/landscape/source/css/_partial/article.styl

ツリー構造で示すと、↓をいじる。

  • .article-entry
    • img, video
      • max-height: 100vhの設定を無効化(コメントアウト)する。

最終的には↓のようになってる。 (max-height以外のコメントアウトは無視して。)

  img, video
    max-width: 100%
    // max-height: 100vh
    // width: auto
    height: auto
    // object-fit: contain
    display: block
    margin: auto

最後に、clean&generateすればOK。

解説と蛇足

jsの中身は hexo-native-lazy-load pluginのほぼパクり。

hexo-native-lazy-load pluginそのままだと、 post_asset__folderを有効にしないと、うまく動作しない。 <img>widthheightを入力してくれない。

この記事のjsはpost_asset_folderが無効でも動作するように改良した(つもり)。 やってることは、大雑把に↓の2つ。

  1. loading="lazy"を付与
  2. image-sizeで画像サイズ取得して、width, height属性を付与

ちなみに、pluginとして公開する予定はなし。体裁を整えるのがめんどいため。

cssについては、本当はmax-height: 100vhの設定も有効のままにしておきたかった。 だけど、lazy-loadingで有効にすると、aspect比が崩れちゃうのよね...。 なんでaspect比を固定する属性とかがcssにないんだろう。不思議。

なお、lazy-loadingが効いてるかどうかは、chromeのデバッガを使えば分かる。 Networkタブで、スクロールするごとに画像がloadされてれば成功。 ↓の例だと、prisma_klangfest_chloe_3.webpが遅延読み込みした画像。 chromeでlazy-loadingの動作確認

他、 先駆者の方の記事 も参考にしてる。 感謝感謝。

これで、フィギュアレビュー記事の体感表示速度が上がったはず。 Netlifyくん、転送速度が結構遅い。 無料のホスティングサービスなのでしょうがない。工夫でカバー。

Bio
Bio icon

tenpaMk2

🇯🇵インドアクソオタク。

Tag cloud
  1. AI生成
  2. ALTER
  3. ANIPLEX
  4. Astro
  5. AZT8-45
  6. A列車で行こう
  7. Borderline Toybox
  8. BROCCOLI
  9. Building Gadgets MOD
  10. Chart.js
  11. cocoen-js
  12. Create MOD
  13. DDDy
  14. Excalibur.js
  15. Fate
  16. Fate/Apocrypha
  17. Fate/EXTELLA
  18. Fate/EXTRA CCC
  19. Fate/stay night
  20. FGO
  21. FLARE
  22. FREEing
  23. GameDev
  24. Gatsby
  25. Gatsby Theme
  26. Git
  27. Google Analytics
  28. Hexo
  29. Hexo時代の記事
  30. HOBBY STOCK
  31. hololive
  32. homebrew
  33. JavaScript
  34. KDcolle
  35. KDColle
  36. Kon'D
  37. Lightroom
  38. Mac
  39. Markdown
  40. Minecraft
  41. MVStudio
  42. NEKOPARA
  43. NEKOYOME
  44. Node.js
  45. npm
  46. NSFW
  47. Phat!
  48. PLUM
  49. plusone
  50. POP UP PARADE
  51. PSO
  52. quesQ
  53. RAW現像
  54. Re:ゼロから始める異世界生活
  55. React
  56. RSS
  57. SAO
  58. spiritale
  59. SSG
  60. Stable Diffusion
  61. Tailwind CSS
  62. Thermal MOD
  63. To LOVEる
  64. Tony
  65. Twitter
  66. TypeScript
  67. Vite
  68. VOCALOID
  69. VSCode
  70. WebP
  71. Wonderful Works
  72. zsh
  73. ご注文はうさぎですか?
  74. はじまるA列車
  75. はにかみ、彼女は恋をする
  76. ひげを剃る。そして女子高生を拾う。
  77. りゅうおうのおしごと
  78. アクアマリン
  79. アストルフォ
  80. アズキ
  81. アズールレーン
  82. アトリエシリーズ
  83. アリスグリント
  84. アルトリア オルタ
  85. イリヤスフィール・フォン・アインツベルン
  86. イージーエイト
  87. ウイング
  88. エリス・ボレアス・グレイラット
  89. エルドール
  90. オーキッドシード
  91. キャスター
  92. クドわふたー
  93. クロエ・フォン・アインツベルン
  94. グッドスマイルカンパニー
  95. グリザイア:ファントムトリガー
  96. ゲーム
  97. ココナツ
  98. コトブキヤ
  99. ゴールデンヘッドプラス
  100. サキちゃん
  101. ショコラ
  102. ジェネ
  103. ジャベリン
  104. ジャンヌ・ダルク
  105. ステファニー・ドーラ
  106. ストロンガー
  107. ソフィーのアトリエ
  108. ソードアート・オンライン
  109. ダイキ工業
  110. チノ
  111. チノちゃん
  112. チョコメロ
  113. ティアーユ・ルナティーク
  114. ディ・モールト ベネ
  115. デート・ア・ライブ
  116. ドール
  117. ドールグッズ紹介
  118. ナナ・アスタ・デビルーク
  119. ネコぱら
  120. ネロ・クラウディウス
  121. ノーゲーム・ノーライフ
  122. バニラ
  123. バニー
  124. フィギュア
  125. フィギュアレビュー
  126. ブログ
  127. プラスワン
  128. プラフタ
  129. プリズマ☆イリヤ
  130. プログラミング
  131. マシュ・キリエライト
  132. マックスファクトリー
  133. マヤ
  134. ミーア
  135. ミーシャ・ネクロン
  136. メグ
  137. メディコス・エンタテインメント
  138. モモ・ベリア・デビルーク
  139. モンスター娘のいる日常
  140. ユニオンクリエイティブ
  141. ライザのアトリエ
  142. ライザリン・シュタウト
  143. ララ・サタリン・デビルーク
  144. リューノス
  145. レム
  146. レーシング
  147. 五島潤
  148. 冴えない彼女の育てかた
  149. 初音ミク
  150. 加藤恵
  151. 喵屋
  152. 天使の3P!
  153. 巡音ルカ
  154. 時崎狂三
  155. 東京フィギュア
  156. 水澄華実
  157. 氷堂美智留
  158. 深見玲奈
  159. 無職転生
  160. 玉藻の前
  161. 画像比較スライダー
  162. 白銀ノエル
  163. 百瀬くるみ
  164. 空銀子
  165. 結城明日奈
  166. 結城美柑
  167. 美咲詩絵
  168. 美遊・エーデルフェルト
  169. 能美クドリャフカ
  170. 花偶堂
  171. 荻原沙優
  172. 西連寺春菜
  173. 遠坂凛
  174. 雛鶴あい
  175. 霞ヶ丘詩羽
  176. 魔王学院の不適合者
  177. 黒咲芽亜