月次集計カード
概要だけ先に表示。本文は到達時に読込。
読み込み準備中...
遅延読み込みは、最初の画面表示を軽くして「必要になった部分だけ後で読む」ための定番パターンです。
htmxなら、hx-trigger="revealed" でスクロール到達時に読み込みを発火し、該当ブロックだけ差し替えできます。
このページでは、重いカード本文・タブの初回読込・添付プレビューを3デモでまとめます。
タグ:hx-get / hx-trigger / hx-target / hx-swap
hx-get:遅延で読みたいHTML断片(本文/タブ中身/プレビュー)を取得します。hx-trigger:発火条件を指定します。今回は revealed once を基本に、タブでは click once も使い分けます。hx-target:返却HTMLを差し込む先を指定します(例:this / 特定パネル)。hx-swap:差し替え方を指定します。遅延読込では outerHTML でプレースホルダごと置換する形が扱いやすいです。
カードの枠と見出しは先に表示し、本文だけをスクロール到達で読み込みます。
最初はスケルトンを置き、読み込み完了で本文へ差し替える最小構成です。
<div class="DEMO">
<h4>① 最小構成(revealedで“重いカード本文”だけ遅延)</h4>
<article class="CARD">
<h4>月次集計カード</h4>
<p class="INF_META">概要だけ先に表示。本文は到達時に読込。</p>
<div
class="LOADING"
hx-get="/htmx/demo/_lazy_load_1.php?card=monthly"
hx-trigger="revealed once"
hx-target="this"
hx-swap="outerHTML"
>
読み込み準備中...
</div>
</article>
</div>
<?php
// 文字コード付きでHTMLを返す
header('Content-Type: text/html; charset=UTF-8');
// セッションを開始する(統一のため)
session_start();
// 共通データを読み込む
require __DIR__ . '/_lazy_load_data.php';
// カードIDを受け取る
$card = (string)($_GET['card'] ?? 'monthly');
// 前後空白を除去する
$card = trim($card);
// カード本文を取得する
$body = lazy_load_get_card_body($card);
// 取得失敗時は表示文言を補正する
if ($body === null) {
// 代替本文を作る
$body = [
'title' => 'データなし',
'lines' => ['対象カードが見つかりませんでした。'],
];
}
// カード本文を開始する
echo '<div class="CARD MT32">';
// 見出しを出す
echo '<strong>' . lazy_load_h((string)$body['title']) . '</strong>';
// 補足を出す
echo '<p class="INF_META">本文のみ遅延読み込み完了</p>';
// 本文行を順に出す
foreach ((array)$body['lines'] as $line) {
// 1行を表示する
echo '<p>' . lazy_load_h((string)$line) . '</p>';
}
// カード本文を閉じる
echo '</div>';
// デモ用の遅延
usleep(3000000);
概要だけ先に表示。本文は到達時に読込。
hx-trigger="revealed once" で、要素が見えた1回だけ本文取得を実行します。hx-target="this" にし、hx-swap="outerHTML" でスケルトン枠ごと本文へ置換します。
タブ本体は先に出し、中身は各タブの表示領域に入ったタイミングで初回だけ読み込みます。
「押した瞬間に確実に読む」なら click once、「表示されたら読む」なら revealed once を使います。
<div class="DEMO">
<h4>② タブ(開いた時に初回だけ読み込み)</h4>
<details open>
<summary>売上サマリ</summary>
<div
id="DEMO_LAZY_2_SALES"
class="LOADING"
hx-get="/htmx/demo/_lazy_load_2.php?tab=sales"
hx-trigger="revealed once"
hx-target="#DEMO_LAZY_2_SALES"
hx-swap="outerHTML"
>
読み込み準備中...
</div>
</details>
<details>
<summary>部署別</summary>
<div
id="DEMO_LAZY_2_DEPT"
class="LOADING"
hx-get="/htmx/demo/_lazy_load_2.php?tab=dept"
hx-trigger="revealed once"
hx-target="#DEMO_LAZY_2_DEPT"
hx-swap="outerHTML"
>
読み込み準備中...
</div>
</details>
<details>
<summary>異常値</summary>
<div
id="DEMO_LAZY_2_ALERT"
class="LOADING"
hx-get="/htmx/demo/_lazy_load_2.php?tab=alert"
hx-trigger="revealed once"
hx-target="#DEMO_LAZY_2_ALERT"
hx-swap="outerHTML"
>
読み込み準備中...
</div>
</details>
</div>
<?php
// 文字コード付きでHTMLを返す
header('Content-Type: text/html; charset=UTF-8');
// セッションを開始する(統一のため)
session_start();
// 共通データを読み込む
require __DIR__ . '/_lazy_load_data.php';
// タブIDを受け取る
$tab = (string)($_GET['tab'] ?? 'sales');
// 前後空白を除去する
$tab = trim($tab);
// タブ本文を取得する
$panel = lazy_load_get_tab_panel($tab);
// 取得失敗時は表示文言を補正する
if ($panel === null) {
// 代替本文を作る
$panel = [
'title' => 'データなし',
'items' => ['指定タブが見つかりませんでした。'],
];
}
// パネルを開始する
echo '<section class="CARD">';
// 見出しを出す
echo '<strong>' . lazy_load_h((string)$panel['title']) . '</strong>';
// 箇条書きを開始する
echo '<ul class="HTMX-LIST">';
// 項目を順に出す
foreach ((array)$panel['items'] as $item) {
// 項目を1つ出す
echo '<li>' . lazy_load_h((string)$item) . '</li>';
}
// 箇条書きを閉じる
echo '</ul>';
// 注記を出す
echo '<p class="INF_META">このタブは初回表示時のみ取得しています。</p>';
// パネルを閉じる
echo '</section>';
// デモ用の遅延
usleep(3000000);
once を付けて同一パネルでの再発火を防ぎます。hx-trigger="click once" をタブボタン側へ付ける運用も有効です。
一覧(ファイル名やサイズ)は先に描画し、重いプレビュー枠だけを遅延読み込みします。
添付が多い画面でも、まず一覧操作を優先して軽く始められます。
<div class="DEMO">
<h4>③ 画像/添付(一覧は先に出し、プレビューはスクロール到達で遅延)</h4>
<div class="CARD">
<strong>見積書_2026_Q1.pdf</strong>
<div class="INF_META">2.1MB / 経理部</div>
<div
class="LOADING"
hx-get="/htmx/demo/_lazy_load_3.php?id=att-001"
hx-trigger="revealed once"
hx-target="this"
hx-swap="outerHTML"
>
プレビュー読込準備中...
</div>
</div>
<div class="CARD MT32">
<strong>契約書_再締結.docx</strong>
<div class="INF_META">860KB / 法務部</div>
<div
class="LOADING"
hx-get="/htmx/demo/_lazy_load_3.php?id=att-002"
hx-trigger="revealed once"
hx-target="this"
hx-swap="outerHTML"
>
プレビュー読込準備中...
</div>
</div>
<div class="CARD MT32">
<strong>写真_現地確認_01.jpg</strong>
<div class="INF_META">3.4MB / 営業部</div>
<div
class="LOADING"
hx-get="/htmx/demo/_lazy_load_3.php?id=att-003"
hx-trigger="revealed once"
hx-target="this"
hx-swap="outerHTML"
>
プレビュー読込準備中...
</div>
</div>
</div>
<?php
// 文字コード付きでHTMLを返す
header('Content-Type: text/html; charset=UTF-8');
// セッションを開始する(統一のため)
session_start();
// 共通データを読み込む
require __DIR__ . '/_lazy_load_data.php';
// 添付IDを受け取る
$id = (string)($_GET['id'] ?? '');
// 前後空白を除去する
$id = trim($id);
// 添付情報を取得する
$att = lazy_load_get_attachment($id);
// 添付情報が無いときはエラーを返して終了する
if ($att === null) {
// エラーブロックを出す
echo '<div class="FORM-RESULT is-err">プレビューを表示できませんでした。</div>';
// 処理を終了する
exit;
}
// プレビュー枠を開始する
echo '<div class="CARD">';
// 見出しを出す
echo '<strong>Preview: ' . lazy_load_h((string)$att['name']) . '</strong>';
// メタ情報を出す
echo '<div class="INF_META">' . lazy_load_h((string)$att['size']) . ' / ' . lazy_load_h((string)$att['owner']) . '</div>';
// プレビュー本文を出す
echo '<p>' . lazy_load_h((string)$att['preview']) . '</p>';
// プレビュー枠を閉じる
echo '</div>';
// デモ用の遅延
usleep(3000000);
revealed once を設定すると、見えた添付だけ順次読み込まれます。経験:Webアプリ/業務システム
得意:PHP・JavaScript・MySQL・CSS
個人実績:フォーム生成基盤/クイズ学習プラットフォーム 等
詳しいプロフィールはこちら! もちもちみかんのプロフィール