今年の本業は、 3rd party script で、そこから呼ぶウィジェットを最適化するコンパイラを書く、その仕様を考えて、実装するという感じだった。要は Google Analytics と、最適化コンパイラ付き GTM みたいなものを作っていた。その内容は以下に書いた。
パフォーマンス改善に Core WebVitals という大義名分を得た
今年は、 パフォーマンスのエンジニアをやっていた、と思う。サードパーティスクリプトの配信を生業にする会社のエンジニアとしては、来年の Core WebVitals というパフォーマンス関連の大きな変化で、波にのってやりたいことがやれたと思う。 Core WebVitals の導入で実際にどれぐらいの影響がでるか不明だが、パフォーマンスが SEO に影響する、というのは、 若干やりすぎと思いつつも、 Google の目指す Web の世界観と、モバイルがメインとなったエンドユーザーの体験にとって両方大事なもので、とくにフロントエンド周りで富豪的なプログラミングを常態化しつつあったエンジニアコミュニティの開発スタイルに一石を投じるものではあった。
大義名分として利用はしているが、SEO最適化そのものを目的にするのではなく、コンテンツしかり、ユーザーの体験を最適化すると、それが評価される、というのは正しい世界観であると思い、同調している。Chrome に組み込まれている Lighthouse は Idiomatic な計測ツールだが、他のツールが有意義な指標を出せてない以上、まずこれに従うべきだと思っている。そのための根拠は一応提示されている。
Next.js 再評価と Lighthouse
Web の最適化を考えることで、自分は Next.js を再び強く評価するようになった。
Core WebVitalsの指標は、フロントエンドの改善に目がいきがちだが、ある程度やるとサーバーサイド込みで改善が必要で、その最適化をある程度以上すすめるには、現状 Next.js のようなクラサバまたがる最適化が必要、という認識を持った。
Lighthouse の意義は、パフォーマンス最適化を、スコアによってゲーミフィケーションしたことだと思っていて、これによって今まで意識することが少なかったパフォーマンスや、アクセシビリティに開発者の意識を向けることに成功している。
Lighthouse によって、手軽にフロントエンドのISUCON的なことができるようになった。お題は無限にあるので、まずは自社の重い画面を分析してみるとよいと思う。
現時点のベストプラクティスは静的サイトの動的更新の JAMStack であると認識しているが、CI を通って更新するので、コンテンツの更新が遅く、 そうでない場合は Next.js + ISR がイケてる。
ただし、これも結果整合で Edge Cache の不整合が発生するので、運用者にそれの説明コストを払う必要があったり、事故ったりした際のリカバリがきつそうな気もしている。
そのへんで期待してるのが Cloudflare Workers 関連のプロダクトで、 CDN Edge でJSでロジックを書いて、素早いキャッシュパージができる。
現状でも Fastly VCL でも可能なのだが、 Fastly の仕様にロックインしてしまう。現時点で自分は Fastly に賭けるみたいな判断・覚悟ができてないため、次の仕様が普及することを期待している。
Fastly は確かにすごいのだが、これに詳しくなると Fastly でしかフロントエンドが作れない人間になってしまう危機感が常にあって、なかなか手が出ない。
日経電子版のチームはFastlyがっつり使いこなしていてすごい。会社としてロックインする、みたいな覚悟がないと、これはできない。
サードパーティスクリプト改善への取り組み
自分の仕事としては、 3rd party script というテーマがなかなか面白くて、ITP や GDPR がある環境の中、いかにパフォーマンスに配慮しながら、かつ 3rd という限られた環境で、いかにメインスレッドを専有せずに自分のタスクを遂行するか、ということをずっと考えていて Web Worker (Dedicated Worker) を使ったフロントエンドののプログラミングスタイルを試行錯誤していた。
その中でもとくに、 comlink インスパイアで作った minlink という自作ライブラリが、メチャクチャ小さいサイズながら、よく動いていて、自分でも気に入っている。 node の worker-thread の勉強も兼ねて、 node 対応もしてある。
- Web Worker の使用 - Web API | MDN
- off-the-main-thread の時代 - mizchi's blog
- mizchi/minlink: Minimum(> 1kb) and isomorphic worker wrapper with comlink like rpc.
今年前半部の反省なのだが、3rd party script の一部に、自由文脈記述のウィジェットを配信するみたいなものがあるのだが、パフォーマンス意識するあまり、コーディング規約を増やしすぎて、クリエイティビティを疎かにするような仕組みを作ってしまった。 最初は preact + css in js, terser で treeshaking + Dead Code Elimination を有効にする書き方を推奨するつもりだったが、何人かに書いてもらってみて、それを意識してコードを使いこなせる人間は、あまりにも少ないことがわかった。
terser のデッドコード検知はかなり賢いのだが、それは書き手が terser のコード畳み込みを意識して書いた場合に発動するもので、自由奔放に書いてもコードが削れるものではない。Terser REPL で色々と試した結果、そういう認識になった。
そこでたどり着いたのが svelte + svelte-check で、 元々は Svelte の TypeScript 対応という触れ込みで触ってみたのだが、 CSS と JS の変数で、デッドコードへの警告が出せたり、アクセシビリティの警告が出せる、ということがわかった。
下手に DCE を意識してコードを書くより、CIを通して未使用コードを検知できる仕組みが作れた。
いろんな賢い仕組みを作ってみたが、結局「生産性やクリエイティビティを犠牲にしてパフォーマンスを選択する」ということは不可能で、仕様を作る人間としては、それを意識させない仕組みを提示する必要がある。svelte は小さいビルドサイズながらなかなかリッチな表現形態を持っていて「ライブラリではなくコンパイラ」という思想をよく体現している。
rollup と svelte は webpack と違って ブラウザで動かせるので、 rollup を svelte コンパイラ込みでクライアント向けにビルドして、サーバーを介さない、高速なプレビューを実装できた。そこは OSS にしてある。
今年は、 svelte と rollup という Rich Harris 製の OSS にお世話になることが多かった。
browserify の Node.js エミュレータという世界観で始まったフロントエンドビルドツール界隈だが、ES Modules がすべて、という世界観によって、 Node.js の一強という世界観が薄れて、 Deno や Skypack が台頭しつつあるように感じる。
IE との付き合い方
IE との付き合い方を、今までとは根本的に発想を変えた。IE でも動く水準で仕様を考えたりコンパイルするのではなく、いかにIEを意識せずに仕様を決めるかを意識した。
その上で IE を別系統でビルドして、メインストリームの開発環境からIEに縛られているという悪影響を排除するか? という考え方をするようにした。
2020年時点でたった 4% の IE に発想を縛られるということが悪だと思っていて、モダンブラウザ向けに仕様を考えたあと、いかにIEで再現できるか、というステップを踏むことにした。
それで作業量が減ったかというと、結局は別系統のビルドができてしまい、その関係で IE 対応に 1ヶ月ぐらい時間を使ったりしてしまったので、作業工数としてはやはり見積もりづらく、辛い。早くIEのことを考えない世界に行きたい。
来年の話
反省点として、実際にフロントエンドの問題だと思って取り組んだものが実際にはサーバーサイドの問題だったことがあった。フロントエンドの問題を潰したことでそれが浮かび上がったので、フロントエンドの改善には一定の意義があったのだが、実際には DataDog APM を見る必要があった。
フロントエンドや埋め込みタグというテーマだったせいか、マイクロチューニングにばかり詳しくなってしまい、来年は datadog も合わせてサーバーサイドと合わせて多面的にパフォーマンスを計測できるようになりたい。
結局、 Next.js フルスタックが必要だ、と思ったのも、Core WebVitals のパフォーマンス改善でクライアント・サーバーを複合的に見れる人が少ない、という問題意識がある。自分もミスをしたので、パフォーマンスのエンジニアを名乗るにはまだまだ未熟で、精進が必要だと思う。
フルスタック Next.js 調べるのに、最近データベース周りを調査していて、最近 postgres が熱いのでは、と気づいた。主に create trigger のリアクティブ性によって、新しい発想のフレームワーク・ライブラリ・環境が出現してきている。
- CREATE TRIGGER
- supabase/supabase: Website, docs, and examples. Follow to stay updated about our public Beta.
- Materialize – A Streaming Database for Real-Time Applications
- Hasura | Instant GraphQL APIs for your data | Join data across databases, GraphQL & REST services to build powerful modern applications
最近、というか年末年始は、Next.js の本を書く予定。ただ最近、 among us と スターデューバレー 1.5 にハマってしまったため、年末年始に書き上がるかは、それらがどう転ぶか次第。
他細かいやってたこと
- vue
- k8s
- kustomize など
- チームメンバーが詳しいので、もっぱらコンテナハッシュを更新するという体験
- 個人で学習用クラスタを建てたが、高いので閉じてしまったどうにかしたい
- Chakra UI
- React で Tailwindみたいなユーティリティ指向のコンポーネント書く時にめっちゃ便利
- tailwind 自体は、なれてないせいもあるかもだが、なんか肌になじまない
- AMP
- 調査対象
- Google Analytics
- 調査対象
- タグの実装はいいとして、管理画面複雑すぎる。データ分析用の仮説が Analytics 側で存在してそのフレームワークに乗ることを強制させられる。エンジニアとしては、関係で送ったデータがどこに保存されてるのか、まったくわからん
- Google Big Query
- 仕事
- 最近 snowflake が気になってる
- Google BigTable
- 仕事
- Google Cloud Pubsub
- 仕事
良いお年を