Chrononglyph

web制作

#8174

想定外の高負荷

今日の出来事web制作

いよいよ満を持して中型イベント専用アプリ(期間限定ランキング)開発に着手しました。
技術スタックはReact(Next.js)、Phaser 4、Laravel APIで、
主にフロントエンドコンテナのAPIはNext.js、スクロールなどweb的な動きをさせたい部分はReact、
ゲーム的な動きをさせたい部分はPhaser、サーバーサイド処理をLaravelに任せるといった構成です。
このうちPhaserはいわゆる2Dブラウザゲームを作るためのゲームエンジン的なもので、今回が初使用。
自分はまったく存じ上げませんが、実装主体はCodexに全面的に任せる方針を採用しているため、
ネットにノウハウさえ転がっているなら実務経験ゼロでも採用できるというわけです。
年初にほんの少しPICO-8に触れたことを除けば、本格的にゲーム系プラグインに触れるのはこれが初めてとなります。


が、いざスタートしてみると思いもよらぬところで壁にぶち当たりました。
開発していると頻繁にMacbookのWindowServerが落ち、そのタイミングで強制再起動がかかってしまうのです。
最初、これは最近アプデしたmacOS 26.4.1に固有の不具合なのかと思っていました。
ChatGPTに確認すると確かに当該バージョンでWindowServerが落ちるという報告があると言うので。
ただ、あまりにも頻繁に再起動するので、もしこれが世界中のユーザー環境で起きているならもっと騒ぎになっているはず。
そうでないということは、この開発のせいでは?
……と思いアプリ側、特にPhaserの設定を見直したところ、あっさり改善しました。
アプリの描画負荷があまりにも高かったので、
OSのウィンドウレンダリングを司るプロセスをクラッシュさせてしまっていたわけです。


今回作成しているwebアプリはそれほどレンダリングに負荷を与えるものではないと思っていました。
3Dアクションを作っているわけでもないし、そもそも常時何かが動いているわけでもない。
しかしまさかOSのコアプロセスをクラッシュさせるなんて……。
この辺はAIに任せきりでは大変な負荷がかかるものだと思って、
意識的にレンダリング負荷を落とす工夫を盛り込む必要があると感じました。
今回のこれは自分の環境で動けばOKというものではなく、参加希望者すべてのPCで無事に動かなければなりません。
自分の開発環境であるMacbook Pro M1 Maxはそこまでスペックが低いとも言えないので、
この環境で落ちてしまうようでは先が思いやられます。


開発自体は思っていたより10倍順調なのですが、
レンダリング負荷などのように当初想定していなかった作業は他にもありそうな予感がしています。
一番良くないのはリリース後にそれが発覚することなので、とにかく多方面からテストする必要はありそう。


