#サイト制作
25 件
Three.js の浮島を静的サイトに載せる
浮島ページは自分のスクリプトだけを読み込みます。シーンは実行時に生成し、Three.js はこのページのチャンクにだけ入り、最初の HTML には空の舞台しかありません。
モデリングなしで立体感を出す — 手で三角形を組む浮島
島の岩はモデリングツールから書き出したものではありません。五層の不規則なリングを実行時に組み上げ、頂点色とフラットシェーディングだけで石らしく見せています。
千二百インスタンス — 庭を数回の描画に収める
草六百、花百二十、苔石八十五、低木四十二。庭の密度は数を減らすのではなく、InstancedMesh で同じ種類を一描画にまとめて作ります。
シーンの光 — 三つの灯りと一度だけ計算する影
半球光が環境色、キーライトが向きと影、リムライトが島を背景から引き剥がし、残る七つの点光源は灯りを足すだけです。
二つのシェーダーで水をつくる — 水たまり・小川・滝
島に水面シミュレーションも反射もありません。ShaderMaterial は二つだけで、寝ている水と落ちる水を担当し、time と night を共有します。
3D の読み込み予算 — チャンク分割・可視になってから読み込み・止めどき
3D ページの費用は三つあります。ダウンロード、初回フレームのコンパイル、毎フレームの描画。それぞれに別々の予算を決めないと、見栄えが引っかかりに変わります。
グレースフルシャットダウン:終了手順が 502 と正常応答を分ける
終了信号で即座に exit すると処理中の要求が切られます。正しい順序は、新規受付の停止、処理中の完了待ち、資源の解放、そして終了です。
HTTP キャッシュ:Cache-Control と ETag は半分ずつ担う
Cache-Control は「リクエストを送るか」を、ETag は「送った後で本文を省けるか」を決めます。混同すると片方を直しても直りません。
iframe sandbox:能力を絞るもので、強化するものではない
sandbox 属性は既定で全能力を奪い、allow-* で一つずつ戻します。方向を逆に覚えがちで、script が動かないのは既定値だからです。
セマンティックバージョニング:主番号の約束は「挙動が黙って変わらない」
MAJOR は「変更が大きい」ではなく「破壊的」の意味です。リファクタで主番号を上げたり、破壊的変更を副番号に隠すと、下流の自動更新が事故になります。
技術的負債の利息とは何か
負債は醜いコードではなく、以後の変更が毎回余分に払うコストです。判定は測定可能で、1 回の変更で触るファイル数、テスト時間、同時に直す箇所の数です。
URL 符号化:空白・プラス・二重符号化の罠
クエリでは + が空白、パスでは + はプラスです。同じ文字でも位置によって規則が異なり、二度符号化すると一致しない値が静かに生まれます。
一貫性ハッシュ:マシンを 1 台足してもほぼ全鍵を並べ直さない理由
剰余による分割は台数が変わるとほぼ全データが移動します。ハッシュ空間を環にして時計回りで最初のノードに割り当てれば、動くのは 1 区間だけ。代償は仮想ノードです。
静的サイトのキャッシュヘッダー:ハッシュ付きは永久、HTML は毎回確認
キャッシュ方針を決めるのはファイル名が内容で変わるかどうかで、サイズではありません。HTML を長くキャッシュすると、削除済みチャンクを指す古い入口を配ることになります。
WebAssembly が効く場面は、宣伝よりずっと少ない
WASM の利得は重い計算、まとまったデータ、少ない境界越えが揃ったときに出ます。O(n) の JavaScript ループを書き直しても、遅い読み込みと追いにくいスタックが残るだけです。
手書き i18n:3 言語サイトでルーティングを自作する代償
このサイトの i18n は Astro 組み込みの設定を使わず自作しました。その理由と、代償が実際に現れた場所——2 回の 404 と、半分しか翻訳されていなかったブログについて書きます。
静的サイトの全文検索:索引はビルド時に、実行時にサーバーなし
静的サイトの検索は Algolia を繋がなくても作れます。索引をビルド時に生成し、検索は完全にブラウザ内で実行する——代償はビルドが数秒伸びるだけです。
1059 件のアサーション、テストフレームワークなし:純粋なロジックを import ゼロに保つ
このサイトの自検は node scripts/selftest.ts を直接実行するだけ。フレームワークも依存もありません。代償は検証対象のモジュールが相対 import を 1 つも持てないこと、そしてその代償はコードの形を買いました。
head の出典は一つ:SiteHead、JSON-LD のエスケープ、hreflang
三つの HTML シェルが一つのコンポーネントを共有し、head のタグをすべて出力します。データはサーバー層で組み立てます。JSON-LD の山括弧をエスケープする必要がある点も忘れずに。
静的サイトの公開は「フォルダを上げる」だけではない:キャッシュ、圧縮、正直な 404
静的ホスティングの罠はほぼ全部レスポンスヘッダーにあります。永久にキャッシュしてよいファイル、絶対にしてはいけないファイル、そして静的サイトが SPA 式フォールバックを使ってはいけない理由。
@/ エイリアスは三箇所に設定する。どれが欠けても壊れる
深い相対 import を全廃した代償は、エイリアスを三箇所で設定することです。一つ欠けると、エディタのエラー・ビルド失敗・スタイルの静かな消失という別々の症状になります。
zod で frontmatter を契約にする:記事の書式エラーをビルド時に落とす
Content Collections の schema が唯一の真実です。タイトルが 120 字を超える、日付が壊れている、タグが配列でない——どれもビルド時に失敗し、ページが黙って消えることはありません。
なぜまた個人サイトを作ったのか
書く場所がなかったわけではなく、記事とゲームとツールを同じ場所に置けなかったから。
設定不要のレジストリ:ゲーム追加はディレクトリ追加と同じ
一覧・詳細ルート・トップの注目枠・sitemap はすべて import.meta.glob が自動検出します。代償は Vite の規則、リテラルの相対パスだけという一点です。
ビューにロジックを置かない:データ組み立てはすべて src/server へ
ページにはルートの export とコンポーネントの読み込みしかありません。取得・パス組み立て・日付計算はすべて src/server に移しました。その利点と、強制される型の制約について。
