🚧 改装中 (v0.1):UES.ONE は現在ベータ版です。
UES.ONE:CDNフリー、フリッカーフリーのデータ駆動型デジタルガーデンの構築

UES.ONE:CDNフリー、フリッカーフリーのデータ駆動型デジタルガーデンの構築

12月 5, 2025·Ahaxzh
Ahaxzh

情報が断片化されたこの時代において、自分だけの「デジタルガーデン」を持つことは特に貴重です。

ついに、UES.ONE が公開されました。これは単なるブログではなく、Web技術、データ管理、そしてユーザー体験に対する私の深い探求の成果です。

もしあなたが、ありきたりな CMS に飽き飽きしていたり、数メガバイトもの JS に依存する現代の Web ページに疲れ果てているなら、この記事は何かしらのインスピレーションを与えるかもしれません。ここでは、完全に データ駆動 で、CDN 依存ゼロ、そして 極めて滑らか なこの静的サイトがどのように構築されたか、ゼロから解き明かしていきます。

🌱 はじめに:なぜ Hugo なのか?

技術選定の当初、WordPress、Hexo、Gatsby などの主要なフレームワークを検討しました。最終的に、Hugo の驚異的なビルド速度(ミリ秒単位)と、Go 言語の強力なエコシステムが決め手となりました。

macOS でこれらすべてを始めるには、たった一行のコマンドで十分です:

brew install hugo

なぜ Hextra テーマを選んだのか?

エンジンが決まったら、美しい外殻が必要です。私は Hextra を選びました。これは Next.js スタイルのドキュメントテーマを Hugo 用に改造したもので、Tailwind CSS をサポートしているだけでなく、「ドキュメント」と「ブログ」という2つのレイアウトを完璧に融合させています。何より、そのミニマリズムの美学が私の心に響きました。

プロジェクトの初期化とテーマの導入:

hugo mod init ues.one
hugo mod get github.com/imfing/hextra

こうして骨組みはできあがりました。しかし、それに魂を吹き込むには、まだ長い道のりがありました。

🏗️ コアアーキテクチャ:YAML データ駆動 (Data-Driven Architecture)

従来のブログは通常、独立した Markdown 記事の集まりです。しかし、私には整理整頓の癖があります。自分の読書リスト、映画リスト、音楽コレクションを、単なる記録ではなく、リレーショナルデータベース のように体系的なものにしたいと考えました。

そこで、「YAML First」 というデータ戦略を策定しました。

data/ ディレクトリには、HTML を直接書くのではなく、高度に構造化されたデータを保存しています:

  • books.yaml:読書記録
  • movies.yaml:映画リスト
  • music.yaml:音楽コレクション
  • memos.yaml:つぶやき (Memos)
  • quotes.yaml:厳選された名言

例えば movies.yaml では、映画をこのように保存しています:

- id: "m_001"
  title: 
    zh-cn: "黑客帝国"
    en: "The Matrix"
    ja: "マトリックス"
  year: 1999
  rating: 5
  poster: "matrix.web"
  comment:
    zh-cn: "你选蓝药丸还是红药丸?"
    en: "Blue pill or Red pill?"

これらのデータをもとに、専用の Hugo Shortcodes(moviewall.html など)を作成し、Hugo の強力なテンプレートエンジンを利用して YAML を美しいポスターウォールとしてレンダリングしています。

これには巨大なメリットがあります:将来、Hugo から Next.js、あるいはモバイルアプリに移行したくなったとしても、これらの YAML ファイルを持っていくだけで済みます。何百もの Markdown ファイルからデータを考古学者のように発掘する必要はありません。

⚡ パフォーマンス哲学:あえて逆を行く「ゼロ CDN」

Web 開発が公共 CDN(jsDelivr, unpkg など)に過度に依存している今日、私は「流行に逆らう」決断をしました:全リソースのローカル化 です。

このサイトで見られるすべての JS ライブラリ(Swiper, Fancybox)と CSS スタイルは、すべてローカルの assets/ ディレクトリでホストされています。

