ポートフォリオは2020年の10月から始まり、今回で6代目を迎えました。
ポートフォリオは一般的には職を得るための制作物と言うイメージが強いですが、個人的には新技術のお試し場と自己顕示欲露呈の場の側面が強いです。表向きのターゲットは採用担当の方であっても、真のターゲットはプログラミング好きな方々と自分だったりします。
デザイン
私はVTuberが好きです。VTuberの何が面白いって、視聴者の想像を超えてくるんですよ!!
ということで今回のポートフォリオのテーマは「控えめだけど驚きのある体験」としました。
といいつつ、まだこのテーマを満たせていませんが……
こんなデザインを予定していたのが、
(中略)
PCではこうなって
モバイルではこんな感じになってます。
控えめは満たせてるけど、驚きのある体験はまだ提供できてなく、課題です……
技術選定
ポートフォリオという役割を鑑みると
- アクセスは少なめ→いわゆるCPU時間の消費は少なくて済む
- 新規ユーザーがほとんど→一発芸的な驚かせ方が許される
- 長く使う→ランニングコストを抑えることが重要
といった観点で選びました!
フロントエンド「SvelteKit」
今回のメインはSvelteKitです!最近v1系になったやつですね!
React系と比べるとスッキリと書けて良い感じです。
もちろん型もしっかり見てくれます。
個人的に嬉しいポイントは、下の階層のページ(たとえば/works/programming)のビルドでフェッチしたデータをその下の階層のページ(/works/programming/作品uuid)でも簡単に使えることです。プログラミング作品の個別ページの下にあるタイムライン的なものはAPIを再度叩かず表示できちゃっています!
そして今回はサーバーレスでサーバーサイドレンダリングしています!言葉が矛盾していますね……サーバーレスという言葉は一体なんなんでしょうか。
SSRしている理由としては、バックエンドのAPIが大きな理由で、Notionは裏側S3な都合で画像URLが変わっちゃうので……って理由です。(CSRもNotionのシークレットキー問題があるので厳しい)
SvelteKitの不満をしいてあげるなら、+page.svelteのような形でファイルが大量に散らばってしまうので、Next.jsなどと比べるとファイルがごちゃつくといったところでしょうか。(ただこれもNext.js 13からのappディレクトリはそうとも言えないので最近の流行りなのかも?)
バックエンド「NotionAPI」
個人開発のコストはDB次第と言われる昨今です。また画像管理も悩ましいポイントです。
microCMSのようなSaaSも悩みましたが、データのエクスポートもできて管理もしやすいNotionをCMSのようにして使うことにしました!
目的のデータまでの階層が恐ろしく深く、またNotionのテーブルのプロパティに応じてJSONの構造や名前が変わります。
APIあるあるですが、少しデータが取り出しにくいです。とは言っても普段のデータ編集が極めて楽になったのでとても満足です!
インフラ「Cloudflare Workers」
SvelteKitをごった煮VPSにぶちこんでSSRさせる手もありました。
でもポートフォリオはコストを掛けず息を長くさせたいという側面もあったので、Cloudflare Pagesあたりを当初予定していました。
作成途中にアクセスカウンターほしいなと思いはじめ、さらにSSRの問題もあり、最終的にはCloudflare Workerになりました。アクセスカウンタはCloudflare Workers KVというRedisみたいなKVS型のデータストアを使っています。
Cloudflareが世界中のエッジサーバーでうすゆきポートフォリオをSSRしてくれているのですが、実際アクセスはほぼ無いので、なんだか申し訳ない気分です……
というか、Cloudflare慈善事業過ぎません???
一方で一番苦労した点はこのインフラ部分なのも事実です。個人としてもインターネットの情報としても圧倒的情報不足でした。
SvelteKitをCloudflare WorkersでSSRしている人がそもそも激レアな上、KVを使ってSvelteKitでアクセスカウンタを作りたい人間はどうやら宇宙初だったらしく、情報が1つとしてありませんでした。
BingAIくんと相談しながら、なんとか色んな情報を参考にして作りました。
(後日談として)しばらく運用した結果、かなりこのKVの無料枠がギリギリだということが分かりました。1日ごとにリセットされるのですが、毎日無料枠の50%は絶対に超えて、日によっては無料枠の90%あたりまで消費することもよくあります。
KVの無料枠は1,000 writes per dayなので、ギリですね……]
機械的なアクセスで地味にリソースを吸われていたり、アクセスカウンタだけでなくSvelteKitのSSR自体もKVを使っていたり、要因は様々です。
追記:アクセスカウンタをブラウザからfetchAPI経由で叩くようにしたことで、KVへの書き込みを大幅に減らすことができました。
一方Cloudflare Workers側は余裕がありそうで安心です。CloudflareはUTC基準なのですが、1日の6割を終えた時点でこんな感じです。
この数字を見るとそれなりにアクセスのあるサイトのように見えなくも無いですが、Google Analytics上、つまり人間がアクセスしてきた可能性の高い(クライアントサイトでJSが実行されて値が送られた)数はですね、
0なんですよ……1人にも見られずKVの無料枠ギリギリまで来ているのはとても悲しいですね……(やはりクライアントからアクセスカウンタのインクリメントエンドポイントを叩くしか無いかも?)
またアクセスされた方はお気づきかと思いますが、レンダリングが少し遅めです。プリフェッチしたりで誤魔化していますが、やはり全てのSSRをサーバーレスでやるのは適切じゃないかもですね……
こだわり
技術の話はおいておいて、こだわりポイントについて紹介させていただきます。
コンソールの装飾
実はブラウザのconsole、一部のCSSをサポートしていたりします。
こういうところって基本見られないんですが、自分は他の方のポートフォリオ見るとき絶対確認する要素です。こういう隠し要素好きなので……
CSSアニメーション
全人類が大好きなCSSアニメーションです。まだまだこれからの部分ですが、気持ち良いアニメーションを増やしていきたいです。
アクセスカウンタ
アクセスカウンタってレトロでいいですよね。ただ静的サイトでは実装が大変なこともあり、ポートフォリオで見る例は少ないのが悲しいです。
アクセスカウンタはレトロな存在ですが、Cloudflare Workers KVをクライアントからAPI経由で書き込ませるモダンな仕組みで実装しています!
テストと静的解析
前回のポートフォリオの反省を踏まえて、TypeScriptによる型チェックをしっかりするようにしました。anyがあるって?いやー……それはしょうがなくて……
CIでlintと静的解析とテストを行っています。これが想像以上に良くて、突貫工事で実装しても最低限静的解析は黙らせなきゃいけない!ってなるので、下限の品質が保たれます。
E2EテストではPlaywrightを使っているので、複数ブラウザのテストもできちゃいます。
このテストでsafariが対応していないコードを書いていることに気づけたり、実際に効果があります!!
変更の理由
さて、そもそも既にNext.jsでポートフォリオを持っていたのになぜポートフォリオを作り直したのかという話です。
技術的負債の解消
旧ポートフォリオはNext.js 13で構成されています。一見ナウでヤングに見えるのですが、当初はNext.jsに初めて触れるために実験的に作ったものであった上、TypeScriptを知らない時代に作ったものでしたので、中身がとんでもない事になっていました。
新規機能追加が絶望的に難しい状態です……
またバックエンドはさらに前のポートフォリオで使っていたDrupalをヘッドレスCMS化して使っていました。
他にも課題としてダイナミックリンクがぶっ壊れており、新しくDrupal側で作品を追加しても個別ページがレンダリングされない問題も抱えていました。
デザインの刷新
また旧ポートフォリオを作った当時は安定したデザインを求めていたのですが、下記のようなデザインは初回のインパクトが大事なポートフォリオにはそぐわないのでは!?と思い始めてきました。
ポートフォリオなんてアクセスした人にとっては人生で1度程度にしか見ないものなので、もっと無難でないものを作りたくなった所存です!!
おわり
旧ポートフォリオは激動の大学3年生を支えてくれました。インターンのESや本選考のESで提出し、たくさんのエンジニアや人事の方に見られたと言うのは紛れもない事実です。R.I.P.