今回、Early Hintsの話をするってことなんですけど、正直、Early Hintsって、僕自身は聞いたことがなくて、ざっくりどんなものかって、ちょっと説明してもらってもいいですかね。
そうですね。最近結構、フロントエンド界隈でちょっと話題になっているのかなと思うんですけど、なんか、HTMLだけ返しても意味ないじゃないですか。
CSSとか、最近だとSPAだとJavaScriptも返さないと、ちゃんと表示できないじゃないですか。
リソース系も返さないといけないですよね。
そうですね。なので、HTML送る前に、CSSとか、事前にダウンロードしてもらった方がいいじゃないですか。
HTMLをダウンロードする前に、リソース系をダウンロードしておく。
そうですね。すれば、HTMLダウンロード終わったら、すぐ表示できるじゃないですか。
すぐレンダリングできますね、確かに。
で、それをやってくれるっていうのが、Early Hintsなんですよ。
なるほど、そういう仕組みなんですね。
このCSSをダウンロードしておいて、みたいなのを先に言っておくっていうのがEarly Hintsですね、ざっくり言うと。
リソース系を、リソースのCSS、JavaScript、あとは他にも、もしかしたら音声ファイルとかそういうのも入るんですかね、バイナリーとか。
音声は入らないですかね。画像とかは、コランプともちょっと話すんだけど、LCPっていう一番目立つ画像とかはやってもいいかもしれないっていう感じですかね。
じゃあ、その特徴というか、そのものによりけりっていうような感じなんですね。
そうですね、その辺も注意点もいろいろあるので、その辺も話していけたらなと思ってます。
はい、じゃあお願いします。じゃあどこからいきましょうかね。
そうですね、ちょっと歴史からちょっと振り返っていきたいかなと思ってて、まず最初にHTTP2サーバープッシュの話からしていきたいなと思ってます。
ほうほうほう、サーバープッシュ。
そうですね。で、実は先日HP2とHP3の話をこのヤイヤルズのオフィシェンスでしたと思うんですけど、
はい、しましたね。
その時に意図的に話さなかったんですよ、実はHTTP2サーバープッシュ。
うんうんうん。
で、なんか多分ちょっと記事とか調べてもらうと、ちょっと前のHP2の記事とか行くと、もうサーバープッシュって結構代々的に載ってるというか、HP2の目玉機能だったんですよ、もともと。
そうですね。なんか僕がHTTP2って言ったら、サーバーからプッシュで通信ができるっていう機能が一個というか、だいたいそれだった気が、それプラス並列でダウンロードできるみたいな、その二大巨頭だったかなという印象なんですけど。
そうですね。当時結構騒がれた機能なんですよ。
うん。
なんだけど、じゃあなんでこの前のHP2、HP3回で一切話しなかったかっていうと、実は今のChromeとか今のブラウザってこのコードック削除されてるんですよ。
サーバープッシュ実装がなくなっているという。
もう消されてます、ブラウザの実装から。なんでもう動かないんですよ。動かないから一切話をしなかったんですよ、実は。
なるほど。使用としてはちなみにまだ残ってるけど、実装としてはないっていう。
たぶんそうですね、使用削除をしてるっていうのはないと思うんだけど、もうブラウザの実装から消えてるから、もう忘れて大丈夫。
実質使えないから。
もう使えないから忘れていいんだけど、そもそもサーバープッシュが何をしようとしてたのかっていうのがearly hintsと関わってくるので、ちょっとそこの話をまず最初にしたいなと思ってます。
はい。
まず最初にちょっと言った通り、HTML受け取ってもCSSとかなかったら、特にすごい昔のサイズだったら表示できるかもしれないけど、今のサイトってCSSとか結構凝ってるからもう表示できないじゃないですか。
JavaScriptとかもなかったら、なんでしょうね、たぶん動かないと思いますね、そもそも。
そもそも適切に表示もできないし、だからHTMLを送るだけじゃなくて、CSSとかJavaScriptも送りたいよねっていうのがまず大前提としてあるんですよ。
サーバーから送りたいよねっていうことですね。
なので、まずブラウザがHTMLくださいってリクエスト送ってくるじゃないですか。
はい。
その時にHTMLだけじゃなくて、強制的にサーバーからCSSとかJavaScriptとかこのリソース必要になるからと持っておくよみたいな感じで、強制的に送りつけてくるっていうのがサーバープッシュだったんですよ。
インデックス.htmlをクライアント側がリクエストしたら、普通だったらHTMLだけを返してくるところをサーバーから、これもこのインデックス.CSSとメイン.JavaScriptも必要だから送りつけておくよみたいな感じで。
そんな感じですね、ざっくり言うと。
一見良さそうに見えるんですよ、どうせ必要になるから。
けどこれ実運用しようってなった時に、色々難しかったんですね。
何かっていうと、サーバー側はブラウザが何のファイルキャッシュで持ってるかって分からないんですよ。
なるほど、例えばさっきの例だったらインデックス.CSSはキャッシュで持ってるんだけど送りつけてしまうってことですね、サーバープッシュの場合は。
そうですね、そのCSSファイル手元に持ってる可能性があるんですよね、ブラウザが。
でもすでにキャッシュ済みのファイルを送りつけたら当然待機無駄になるじゃないですか。
殴りつけられて無駄なデータ容量圧迫しましたみたいな感じになっちゃいますよね。
そう、なんで結局サーバープッシュ有効にした方がパフォーマンスが悪化するっていう結果が出ちゃったんですよ。
キャッシュが使えないからってことですかね。
そうですね、キャッシュが適切に使えないから。
強制パージされてるみたいな感じですね。
クライアント側からしたら。
クライアントがどう動くかはクライアント実装次第だと思うんだけど、結局サーバープッシュしちゃったらクライアントの待機使っちゃうからクライアント側が遅くなっちゃうんですよ。
結果的にってことですね。
なのでサーバープッシュみんな有効にしなくなっちゃったんですよ、結局サーバープッシュ有効にした方が遅いから。
それはユーザー側が、開発者側がサーバープッシュ使えないからっていうこういう問題があるから。
サーバー側かな、基本的にはサーバーサイト側の我々が、我々みたいな開発者が有効にした方が遅いからって理由で無効にし始めたんですよね。
その理由がキャッシュが有効利用できないからってことなんですね。
そうです。みんな無効にし始めちゃったから、じゃあ実装持っとく意味ないじゃんって言ってブラウザから消えたんですよ。
ちょっと面白い話ですね。実際に運用し始めたら問題が発生したという。
実際に運用し始めたら全然ダメじゃんってなっちゃったんですね。
これって結構根本的な問題で、結局サーバー側からはクライアントが何をキャッシュとして持ってるのかっていうのはもう分からないから、何をプッシュすべきか分からないっていう根本的な問題なんですよ。
分かんないですよね。分かりようがないですよね。
分かりようがない。ここで実はサーバープッシュ活用できないかっていうので模索した歴史があって、
それで結構特に日本だと有名なのがCASPERって呼ばれている仕様です。
これはH2OっていうHPサーバーの実装があるんですけど、H2Oで実際に実装されていたものになるんですけど、
これ以前ブラウザー会の時に話をしたと思うんですけど、
その時にブルームフィルターの話をしたんですけど、覚えてます?
ブルームフィルター覚えてます。なんか難しそうだなと思いました。
ブルームフィルターの特徴として、擬音性はないけど擬音性はあるっていうのが特徴なんですね。
つまりブルームフィルターって、trueかfalseかっていう情報だけが持てるデータ構造なんだけど、
キャッシュで使った場合、ブルームフィルターがキャッシュがないって言ったら絶対にキャッシュを持ってない。
けどブルームフィルターがキャッシュがあるって言った時に本当にキャッシュを持ってるか分からないっていうのがブルームフィルターのデータとしての特徴になるんですよ。
これってあれ今回において結構便利じゃないっていう。
例えばこのCSSのキャッシュ持ってるってブルームフィルターに聞いてないって言ったらその人絶対持ってないから送りつけちゃっていいんですよ。
けど持ってるって言われた時に送らなかったとして、じゃあ問題になるかって言ったらHTMLを返した後にHTMLを解析してこのCSSいるじゃんってリクエスト送ってくるから問題ないんですよ。
ちゃんとフォールバックしてくれるってことですよね。
そうですね。なのでその欲しい情報はキャッシュ持ってるかどうかじゃなくてキャッシュを絶対に持ってないっていう情報だけなんですよ。
確かに。
なのでこれってブルームフィルターぴったしじゃん。
なんでそのユーザーが持っているそのキャッシュをブルームフィルターに入れてでブルームフィルターでサーバーにブルームフィルターのデータを送ってでサーバーで判定するどのサーバープッシュをどのファイルをサーバープッシュしたらいいかっていうのを判定させるっていうのがCASPERっていう仕様です。
なんかうまくいきそうな気がしますけどね。
CASPERはクッキーを利用して実際にブラウザーでその挙動させようとしたらクッキー以外あまり使えないと思うんで基本クッキーだったんですよ。
一応実際に実装もあって動くねってなったんですよ。
なるほど。なんかクッキーを使うっていうところがちょっと怪しいなという気が若干してきたんですけど。
クッキーは試しに実装してみましたみたいな温度感。
実験として。
これでちゃんと動くねっていう実証実験としてやられたものっていう認識です。自分の認識だと。
なので実際にブラウザーでやるとしたら専用の仕組みを使ってそのブルームフィルターの情報を送れないかっていう提案までは一応出されたんだよね。
だけど結構大変じゃないですか。実装するの。
なんかいろいろ巻き込みそうだなとは思いますね。そのブラウザ側の実装も。
結局ブラウザーがこれを実装しないといけないし、ブラウザーが送ったとしてサーバーが本当に使うかわかんないし。
っていうので誰も実装しなかったんですよこれを。
これやろうとしたら本当に10年計画とかそういう感じになりそうな気がしますね。
たぶんそう。各ブラウザで合意とってみたいな結構大変なことをしないといけなかったと思うんだけど結局これ大変だから誰も実装しなかったと。
なので正直このキャスパーがうまくいかなかった時点でもうサーバープッシュの運命は決まっていたっていう感じなんですよね。
なるほど。難しかったという。
そう結局サーバー側にブラウザーのキャッシュの状態を伝えるっていうのは非常に難しかった。
ただこのブルーフィルター自体は面白いと思ってて結局そのブラウザーのキャッシュってなんか元々あったけど消しちゃいましたとかもあり得るじゃないですか。
あり得ますね。メモリの関係とか。
消しちゃっても大丈夫なんだけどその擬応性はあるからブルーフィルターにおいて。
だから消しちゃっても特に誤作動とかしないんだけど結局本当にあるかどうかわかんないんで結局どんだけあり得る意味あるのみたいな話はあるんだけどただ一応うまくは動くんだよねそれでも。
だからこの仕組み自体は結構個人的には面白いと思ってるので今回話す意味あるかなと思って話してるんですけどただブラウザの実装としてはうまくいかなかったっていうところですね。
本当にブルーフィルターがバッチリはまる的確な場所だったんだなっていう気がしますね。
そうですね確かにここブルーフィルターぴったしはまるなって自分も当時思ったんでただ結局使われなかったっていうところですね。
難しかったと結果的にはね。
でもやっぱり欲しいってなったんですよ。やっぱりhtml返す前にcssとかそういうの返したいよねって。だって絶対必要だってわかってんだから。
っていうのでなんかやり方ないのサーバープッシュは失敗したけどやっぱりやる方法ないのっていうのでいろいろ考えて出てきたのが今回のearly hintsなんですよ。
なるほど。
でearly hintsの目的は一緒です。
htmlを待ってる間にcssとかjavascriptとかそういうのの取得を進めたいっていう話なんですよ。
一緒ですね。
けど今回はリソースそのものをサーバーからプッシュするんじゃなくて103early hintsっていうステータスコードを使ってこのリンクヘッダーでこのリソースこれから使うよってブラウザに伝える。
ボディーはないんですよね。ボディーはなくてそのヘッダーだけでこのリソース使うよとだけ伝える。
なるほど。データは送らずに先に軽量なデータだけ送ってしまう。
まあ卒業のヘッダーだけ送るって感じですね。
でその送られてきたやつをブラウザが実際に取得するかどうかはブラウザが判断するんですよ。
キャッシュ持ってるかどうかもあるのでそこをクライアント側に判定させる。
そうです。ブラウザ側にこのファイル使うよってだけ言っといてでブラウザ側は自分でファイル自分のキャッシュ持ってるかどうか確認してキャッシュ持ってなかったらゲストするしキャッシュ持ってたら何もしない。
すごい簡単に言うとHTMLパースするのを省いてあげてるって感じですよね。
まあ省けはしないんだけどね。結局HTML返してきたらHTMLパースする必要あるんだけど、
普通の処理だとまずHTMLきました、HTMLパースしました、Dedum構造作りました。
で一個一個上から見ていって、CSSファイル必要だってなったらそこにリクエスト飛ばします。
でCSSファイル返ってきたらそのCSSファイルまたパースしてでそれをHTMLDOM構造に当て込むみたいなことをやってるんだよねブラウザって。
なんだけどearly hintsでHTML来る前にCSSファイル必要だよって言っとくとCSSファイルのダウンロードをまずしといてくれると。
でダウンロード、例えばダウンロード終わった後にHTMLがすぐ返ってきましたと。
でHTMLパースしてHTML解析しますって言ったらこのCSS必要ですってなってもうすでにそのCSSダウンロード済みなんでじゃあこれ使いましょうってなる。
っていうのがざっくりとしたそのearly hintsを使った時のブラウザ側の挙動になりますね。
ちなみにこれ一番最初さっきの例をもう一回挙げるとindex.htmlをゲットするわけじゃないですか一番最初はブラウザ側が。
その時にゲットから返ってくるレスポンスが一個じゃなくてこの103early hintsが複数個返ってくるプラス200のゲットが返ってくるHTMLのボディが返ってくるみたいなイメージなんですかね。
そうですね。その話をすると103early hintsっていうのは情報レスポンスって言われてる結構特殊なレスポンスになるんですね。
最終レスポンスの前に送られてくる中間レスポンスって呼ばれるやつで普通にリクエスト送ったら200番が返ってくるだけだと思うんですけどそうじゃなくてその200番が返ってくる前に103のボディからのレスポンスだけ返ってきてけどまだリクエストは続いていて普段我々が見る200番のレスポンスがその後に返ってくる。
なのでレスポンスが2つ返ってくるイメージですね。
地続きというか並列で走っていて103が途中で走ってくるっていう。
最初の中間で入ってくる。
これ絶対中間なんですかね。ちなみに200が返ってきた後に103が来るってことはないんですかね。
なんでかというと互換性の問題で200が返ってきた後に他のやつが入ってくるっていう仕様を入れたとしても多分ほとんどのブラウザーは200返ってきたらその場で終了しちゃうんで。
ですよね。
だから互換性の問題でそういう実は突っ込めないんです。
なるほどじゃあ200を返している間に103を返さないといけないんですね。
200返す前に103を返さないといけない。
なるほど難しいな。
そうなんでちょっとここが分かりにくい。今まであんまなかったと思うんで。
こういう挙動も見たことないし。多分あれですよね。ChromeのDevToolsとか見てると200の前に103が来てるみたいな挙動になるんですかね。
なるはずだね。
なるほど。
なんでここがちょっと分かりにくい。
分かりにくいってか難しいですね。ちょっと理解が。
100番台のレスポンスはこういう情報レスポンスって呼ばれているものでちょっと特殊な挙動をするものになるんですね。
なるほど。ちなみにこの103のやつは複数項あり得るってことですよね。
えっと複数項は多分ないんじゃないか。ちょっとやったことないんだけど。リンクヘッダーで複数返せる。
なるほどじゃあ1個で1個の103レスポンスで複数項が出てくる。
複数のリンクヘッダーを返すことはできるので普通そうやる。
もう1回103返せるのかなちょっとやったことはない。
でも1個にまとめて送りつける。
普通1個にまとめるべきだね。
理解できました。
なんでここがちょっと分かりにくいところなんですけどそういう挙動をしますアーリヒンツは。
そして。
それでアーリヒンツどういう時に使うといいのっていうかその分かりやすいユースケースで何っていうところで最近ってなんかNext.jsみたいな
サーバーサイドレンダリングするような仕組みっていろいろあるじゃないですか。
ありますねリアクトのコンポーネントをサーバーサイドでレンダリングして結果をクライアントに返すってやつ。
そういう仕組みを動かす時ってユーザーがリクエスト送ったらNext.jsがそのサーバーサイドレンダリングでHTMLを生成し始めるわけじゃないですか。
でそのHTMLを生成って時間かかるわけですよ。
でそのHTML生成してる間にユーザーが暇してるわけじゃないですか。
クライアント側は待ちぼうけしてますね。
その間にCSSとかそういうダウンロード先にしてもらった方がいいじゃんっていう。
まあ確かに。
なので一番の効果が大きい分かりやすい効果が出やすいのがサーバーサイドレンダリングで時間がかかる。
でアブアプリケーションで事前にCSSとかそういうのをダウンロードしてもらうっていう時にこの103アリヒンツが便利なんですよね。
そもそもHTMLをダウンロードするもしくは生成する処理が時間かかるところの方が効果は大きいよねってことですよね。
そうですね。
確かにそうですね。
他の例で言うとデータベースのHTMLをレンダリングするのにデータベースへの問い合わせが必要でちょっと時間かかっちゃったりとか
あとは外部のAPI叩いてるとかそういうのが分かりやすかったりするんですかね。
そうですね。そういうケース。要はバックエンドが遅いケースですね。
バックエンドが遅いケースってそんなにあるのっていうと最近はそういうサーバーサイドレンダリング頑張ってやる仕組みっていうのが増えてるので
バックエンドが遅い仕組みっていうのはやっぱり結構あると。
なのでアーリーヒンツがいいんじゃないかっていうのでちょっと注目され始めてるってところですね。
確かに。なんか効果出そうだなという気がしてきましたね。
そうですね。なんですけどいろいろ注意点というかここまでの話でちょっと注意してほしいところもあって
やっぱりその例えばNext.jsで103アリーヒンツ返そうと思った時に
例えばユーザーがリクエストを送ってNext.jsに来ますと。
例えばNext.jsがサーバーサイドレンダリングする前に103アリーヒンツ返して
その後にサーバーサイドレンダリングし始めますっていうプログラムでいいじゃんって思うかもしれないんですけど
そうなんじゃないかなと思ったんですけど違う。
違くはないんだけど本当にそれでいいのっていうところがあって
例えばサーバーが日本にあります。ユーザーはアフリカとか日本からだいぶ遠いところにいますと。
そもそもそのオリジンに行くのに時間がかかりますっていうケースがあり得るんですよ。
そういう時にまだ無駄してるよねっていう。
要はオリジンのNext.jsに到達するまでに結構時間かかってるじゃんって。
その間に103アリーヒンツ返してCSSとかJavaScriptをダウンロードしてもらってたらいいじゃないですか。
もちろんそうですね。
そう考えると一番103アリーヒンツの効果が出やすいのはCDNのエッジから返す方法なんですよ。
CDN側が103を返してしまう。
CDNが103返してその間にCDNがオリジンに対してリクエスト送るというのが一番効果が出る方法なんですよ。
エッジサーバーから返してるからそもそもリソースファイルのダウンロードは早いしってことですよね。
リソースファイルが例えばCDN上でキャッシュされてたらもちろんそうなるし
オリジンに対してそもそも通信行くのに時間がかかるっていうアプリケーションの性質上あり得るから
本当にそのユーザーにとって103アリーヒンツの効果を最大化したいんだったらCDNのエッジでアリーヒンツを返すっていうのが基本的な考え方になるんですね。
それはそうだな。
そうなるとCDNのエッジから返すってことを考えると
難しいなと思います。
この辺からだんだん難しくなってくるんですけど。
なんでCDNさんはHTMLの中に組み込まれて必要なCSSとかを知ってるんですかね。
その辺も真面目に考えないといけなくて。
以前見たことある仕組みでCDNが返ってきたHTMLを解析して必要なCSSをアリーヒンツで返すっていう実装をやってる人を以前僕見たことあるんですけど
これは全く意味がなくてなんでかっていうと結局HTMLが返ってきたらすぐユーザーに返しちゃった方がいいんですよ。
CDN上で解析して何がアリーヒンツで必要なのか解析するよりもHTML返してブラウザ上で解析してもらった方がいい。
確かに意味ないですよね。
だからHTMLを生成するのに時間がかかるからHTMLを生成する前にCSSとかそういうのを先にダウンロードしてもらいたいっていうのがアリーヒンツの考え方なのでこれは全く意味がないんですよ。
そうですね。それがいいんだったらCDNでHTMLキャッシュすればいいだけですよね。
そうですね。そうなるとCDNでHTMLキャッシュしてるシステムだったらアリーヒンツはそれやっぱりいらなくてなんとかリクエスト来た時にすぐ返せばいいから。
そうなので本当にこれはHTMLを生成するのに時間がかかるケースで効果があるって思った方がいいんだよね。
だけどCDNでアリーヒンツを返すことはロジック上難しそうだなっていうところが。
この後もちょっと話すんですけどこれね真面目にじゃあCDNのエッジから返せるかっていうのを結構考えていくとねだんだん難しくなってきます。
っていうのと他の条件として結構この辺が勘違いされてるなと思ってるところなんだけど103とりあえず返せばいいっていう話では実はなくて。
でChromeもアリーヒンツはHP2もしくはHP3を使ってる時に限定して返すことを推奨してるんだよね。
103自体はHP1.1から存在しているのでHP1.1の時に返しても別に問題はないんだけどそもそもHP1.1しか対応してないクライアントって古いクライアントなんだよね。
まあそうですよね。
なのでその100万台のレスポンスとか103を正しく実装してるか分かんない。
そういう103を正しく実装してるか分からない実装に対して103返すと10中8が誤作動しちゃうので返すのは危ないんだよね。
無視するならまだしも変な挙動をする可能性がある。
変な挙動をする可能性があるので
HP2とHP3以外に103ありヒンツ返すのはリスクがあるって言われてるんですよ。
その古いクライアントが変にサポートしてる可能性があるから返さない方がいいよねってことですね。
世の中に色々実装あるんでHP1.1の実装すべての実装に対して103ありヒンツ本当に返せるのかって誰もわかんないんだよね。
だから返しちゃダメ。基本的にHP1.1だと返しちゃダメでHP2またはHP3の時に限定して返すことが今推奨されているのがありヒンツです。
とりあえず2と3にだけ絞っておけば足切りはできてるよねみたいなことですね。
多分大丈夫でしょうって言われてます。
もしブラウザー以外に返すのは嫌だとかあともうちょっと楽に実装したりとかそういうのがあるんだったら
一番いいのがセックフェッチモードってヘッダーで今のブラウザって開発者のやつ見ればわかるんだけど
結構今のブラウザって色んなヘッダー送ってきてるんですよ。
でそのうちの一つがセックフェッチモードでセックフェッチモードナビゲートっていうのが入っていたら
ありヒンツを返すっていうのが一番良いと言われていて
何でかというとこのヘッダー返した時しかクロームはありヒンツを解釈しないんですよそもそも。
でセックフェッチモードナビゲート返すのどういう時かというと普通にそのHTMLを取ってきてる時ですね。
例えばそのCSSとかそういうのを取得している時はナビゲート返ってこないんですよ。
ユーザーが画面というかページにアクセスした時が基本的にはセックフェッチモードが
ナビゲートになってるっていうことなんですね。
例えばなんかその設定ミスっててCSSとかそのHTML以外のやつにもありヒンツ返してたみたいになると
これって良くないんですよね。ブラウザー協務するだけだと思うんだけど変なレスポンス返しちゃってるから良くないんですよパフォーマンス的に。
無駄だよねってことですね。
無駄なレスポンス返しちゃってるから。
なのでそういうのが怖かったりとかHP2、HP3だとブラウザー以外にも返しちゃうのがちょっと怖いとか
何かそういうのがあるんだったらそのセックフェッチモードナビゲートの時だけ返すっていうのが一応お勧めされている方法です。
なるほど。ユーザーエージェントを見るっていうわけではないんですね。
ユーザーエージェントを見るんじゃなくてHP2かHP3を使っているもしくはセックフェッチモードナビゲートが入っている。
もしくは両方とも見てもいいんだけどそういう風にやって全部のクライアントに対してありヒンツは返さないっていうのが重要です。
ここら辺を守っていれば安全に使える。
そうですね。
正しいクライアントで正しく使えるっていうような、ほぼほぼ正しく使える。
これだったらほぼほぼ大丈夫でしょうっていうやり方がこのやり方です。
結構この辺りちゃんと理解せずに適当にありヒンツ返している人がちょっと自分の観測範囲だと散見されるのでちょっとこの辺は気をつけてほしいなと思っているところですね。
重要ですね。なんか下手にやってしまうと変な挙動になってる。多分ですけど面倒くさいバグを踏む可能性があるってことですよね。
まあだしやっぱ一番怖いのってBotなんだよね。
現在のインターネットって結構意識しない人も多いんですけど今のインターネットで気をつけないといけないことって
我々が普段使っているブラウザーとあとBot、Google BotとかAIのクローラーとかあの手のBotが使っている技術とブラウザーが使っている技術って違うんだよね。
そこが結構気をつけないといけないところなんですよ。今のインターネットで。
例えばGzip圧縮ってあるけど、例えばブロトリとか他のやつも今はあって、
けどブロトリってBotはあんまり対応してなかったりとかもするし、あと今のブラウザーってHP2、HP3以外のリクエストってあんまり送ってこないんだけど、
BotだとHP2を送ってくるBotもあるけど、HP1.1の方が主流っていう国とかもあるし、
HP3はほぼ絶対送ってこないんだよね、Botって。
対応してないんだ。
対応してないBotがほとんどだったりとかもするし、本当にいろんな技術がブラウザーとBotが使っている技術が今だいぶ乖離しちゃってるっていうのが今のインターネットなんですよ。
ちょっとこのBotの話はそれ単体で聞きたいですね、単純に。
単体で話すことあるかわからないんですけど、そのBotって多すぎるんで。
なのでその適当にアリヒンツ返すと壊れるとしたらBotなんだよね。
だから実はBotで壊れてて、実はひどいことにサービスになってましたけど、ブラウザーで動いてたんでずっと気づいてなかったですみたいなのが起こるかもしれない。
変な例だとGoogleのインデックスがちゃんとされてなくて、検索に変な感じで表示されてましたとか、そういう可能性もなきにしもあらず。
なきにしもあらずかな。Googleは対応してくるんじゃないかなと思いつつ、正直やったことないのでわかんないですね。
あとはあれですかね、最近多い、それがBot判定されてるのかよくわかんないですけど、AI、LLMによる検索だったりとかも、もしかしたらジャンプラーとか。
そうですね、そのAIのクローラーとか正直どういう実装されてるかわかんないので、アリヒンツでぶっ壊れるとか全然あると思いますね。
それが原因で全然AIによる検索が引っかからなくて、なんかサイトに全然アクセスが来ないみたいなね、そういうのも。
たぶん今後あると思いますよ。
全然ありそうだなと思うので、ちょっと気をつけないといけないですね、ちゃんとここら辺。
なので、アリヒンツはHP2とHP3以外では基本返さないっていうのが重要だったりします。
めちゃくちゃ重要なとこですね。
そうですね。で、OSSの話をちょっとしておくと、エンジンXはアリヒンツディレクティブっていうのが1.29.0から追加されてます。
設定で書けるって感じですね。
ただ、これはさっき自分が話した件なんだけど、これね、自分はちょっと良くないと思っていて、
これはバックエンドが103を返したら、その103をクライアントに転送できるっていう機能なんですよ。
プロキシなんですかね。
プロキシ先、オリジンが103返してきたら103ちゃんと返せますよっていうのがこのエンジンXの機能。
それを逆に言えば、バックエンドが103を返したとしてもエンジンX側でアリヒンツディレクティブを設定してなかったら転送できないってことですね。
転送できないですね。アリヒンツディレクティブ設定してないと。
めちゃくちゃハマりどころなんですけど。
そうですね。しかもここで重要なのは、エンジンX自身が103を生成するんじゃなくて、
あくまでもオリジン側で103返してきたときに103返せるっていう機能なんですよ。
これさっき自分が言った内容と矛盾してて、103アリヒンツはエッジで返した方がいいですよって話したじゃないですか。
エンジンXで返したいですよね。
エンジンXで直接返さないと意味ないのにできないんですよ今のエンジンX。
なるほど。
アプリケーションが返さないといけないんですよ103。
ただ、エンジンXに103を生成する機能があったとして、どう機能させるのかなという難しさもあるんですけど、さっきのCDNと一緒で。
そうですね。それも後でちょっと話したいなと思ってたんですけど、要はどうデプロイしたらいいのかっていう話もあるし、
結局別システムが別なんで、デプロイしたときにどうしても食い違いが出ちゃうっていうのは避けようがないんですよ。
そうだから、アーリーヒンツを真面目に運用しようとしたらどうするのかっていうのはまだあんまり議論がされてないなと思ってて。
運用の歴がまだまだで、どうするのかっていうのが定まってないんですね。
そうですね。アーリーヒンツ試したら動いたよぐらいの人が多くて、実際に運用するっていうのがまだ情報として出てきてないなと思っているので、
個人的にちょっとその辺が不満というか、なんかその辺ちゃんと考えてる人少ないなと思っているので、ちょっと今回のこの会をやっているっていうのもあります。
なるほど。まだプロダクション環境でちゃんと使ってる人が全然多くないっていうこと?
そんな多くなくて、まだその最後の方に多分その辺も実際にデプロイした会社があるので、ちょっとその辺の事例を紹介したいなと思ってます。
すごい。じゃあちょっと次の話です。
ちょっとまだね、NGXでちょっと気をつけて欲しいところまだあって、
さっきHP1.1だったら対応してるって言ったんだけど、HP1.0は対応してないんですよ。103アーリーヒンツそもそも。
重要なところですね。
NGXってちょっと前までプロクシー先のHPバージョンが1.0になってたんですね、デフォルトが。
なのでここ1.1にしないといけなかったんですけど、ただ実はNGX1.29.7からデフォルトが1.1になったんですね。
多分今アーリーヒンツNGXで使いたいって人は、ステーブル版の1.30を使うと思うんですよ。
ステーブル版でアーリーヒンツ使えるようになったのは1.30が初めてなので、
なので1.30で使うんだったら、プロクシーのHPバージョンは1.1がデフォルトになっているので、あんまり気にしなくてもいいかなと思いつつ、
やっぱりちょっと前までデフォルト1.0だったので、1.1じゃないと使えないですよっていうのはちょっと意識して欲しいところですね。
NGXの1.30以降だったら別に設定を書き換える必要性はないんだけどってことですよね。
そうですね。そこはちょっと意識して欲しいところ。1.1じゃないと、103アーリーヒンツは返せない、そもそも対応してないよっていうところ。
逆に言えばNGXの設定でプロクシーHPバージョンを1.0に明示的にしている場合は使えないってことですもんね。
使えないです。
そこを書き換えないといけないってことですね。
そうですね。
NGX自身で103返せるようにならないのかって自分はずっと思っていて、実はGitHubのイシュー作ってる人はいたので、自分もちょっとコメントしてるんですが、特に動きは今のところないですね。
NGX側としてもどう運用しようかなっていうのは悩ましいところだと思うので。
まあちょっとこの辺り、自分はウォッチしてるんですけど、今後どうなるかってところですね。
ちなみにNGXについてはそのぐらいですかね。
そうですね。
ちなみにCDN、さっきの話で言ったCDN、GABAはどんな感じで対応してたりするんですかね。
そうですね。事例支店のファストリーだけなんで、ファストリーの話するんですけど、ファストリーってVCLっていうので設定いろいろ書けるんですけど、そこでEarly Hintsっていうのを使えばエッジから直接103を返せます。
あとさっき言ったHP2とHP3だけ返したいみたいなのも、VCLってif文とか普通に書けるので、その辺の設定を使えば普通に書けます。
なのでそのファストリーで使いたい、ファストリーのVCLで使いたい場合はVCLでEarly Hints書けばいいんですけど、ただやっぱり実際にやろうとすると、じゃあ何のファイルをEarly Hintsで返せばいいのかっていう問題が出てくるんですよね。
難しい。
ファストリーの場合は、例えばファストリーってEdge Dictionaryっていう機能があって、そのDictionaryを置けるんですよ。このキーに対してこの値みたいなのが置けて、それをAPI使えばその値書き換えられたりするんですね。
すごい単純な理解で言うと、リストを登録できるみたいな。
そんな感じです。
JSON的な。
登録できるみたいな感じですよ。
例えばそのEdge DictionaryでそのEarly Hintsで返したいCSSとかそういうのを登録しておいて、で例えばアプリケーションがデプロイしたときにそのEdge Dictionaryを更新するっていう風にやれば一応できる。一応動きはするはず。
できそう。
これもやっぱり問題はあって、これはファストリーの問題なんですけど、ファストリーのEdge Dictionaryって反映に1分ぐらいかかるんですよね。
一応公式だと30秒ぐらいって言ってるんですけど、自分の体感だと1分とか普通にかかるぐらいの体感、個人的には。
でファストリーの設定ファイルって基本的に1秒もかかんないんですよ。VCLの反映とかって一瞬で終わるんですけど、Edge Dictionaryは結構時間かかるんですよ反映に。
なるほど、そこの動機を取るのが難しいって問題があるんですね。
多分そうなんだと思うんですよね。あとやっぱりそのアプリケーションのデプロイとCDNって全く別のシステムなんで、同時に行うことは不可能なんですよね原理的に。
全く同時は無理ですね。
絶対無理で、そうなるとやっぱりデプロイ中にやっぱり必要ないCSSファイルとかEarly Hintsで返しちゃうはずなんですよね。
先に返してしまうみたいな問題が発生しますよね。
そのアプリケーションで動いているコードとそのCDNのEdgeで返しているコードが違う。
そうなるとどうなるかっていうと、別にブラウザ上でコンソール開くと実はエラーになるんですよ。
Early Hintsで返してるのにお前使ってねえじゃんみたいな感じで怒られるんですけど、
ただ逆に言うと怒られるだけ、そのコンソールで怒られるだけではあるんだけど、けどやっぱりユーザーは迷惑するんですよね。
必要ないファイルダウンロードさせられてるから。
ダウンロードしたけど使ってねえやんっていう警告が出るってことですね。
そうですね、ブラウザ上で出ますね。やっぱりでもそれはもう避けられない、この仕組みを使っちゃうと。
これはもうどうしようもないんだけど、やっぱりそういう問題はあるよっていうのは認識しておく必要がある。
最大1分とかあとはデプロイの仕方によってはもうちょっとだけエラーになる。
そもそもいきなりアプリケーションデプロイもいきなり全部一瞬でバーンって反映されるわけじゃないじゃないですか。
1台デプロイして、例えば500番とか返ってこなかったら他のやつもどんどんどんどんローリングアップデートしてみたいな感じになるじゃないですか、大抵の場合。
まあ。
そうなんでアプリケーションの反映もそんな一瞬で全部できるわけじゃないんですよ。
だからこれは絶対避けられない。
その1030ヒンツがその実際のアプリケーションと違うものを返しちゃうっていう問題はどうやってもあるんだよね。
そもそもデプロイの仕組み自体がそういうものだよね。
ウェブアプリケーションデプロイってそもそもそういうものだからこれに関してはもうどうしようもない。
ちなみに今聞いてて思ったのがREヒンツ何を返すか問題のところで全部返しちゃえばいいんじゃないかなと思ったんですけど。
その必要なリソースをですか。
必要なリソースというか別にそのindex.htmlで使わないものも全部REヒンツで返してしまえばいいんじゃないかなって若干思ったんですけど。
そしたらなんかいい感じに別に使わないものだったとしても無視されて使えるものだけダウンロードされるのかなと思ったんですけど。
今の話聞いたら全部ダウンロードされてしまうから無理なんですね。
REヒンツで返してしまうと。
そうですね全部ダウンロードしちゃうんで結局サーバープッシュと同じ問題が出てきちゃう。
必要ないリソースをユーザーに送りつけちゃうっていうのと同じ問題が出てきてしまう。
だから無理なんですね。
無理か無理じゃないかというと無理ではないんだけど。
そもそもREヒンツってユーザーのパフォーマンスを上げるためにやってるのでパフォーマンス逆に下げちゃったら使いみないじゃないですか。
だったらやらない方がいい楽しみになるので。
存在理由がないってことですね。
そう存在理由がないってところですね。
なるほど。じゃあ本当に送りつけるものは最小限であるべきっていうところがあってってことですね。
そうですね。じゃあその辺の話しますか。
実際にREヒンツを有効にした会社があってショッピファイとかあとファストリーとかの事例が出てるんだけど
ショッピファイが一番具体的かなと思っていて
ショッピファイによるとデスクトップ要はPC版だと改善があったけれども
モバイルスマートフォン版だとむしろ返した方が悪化しましたっていう話があって
その実例が。
あとREヒンツの数が重要だって言ってて
PC版とかでも4個以上返したらむしろパフォーマンス悪化しましたって言っていて
多分3個いないぐらいで本当に必要なやつ以外絶対に返すなっていうのがショッピファイの結論みたいなんですよ。
なるほど。これはあれなんですかね。
HTMLの生成までの間にダウンロードしきれるものの方がいいみたいなことなんですかね。
そうですね。やっぱりそのREヒンツ返すこと自体にボトルネックというかやっぱりパフォーマンスやっぱりリソース使っちゃうので
何でもかんでも返せば早くなるって感じじゃないし
あとやっぱり今言ってくれた通りそのHTMLが返ってきたらHTML解析して必要なリソース分かるんで
結局HTMLが返ってくるまでにダウンロード終わってるぐらいじゃないとあんまり意味がない。
あとやっぱりスマートフォンだとやっぱりCPUとかメモリも少なかったりとか
あとモバイル回線だとそもそも帯域が狭いので
そもそもこのファイル必要だからダウンロードしといてとか言われても
いやそんな帯域余裕ないんだけどみたいになったりとかもするし
だから意外とスマートフォンだと多分効果が薄い
で効果あるとするとPC版だし
あと返しすぎるアーリヒンツで欲張りすぎると多分むしろパフォーマンス下げちゃう
めちゃくちゃ難しいですよこれは
この辺もやっぱり実際にデプロイして計測したからわかったことではあるんだよね
これ最適な数は何なのかとか
ショッピファイの場合は例えば2つ3つが最適だっただとは思うんですけど
それはショッピファイのそのページだけであって
別のページとか別のサービスだったら全然違う数になってきますよねきっと
全然違くはならないと思うんだけど
ただやっぱり実際に計測してない
実際に計測してくださいっていうのがアーリヒンツの結論なんですよね
とりあえず返して満足するんじゃなくて
実際返して実際パフォーマンス上がったのかとか
そういうのもちゃんと計測してくださいっていうのが今のアーリヒンツの状況です
確かに単純に使っただけでは絶対に速くなるものではないよということですね
とりあえず使ったら速くなるっていう状況ではない
やっぱり効果が大きいと思うのは多分LCPが一番わかりやすいかなと思っていて
今のChromeってLighthouseっていうのでパフォーマンス測れるんですけど
いくつか項目あるんだけどそのLCPっていうのは
一番最初のファーストビューでその一番目立つコンテンツ
例えば画像が大きい画像がボーンってあったらその画像とか
あと文章が目立つんだったらその文章とか
それその主要なコンテンツが表示されるまでの時間
これってやっぱりその一番目立つコンテンツがバーンって出るとユーザー動いたなって思うんで
その一番目立つコンテンツが出るまでの時間っていうのは
すごいそのユーザーの体感のパフォーマンスに大きく影響するんですよ
なのであの今LCPは結構重要視されている指標なんだけど
このLCPで例えばCSS
LCPってやっぱりそのCSSとかあと画像だったら画像とか
そういうのをいかに早くダウンロードさせて表示するかの勝負なので
結構そのアーリーヒントで改善させられるというか改善を狙うべきなのは
このLCPが一番分かりやすいかなと個人的には思ってます
ちなみにLCPって何ですか
ライトハウスで見れる
ライトハウスで見れる
項目の一つ
項目の一つがLCPというものがあってということなんですね
そうですね
なのでそのだいたい今のウェブのフロントエンドのパフォーマンスだと
だいたいライトハウスで早くなったかとか見ると思うので
多分アーリーヒントで狙うのはLCPかなと個人的には思ってますね
じゃあアーリーヒントを導入して
してLCPのスコアを上げられないかというのを試行錯誤する
で最適なラインを探すっていうのが一番分かりやすいんじゃないかなと思ってます
このページだったらこのぐらいで
このサービスだったらこのぐらいアーリーヒント返したほうが
一番スコア出やすいなみたいなのを計測していくっていう
そうですね
やっぱりその実環境で計測した方が良くて
手元で何回かやるとかじゃなくて
実際にユーザーの環境で
LCPがちゃんと改善してるのかっていうのを見たほうがいいかなと思ってます
ただ開発環境とかで確認するんじゃなくて
実際にプロダクション環境で計測する
ただあれですよね
ライトハウスとかの場合って自分でアクセスして
開発者が見るみたいな感じだと思うんですけど
ユーザーのログとかから分かったりしないんですかね
実際に具体的にやり方は自分もあまり知らないんだけど
その辺のパフォーマンス計測するっていうのは結構一般的にやられている
そういうサービスもあるし
あとクラックスって言うんだっけな
Googleが取ってるんですよ実は
そういうメトリックス持ってるんですね
Google側が持ってて我々も見ることができます
なのでそういうのを見てちゃんと
そういうのってSEOに直結したりもするので
そういうのがちゃんと改善しているのかとか
そういうのは見たほうが良い
なんかNew Relicとかそういうのを入れて
ちゃんと計測してどんぐらい早くなってるのか
遅くなったのかとかちゃんと見てみるっていうのが重要だよね
そうですねNew Relicにそういう機能あったと思うので
そういうのは結構仕組みとしては世の中にあるものになりますね
じゃあそういうのを使って本当にマジで計測せよってことですね
そう特にEarly Hintsは返したら早いでしょっていう感じでいくと
全然ダメかもしれない
欲張りすぎると遅くなるっていうのがなかなか難しいし
しかもモバイルだと使ってるだけで悪化するっていうのはちょっと厳しいですね
ショッピファイの事例だとモバイルスマートフォンだと特に改善できなかったっていうところなので
本当に本当に使うべきなのかってところからやっぱりちゃんと計測すべきかなとは思ってます
銀の弾丸ではないよっていうところでEarly Hintsがね
ただ個人的にEarly Hints面白いというか
最初に言ったサーバープッシュってコネクションを使い回してるんで
同じドメインから送るしかなかったんですよ
要はCSSとかJavaScriptを同じドメインで送るしかなかったんですけど
Early Hintsは別にこのリソース使うよって言ってるだけだから別のドメインでもいいんですよ
そのリンクのURLを変えればいいだけ
なので実際に自分の環境でも試して動くことを確認したので
それでも全然動くんですよ
CSSとかJavaScriptを別のドメインで配信してるサービスって結構あると思うんで
やっぱりそういうサービスでもEarly Hintsは使えるっていうのは
一応面白いというか強力な部分かなと思ってたりします
そこがサーバープッシュとの大きな違いかなと思ってますね
確かにサーバープッシュの場合だとバイナリを送り付けているので
そのサーバー自体がホストにならざるを得ない
ってことですよね
Early Hintsの場合はクライアントがダウンロードするのであくまでも
だから問題ないよね
そうドメインは何でもいいよねっていうところ
頭いいっすねこう考えると
そうなんで結構使いやすくはあるんですよEarly Hints
既存の仕組みにも入れやすいと思います
実際かたついさんの自宅サーバーというかVPSの上では
Early Hintsも動いてるんですか?
実は動いてます
たださっきも言った通りEngineX単体だと動かせないんで
Goの簡単なアプリケーションコードを書いてやってるんですけど
ただちょっとGoも結構特殊で
今のGoは103 Early Hints対応してるんですけど
これすごい変なコードになっていて
さっき言った通り103の時点で
HBボディが空のヘッダーだけのレスポンス返して
けど200番をその後返さないといけないって話をしたじゃないですか
だから並列で返さないといけないんですよね
並列ではなくてGoの場合はすごい変なコードになっていて
103をステータスコードとして設定した瞬間に
それまでに書き込んだヘッダーを
全部ユーザー側に送り返すようになってるんですよ
だからステータスコードを設定しただけなのに
HTTPのレスポンスを返されるっていう
直感に反する挙動をするんだよね
気持ち悪いですね
すごい気持ち悪くて
実際にGoの標準パッケージのコード内でも
確か100番台だったかな
100番台だったらこういう変な挙動をするみたいなコードが書かれてて
すごい気持ち悪いコードなんですよ
なんかGo2みたいな感じですね
これを書いたら絶対に外部のところに行くみたいな
そんな挙動をしてますよね
コード的にはステータスコードを103で設定しただけなのに
実はそういう変な挙動
変なソースコード動いてるので実際に
そこは結構気をつけた方がいいというか
やっぱ多分Goは標準パッケージもGoのコードなので
標準パッケージのコードを読んでから使った方がいいと個人的には思ってます
いや分かりづらいっすねそれは
だって別にリターンされるわけでもないですもんね
ステータスコード
パッと見103設定してるだけなんだけど
実際にはそういうコードが動いてる
副作用がバリバリあるってことですね
そうめっちゃ副作用ある
気持ち悪い
結構知らないと気持ち悪いですめちゃくちゃ
でも他のフレームワークとか言語とかが
どうやって対応してるのかっていうのはちょっと見てみると面白そうですね
103の対応は
そうですね自分ちょっとGoしか使ってないので
Go以外分からないんですけど
すごい変なことしないといけないだろうなと思うんですよね
そうですね多分変なことしないとそもそも動かないと思いますね
なんでGoはそういう気持ち悪いことやってます
なので自分のサクラの
自分のサクラのVPSだと
そのGoで103ありヒントを返すだけの
すごいシンプルなサーバーを動かして
そこでNginxを経由して103返すっていう実装を動かしてます
気持ち悪いコードを動かしてるってことですね
そうですね
これ聞いてる人の中でも
他の言語とかで103どうやって動かせられるのかなみたいな
ちょっと調べてみてほしいですねぜひ
そうですね自分もGoしか使ったことないので
ぜひそういう情報をみんなも出してくれたら嬉しいなと思ってます
Xとかあとコメントとかでいただければ見るので
ぜひよろしくお願いします