なぜそうするのか?

  1. プライバシー第一:Google Fonts も、サードパーティの分析スクリプトもありません。あなたの訪問記録が、プロファイリングのために巨大IT企業に収集されることはありません。
  2. 絶対的な制御:公共 CDN がダウンしても(珍しいことではありません)、あるいはネットワークが弱い環境でも、このサイトは完璧に動作します。
  3. ビルド最適化:Hugo Pipe を利用して、ビルド時にこれらのリソースに対して Fingerprint(指紋付与)と Minify(圧縮)を行います。Cloudflare Pages によって配信されるため、速度は CDN に全く引けを取りません。

🎨 究極の体験:FOUC との決別 & スマートプリロード

1. FOUC (Flash of Unstyled Content) の解決

静的サイトで「ダークモード」を実装する際によくある問題が FOUC です。ページ読み込みの瞬間に白い背景が一瞬表示され、その後に黒くなる現象です。

これを解決するために、「透明優先・継承ベース」の CSS 戦略を採用しました。すべてのカードコンポーネントのデフォルト背景色を transparent に、文字色を inherit に設定しました。これにより、ブラウザが最初にライトモードで描画しようとダークモードであろうと、コンポーネントは JS の実行を待つことなく、自然に背景に溶け込みます。

2. Memos の「ゼロレイテンシー」切り替え

Memos(つぶやき)モジュールでは、スマートプリロード (Smart Preloading) ロジックを導入しました。

あなたが現在の「カード」を読んでいる間に、ブラウザはバックグラウンドで「前」と「次」のカードの画像リソースを静かにダウンロードしています。コードは次のようになります:

// 画像プリロード最適化:前後アイテムの画像を静かにロード
var nextIdx = (index + 1) % memoData.length;
var prevIdx = (index - 1 + memoData.length) % memoData.length;
if (memoData[nextIdx].image) (new Image()).src = memoData[nextIdx].image;
if (memoData[prevIdx].image) (new Image()).src = memoData[prevIdx].image;

このミリ秒単位の最適化が、指先でスワイプしたときの極上の滑らかさを生み出しています。

3. Smart Quotes(一言)の言語間同期

トップページでは、公開されている API を使用せず、自作の quotes.yaml ライブラリを使用しています。

さらに興味深いのは、多言語切り替え時の体験の一貫性を保つために、sessionStorage を利用して状態同期を実装したことです。もし中国語のトップページでニーチェの名言を見たなら、英語版に切り替えても、ランダムに別の言葉に飛ぶのではなく、同じ名言の英語版が表示されます。

このディテールへのこだわりこそが、私のユーザー体験に対する執着です。

🛠️ 今日のリファクタリング:クリーンコードの勝利

つい今日、サイト全体のコードに対して大規模なリファクタリングを行いました。

  • 設定の標準化hugo.yaml を、数百行の雑然とした設定から、Core(コア)、Modules(モジュール)、Build(ビルド)、Multilingual(多言語)など7つの主要なセクションに再編成しました。
  • コメントのドキュメント化:すべての Shortcodes と Partials ファイルに、技術的な中国語コメント を補完しました。これは AI のためだけでなく、未来の自分のためでもあります。
  • バグの撲滅theme-toggle の HTML 属性値の改行が原因でビルドが失敗する問題を修正するために、Go Template の構文の境界を繰り返し検証さえしました。

結び

UES.ONE は私の聖域であり、遊び場でもあります。

このプロセスにおいて、私は構想と美学を担当し、AI はコーディングとデバッグを担当しました。AI とのペアプログラミング は、私の開発のニューノーマルとなりました。私たちは div の高さについて議論し(あの 60vh か 70vh かのスクロールバー問題のように)、z-index の重なり問題を解決して祝杯をあげました。

ここはまだ成長途中の庭です。コードは変わり、内容は変わりますが、「心を込めて創る」という初志は変わりません。

ぜひ、また遊びに来てください。

最終更新日