QwikCityでブログを作り直した
QwikCityによるJamStack構成のブログの構築
ブログの書き直し自体がもはや一つの独立した趣味となりつつある。
- https://www.namachan10777.dev/blog/blog-on-nextjs
- https://www.namachan10777.dev/blog/blog-on-rust
- https://www.namachan10777.dev/blog/blog-on-astrojs
Astroは十分に快適だった。key=も要らない。タグで書けば良い。
問題があるとすれば、現代の多くのWebページは静的なものであってもclient:loadすれば済む。document.getElementByIdでイベントを相互に送信し合う迷路のような依存関係が生まれるか、
そもそもとして一つでも別のUIフレームワークを用いた時点でバンドルツリーにはそれのランタイムが紛れ込む。
Markdownの扱いと画像最適化
QwikはイマドキのWebフレームワークとしてSSG機能を備えるし、import.meta.globは使えるが、これだけでは少し不便だ。
content-collectionsを使えばコンテンツ管理の問題は一部解決する。
ただ、content-collectionsはAstroの同名の機能ほどにはViteと連携して動かないので
MarkdownのパースをUIフレームワーク(というよりVite)と連携できないことの問題が最もよく現れるのはunifiedのエコシステムでMarkdownをhtmlに変換するだけではにwidthとheightを付与し、loading="lazy"を指定して最適な幅の画像を自動で読み込ませる ――は実現できない。contents-collectionのコンテンツをビルド時に変換する機能を使い、remarkでMarkdownをパースして画像をビルド時に最適化してしまい、mdastに埋め込む。
無理やりas unknown as Tを使って誤魔化しているが、mdastを定義し直すのはかなり面倒くさい。
;
;
;
;
;
;
;
;
;
;
;
;
;
;
// Assume the output format is WebP
;
;
OGP
satoriで生成したSVGをsharpでWebPに変換して配信する。onStaticGenerate関数を書けばGETエンドポイントも静的にビルドされるので便利だ。dependenciesに書かれたqwikコンポーネントは静的ビルドされたHTMLに含まれない(これは仕様のようだ)。devDependenciesに書いて静的にビルドさせる必要がある。devDependenciesだと解決に失敗する。dependenciesに書く。
一見すると直感的には逆なように感じるが、QwikCityでのビルドはWebサーバーのビルドだと考えると
Pagefind
まずViteは動的インポートでも素直にECMAScriptの仕様通りの動きはさせない。import('/pagefind/pagefind.js?url')のように?urlを付けるだけでバンドルを防止出来る。?urlというクエリパラメータ込みでリクエストをしてしまう。
QwikCityは静的ビルド時は?urlを無視してチャンク分割を試みるので?urlが必要なくなったりはしない。
NextやAstroならこれで解決だが、QwikはクライアントサイドのJSを細切れに分割しJSONシリアライズして通信する仕様上、pagefind.jsはSSRには関与せずクライアントだけでimportするのでuseVisibleTask$を使いたい。useStoreで作ったデータ置き場にnoSerializeでモジュールを配置する。
Qwikのコードはあまり読めていないのでnoSerializeでどうしてうまく動くのかはあまり分からない。useVisibleTask$で取ってきたモジュールを保存しておく、
;
;
;
;
QwikCity雑感
Pros
確かにパフォーマンスの良さは感じる。大抵のことは実現できるように作られているし、
仮想DOMとローダーの綺麗な世界だけではうまく実現できないようなこと
Astroは良かったが、致命的に動的なイベントハンドリングが弱い、というか無い。document.getElementByIdを書くことになり
あとSFCはコンポーネント分割の体験があまり良くない。のサブコンポーネントとしてしか存在しないを
Cons
hooksを一から書くのがかなりキツい。useSignalなどのコードをちらっと見たが、Qwik内部のシステムと強固に繋がっている。を使ったらかなり面倒そうなエラーが発生した。
総評
実務で使うには流石に怖い。