余談ですが、YouTubeで2017年のアニメ『けものフレンズ』が期間限定で全話無料公開されていたので、
作業のお供に流していました。観たのはほぼ9年ぶり(#04864 / 2017年05月01日)でしたがやはり面白いですね。
内容について語り出すとまた止まらなくなるので割愛しておきますが。
ガッツリ作業するときのお供にアニメ、意外と悪くないかも?


#8168

AIの改修による暴走

今日の出来事web制作

出社日の退勤は、まず会社最寄駅から新宿駅まで行き、
新宿駅から自宅最寄駅までは確実に座るために次発乗車列に並ぶことも考慮して駅で待機します。
そして新宿駅で無事に座れたらあとは読書タイム。
逆に言えば、新宿駅に辿り着くまでは乗り換えの都合で読書をする余裕が無いのでスマホをいじるしかありません。
こういうとき、最近はGoogleアプリでニュースをチェックしていることが多いのですが、
自分のサイトを巡回することも結構あります。
そこで今日はサイトを巡回しようとしたらサイトがめちゃくちゃ重く502エラーを吐くこともあったため、
「またサーバーが攻撃されているかも?」と思いつつ内心不安になりながらも帰路を急ぎました。


サーバーのリソースモニタを見ると夕方からCPU使用率が不自然に上昇しており、
ターミナルでSSH接続するとターミナル自体が固まってしまうほどサーバーが激重状態になっていました。
が、結論から言うとこれはセキュリティ・インシデントやDDoS攻撃などではなく、
単にこのブログのフロントエンドが不当にリソースを食う設計になっていたせいで暴走していただけした。


基本的にこの手のトラブルが起きた場合はChatGPTに訊けばどうにでもなります。
React2Shellの件(#08035 / 2025年12月15日)や今回使った手法はどちらもtopコマンドを起点にしています。
これはWindowsでいうところのタスクマネージャーで、CPU使用率の高いプロセスが一目瞭然になるんですよね。
プロセス番号さえ分かればどこの何が暴走しているのかは仮想化環境内だろうと特定できるので、
今回はこのブログのフロントエンドコンテナの中にあるNode.jsが暴走していたとわかったわけです。
そしてなぜ暴走していたのかと言えば、
本家ブログで本文やタグを表示しようとするときに全記事(執筆時点で8,167本)を探索するAPIが走っていたと。
実際、ログをリアルタイムで流すようにして本番環境にアクセスしてみると、
面白いくらいアクセスした瞬間だけCPU負荷が爆上がりすることがわかりました。


今回、この原因を作ったのはAIの改修であり、これはこれで問題だと改めて思いました。
やはり自分の手が届かない範囲で改修を完結させてしまうとこういう予期せぬ問題が発生することがあるんだなと。
人力開発では何を書いて何が起こりうるのかを自分がそれなりに把握できていたのでこうした問題は起こりにくく、
それゆえにどうしてもテストなどの後工程は軽視されがちでした。
しかしエージェントコーディングにおいてはむしろ盤石なテストプロセスが必須なのかも。
AIを過信しないことはもちろん大事ですが、人の手が介入しないからこそ個々のプロセスについて言語化しておき、
ルールを過不足なく決めることは今後の開発において急務になるんじゃないかと思っています。


#8095

web制作は上流工程へ

今日の出来事web制作ai

Codex導入以降、web制作が捗りまくっています。
具体的にはピクチャレ大会の改修が10コミットに達しており、これは低迷していた2025年の7ヶ月分の作業に相当します。
必要性は感じているが見た目の変化に乏しいので改修モチベーションを捻出できない、
といったような保留タスクが一気に進んだ感じですね。セキュリティ関係とかちょっとした不具合とか。
このブログも先日プロジェクト全体のセキュリティ強化を実施しましたが、
Codexが出してくれたレポートによると驚くほど多くの脆弱性がありました。
このブログはGPT-4の時代にChatGPTに大部分を書いてもらった経緯があり、
自分にとっては初めてのAIコーディングによる成果物です。
ただ、当時はまだエージェント機能は使えなかったので1ファイルずつ作らざるを得ず、
そのため機能単位でAIにコードを書いてもらって自分がそれを該当箇所に埋め込むという作業が主でした。
総合テストなんてやっていません。
そういう経緯もあり、ファイル間の連携が雑だったのは間違いありません。
が、しかしまさかこんなにガバガバだったのかというほどたくさんのセキュリティリスクが出てきました。


実は02月01日復帰前にこのブログはまた攻撃されたのか、
それとも内部の不具合だったのかコンテナが暴走してCPUを食い続けるという事故が発生し、
去年末のReact2Shellに続いてまたしても強制シャットダウンを経験しました。
セキュリティを見直そうと思ったのはそういうきっかけがあったからですが、
このタイミングでCodexと出会えたのは運が良かったと思います。これが無かったら相当の難工事だったでしょう……。


とはいえ、Codexがあまりにも有能なら人の手はもう不要なのかというとそういうわけでもありません。
体感では、コーディングをAIに依存すればするほど、人間が自然言語で書くプロンプトの重要性は高まっています。
やってほしいことを一言一句漏らさず言語化する必要があるからですね。
軽微な修正では、プロンプトをしっかり書いて指示するより自分で改修した方が早いケースもまあまああります。


結局、AIに指示するためにはシステムのことを十分理解していないといけないし、
web制作の基礎知識もそれなりに求められます。
書く内容がコードそのものではなく自然言語になっただけで、やっていることはあまり変わっていないような気も。
ただ、知識を補填して完成度の高いコードを爆速で書いてくれるので間違いなく効率は上がりました。
個別の言語化があまり必要ないセキュリティ強化などは本当にやりやすくなりましたね。
AIのおかげでwebサイト全体のセキュリティは長い目で見てかなり強化するんじゃないだろうか。


一通り保留タスクを片付けたら、次はいよいよ大規模開発をCodexでやっていくつもりです。
これはまず「仕様書の整理」といういままでやってこなかったタスクが待ち構えており、
これをどう片付けるかという問題になりそう。
趣味のweb制作活動も、今後はシステム開発における上流工程みのある作業にシフトしていくんでしょうね。


#7723

Nuxtの魅力再発見

今日の出来事web制作Nuxt

ただの趣味から仕事でも使うツールになったことで、
メモ帳に書き殴っていた実家時代から大幅に飛躍したweb技術領域。
その成果の第1弾がピクチャレ大会で、これは「Next.js」というフレームワークを使って作っています。
実は2022年のプロジェクト黎明期から、
実際に作り始めてみた頃まではずっと「Nuxt(ナクスト)」というフレームワークで検討していました。
これは2020年当時の同僚間の話で「Reactは難しい。Vue.jsなら昔ながらのHTMLコーダーにも理解しやすい」
というような情報がさも常識かのように飛び交っていた影響もあり、
ReactのフレームワークであるNext.jsよりVue.jsのフレームワークであるNuxtの方がハードルは低いだろう、
と思い込んでいたことによります。


しかし実際に触ってみるとReactのコンポーネント指向開発がとても面白く、
開発初期に思い切ってNext.jsへ転向することにしました。
当時の記事(#06970 / 2023年01月16日)によると、当時はNuxtがメジャーアップデートしたばかりで情報が少なく、
その情報の少なさが開発初期にしていきなり暗礁に乗り上げるきっかけになったので思い切って切り捨てた、
という感じみたいです。いまなら時間も経っているしChatGPTもいるしなんとかなりそうな気はしますね。


そんな矢先、「Nuxt Content」というNuxtのモジュールと「Nuxt Studio」というwebサービスを知りました。
Nuxt Contentは、簡単に言えばGitで管理されたMarkdownファイルをそのまま表示させる技術。
Nuxt Studioは、そのMarkdownファイルをコードベースでweb上から直接編集できるようにするサービスです。
「Markdownで書いた記事をそのまま読み込む」
というスタイルは現行の本家ブログのシステムそのままであり、大いに驚きました。
これならモジュールのサポートも受けつつシステムを変えずに運用することも不可能ではない。


本家ブログの現行システムは突貫工事で作った結果どうしてもビルドが通らなくなってしまい(#07716 / 2025年01月31日)、
ゼロベースからの作り直しを決意したばかりでした。
ChatGPTと話し合いながら、そのときは最終的にはピクチャレ大会と同じような構造にすることにしました。
すなわちDBコンテナ、バックエンドコンテナ、フロントエンドコンテナをそれぞれ別に用意する方式です。
記事をアップしたらバックエンドがDBへ変換し、APIでDBを読み込んで記事を表示するという想定です。
もちろんこれは開発が難しいということもありますが、
結局マスターデータはMarkdownでDBは中継でしかないため、
DBとしてのマスタとMarkdownとしてのマスタが共存せざるをえないというややこしさもあります。
その代わり、DB化するので全文検索などで有利なのは確か。


そもそもこの問題の根本は「ビルドが通らないこと」だったので、
ゼロベースから作り直すにしても必要以上に複雑化する必要はありません。
それならば、モジュールとしてMD-HTML変換がサポートされているNuxtの方が有望なのでは……と思った次第です。
Studioを使えば実質どの端末からでもブログ編集できるという点も魅力的。
もちろん、Markdownをそのまま扱うことのリスクやデメリットもありますけどね。
たとえばこの方式だとブログ全部の全文検索はあまり現実的ではなく、諦めざるをえません。
まあ、そもそも向こう数年は全記事公開する目処が立っていないため重要度はかなり低いのですが。


自分としては2022年当初こだわっていたNuxtの魅力を期せずして再発見でき、なかなかアツい展開です。
Nuxt Contentは実際にミニアプリを作って試してみて、有望そうならこっちで行こうかなと。
2年前なら「Vue.jsも触ったことないのに……」と尻込みしてしまうところですが、
ChatGPTのおかげで技術知識の有無はさっぱり考慮しなくていいというのは本当に便利な時代になったなと思います。


#7243

CSSを学び直すのも面白いかも

今日の出来事web制作CSS

自分のweb技術の習得遍歴は、一番最初が2005年のHTMLで少し遅れてCSS、
そしてWordPressをいじるようになってからようやくPHPに触れるようになり、
最近はjavascript(ES2015)といった感じになっています。
HTMLとCSSの間に少し時間差があり、最初期の特設サイトはHTMLのみで書きました。
HTMLの属性で直接スタイルを指定していたような時代です。
その後、CSSというスタイル指定専用の技術があると知り随分と感動した思い出。
HTMLは単にページ構造をルールに沿って書くだけですが、
CSSはクラス名を定義して別ファイルでその内容を記述していくというところが
HTMLと違ってプログラミングっぽいと思ったものです。
ある意味自分にとってのwebエンジニアとしての原点と言えるかもしれません。


そのCSS、長らく基礎だけで凌いできましたが最近になって再学習の必要性を感じています。
というのも、CSS3過渡期だった当時と違って最近のCSSはめちゃくちゃ進化している!
CSS単独で変数(ver)を扱えるようになっていたり、アニメーションの実装ができたり、
さらに直近ではスクロールドリブンアニメーションと言って、
スクロールの状態に応じて要素をアニメーション変化させることもできるんだとか。
最近の凝ったサイトでよく見る、スクロール連動で動くやつもおそらくCSSで実装するのでしょう。
CSSを再学習すればよりインタラクティブなデザインができるようになるという期待があり、
そういう意味でも最近の変化点を追う意義はありそう。
もちろん、既存プロジェクトにそれを適用する意味があるかどうかは別の問題ですが。


ピクチャレ大会をきっかけに知った「Styled-Component」もとても面白い技術で、
これはjavascriptの中にヒアドキュメントとしてCSSを記述することで柔軟性を持たせつつ、
コンポーネントを上書きする形で簡単にスタイルを適用できるため、
クラス名をいちいち定義せずともコンポーネントごとにスタイルを記述できるというものです。
Next.jsではとりあえずこれをマスターすれば困らなさそうな感じがしていますが、
これに最新のCSS技術を組み合わせたらもっと面白いことになりそう。


こうした新技術に対する偽りなき好奇心はwebクリエイターの大きな原動力になると思います。
少なくとも自分に関しては、
そうした好奇心のおかげでここまで来ていると言っても過言ではないと思います。
その好奇心を満たすためにも、技術領域の最新ニュースを取得することは今後も続けていこうかと。
まあ、基本的にはGoogleアプリ辺りが自動的に配信してくれるんですけどね。
本当に便利な世の中になったと思います。


#7123

webアプリのログイン認証

今日の出来事web制作

この2連休は、新ピクチャレ大会にログイン認証を実装する作業にすべてを捧げました。
寝ている以外のほとんどの時間を費やし、日曜日の26時についにログイン通過。
この紆余曲折はぜひQiitaにでも書いて共有したいところではありますが、
経緯を丁寧に書いているとそれだけでまた数日潰れるのでブログで勘弁してください。


まず、要件として今回のログイン機能はフロントエンドがNext.js、
バックエンドがLaravelでそれぞれをDockerが仮想コンテナ上に構築している、
という前提のもと、名前とパスワードのみ登録していた前サービスを引き継ぐ必要がありました。
そこで最初に取り掛かったのがLaravelが提供する「Laravel Breeze」というライブラリ。
これを導入すればすごく簡単にログイン認証をつけられるというもので、
実際に2020年にLaravelの研修を受けた際にもできた記憶があるので、
まあこれが無難だろと思って着手しました。が、丸一日かけても実装することはできませんでした。


その主な要因は2つ。
まず、Laravel Breezeは基本的にLaravelで完結するwebアプリを想定していること。
つまり、フロントエンドもLaravelのBlade等で表示する想定の構造になっているということです。
もちろんそのBladeをReact等に置き換えることはできなくはないのですが、
今回のプロジェクトは表示部分とAPI部分をコンテナから分離してしまったため、
Laravelで構築したサービスを運用するためにはどうしたってAPIを通さなければなりません。
Laravel Breezeの内部構造を見るとAPIではないルートにもアクセスするよう定義されていて、
ここにアクセスできるようにいまから改修するのは非常に難しい。
というか自分にできるのかという問題が。


もうひとつは、LaravelコンテナとNextコンテナはそれぞれ別のネットワークなので、
これを両者間で認証情報を伴う通信を開通させるのが非常に難しい。
言うなれば異なるコンテナはそれぞれ見知らぬ人が運営するサイトのようなものなので、
当然簡単に相互書き込みできないようにネットワーク上のルールが決められています。
その例外を作ってトンネルを開けるのですが、
Dockerだとこっちから見るとlocalhostなのにあっちからは全然違うIPだったりしてややこしい。
結局これで匙を投げて、別のライブラリを探すことにしました。
それまででも結構な作業時間を費やしていたので損切りには勇気が要りました。


次に試したのは「Next-Auth」。つまり、今度はフロントエンド側のライブラリ。
簡単にSSO(シングルサインオン)を構築できるなどハードルの低さが売りみたいで、
もちろんパスワード認証にも対応している。
これは期待できるぞと思っていざ着手してみると、
公式のドキュメントがあまりにも少ないことに気づきました。
公式はパスワード認証を「非推奨」としており、なるべく使ってほしくない意図があるそうです。
なのでいちおう機能としては用意するけど、パスワードの保存先や暗号化は自前で実装してね、
ということらしい。なんてこった。
しかし世界は広いもので、自前でフルスタックのNext-Auth製パスワード認証機能を作った猛者が、
Githubに全ソースを公開していたのでそれを参考に作ることにしました。


パスワードの保存先は最近流行りのクラウドサービスに頼るという手もありましたが、
既存のMySQLサーバーを流用できる「Prisma」というライブラリに頼ることにしました。
これはざっくり言うとフロントエンド側でデータベースの中身を操作できるライブラリです。
具体的にはデータの読み書きはもちろん、テーブルの作成や定義、初期値の入れ込みなど、
Laravelでできる基本的なことはシンプルにできるようになっています。
あまりにもあっさりできたので、
「これもうLaravel要らないんじゃね?」と思わずにいられませんでした。


ただそこから先は苦行でした。無料公開していたGithubのオープンソースも結構ガバガバで、
とにかく押しても引いてもエラーが出る。そのたびにエラーの内容を検証しては次に進む。
2日目の夜からはChatGPTにも頼ってひたすらエラーをつぶしまくりました。
そして苦節30時間(推定)、ついにログインに成功!
いやー、webプログラミングでここまでの達成感を味わったのはひさびさな気がする。
この2日だけでDevToolsの使い方を始め、かなり問題解決能力は上がったと思います。
あとやっぱりプログラミング分野に関してはChatGPTは有能ですね。
「この情報群のどこかに答えはあるんだけどその探し方がわからない」
といった場合にソースコードとエラーメッセージを投げると結構的確に答えてくれました。
割と真面目にChatGPTが自分にとってのメンターになりうると思っています。
いままではエラーが出たら「エラーメッセージでググる」「公式ドキュメントを読む」
といった程度が関の山でしたが、
今回の試行錯誤を経て「ロガーを仕込む」「ネットワークログを読み解く」
といった手法も開拓しました。
特に後者はコンソールでエラーが出ていない場合もエラーが表示されている場合があり、
非同期通信などを伴う処理ではチェックは必須と言って良さそうです。


残り時間がどんどん少なくなってきて少しずつ焦りも出てきたピクチャレ大会開発ですが、
ひとまず最大の山場(?)を越えられたのはなによりです。
あと1つ大型のタスクを残しているのですが、それが今回よりキツくないことを祈っています……。