JamstackプラットフォームのLayer0へNext.jsのアプリをデプロイしながら試す
Layer0というJamstackプラットフォームを試してみた記事です。 Jamstackプラットフォームが何かは表現しにくいですが、Netlify、Vercel、Cloudflare PagesみたいなSPAなアプリケーションとかをホスティングしてくれるサービスです。
Layer0はMoovweb XDNという名前のプロダクトでしたが、2021年4月にLayer0へリブランディングしています。
Layer0は、Netlify、Vercel、Cloudflare PagesのようにSPAアプリケーションをホスティングできるプラットフォームです。 他のプラットフォームと同じようにブランチでのプレビュー環境、A/B テスト、Lambdaを使ったserverlessなAPIを作れて、Web Vitalのメトリクスを使ったパフォーマンスモニタリングをサポートしています。 また、FastlyベースのCDN上にJavaScriptでルーティングやCookie操作などのプロキシ処理をかけるEdgeJSという仕組みをもっています。
軽く触ってみた感触では、次のようなVercel等とCloudflare Workersの中間ぐらいの印象を受けました。
My first impression of Layer0( https://t.co/bXXYp5eTYK )
— azu (@azu_re) April 24, 2021
/w Vercel/Netlify/Cloudflare Workers pic.twitter.com/Sd1RDyq0YY
Netlify、Vercel、Cloudflare Pages(Pagesの実体はWorkersなので少し特殊)はSPAのアプリケーションを簡単にデプロイできる方向に寄っている感じがします。そこへServerlessなFunction対応やISRなどで色々な用途に対応していく感じのイメージです。
一方で、Cloudflare WorkersはスタートがCDNで、CDN上でJavaScriptのアプリケーションが動かせるので自由度がものすごく高いです。 しかし、既存のNode.jsのエコシステムは使いにくいため作り込みが必要だったり、用途が限定的になりやすいです。 Cloudflare Workersについては次の記事でも書いています。また、CloudflareもNode.js support in Cloudflare Workersという記事(これはwebpackでbundleするのでpure jsなnpmモジュールは動くよという話)を書いたりしているので、この辺のエコシステムの問題は認識している感じがします。
最近でたDeno DeployもCloudflare Workersと似た系統のEdgeで動くサービスです。次のスライドでも比較しています。
Layer0は、NetlifyやVercelが持っている基本的な機能はサポートしている感じです。
- GitHub連携でのデプロイ
- StagingやProductionのような複数の環境
- NetlifyのA/Bテストと同じSplit Testing
- Next.jsのISR、他のフレームワークでもISR対応
- Web Vitalsを使ったRUM
layer0 dev
でのローカルデバッグ- このコマンドの面白いところは
--cache
でキャッシュもローカルで試せる
- このコマンドの面白いところは
- React(Next.js)、Vue(Nuxt.js)、Angularなどの各種フレームワーク対応
- 後述するCDNレイヤーのルーティングやService Worker連携のためのアダプターが用意されている
また、Cloudflare Workersと似た形で、FastlyベースのCDN上でCookie操作/キャッシュ操作/Proxy処理といった簡単なロジックをJavaScriptでかけるようになっています。
このルーティング処理(route.ts
)が特徴的で、Cloudflare Workersほどの自由度はありませんが、リクエストとレスポンスに対する処理をJavaScriptで書けます。
そのため、FastlyのVCLのようなロジックがJavaScriptで書けます。
// https://docs.layer0.co/guides/routing#section_route_execution のサンプル
const { Router } = require('@layer0/core/router')
const { nextRoutes } = require('@layer0/next')
// In this example a request to /products/1 will be cached by the first route, then served by the `nextRoutes` middleware
module.exports = new Router()
.get('/products/:id', ({ cache }) => {
cache({
edge: { maxAgeSeconds: 60 * 60, staleWhileRevalidateSeconds: 60 * 60 },
})
})
.use(nextRoutes)
📝 Layer0の裏側がFastlyだとドキュメントで明言はされてないですが、
dig
、エラー時にFastlyが見えること、Sub-Processors、Fastly Partnerなどからそうだと判断しています。
たとえば、NetlifyやVercelなどではベーシック認証をかけるには有料プランやFunctionsを使う必要があります。
一方で、Layer0はRoutingレイヤーとしてCDN上でちょっとしたスクリプトが動くので、次のコードをroute.ts
へ追加するだけでベーシック認証を追加できます。
(Cloudflare Workersもこの辺が完全にJavaScriptのコードとして表現できるので、自由にかけられます)
const { Router } = require('@layer0/core/router');
const { nextRoutes } = require('@layer0/next');
module.exports = new Router().requireBasicAuth({
username: process.env.BASIC_AUTH_USERNAME,
password: process.env.BASIC_AUTH_PASSWORD,
})
.use(nextRoutes);
📝 このルーティングがどのように実行されているかは調べてませんが、webpackでbundleしていてNode.jsのモジュール自体は動かないようでした。 そのためCloudflare WorkersのようなPure JSに近いものを動かしている or DSLとしてJSを使っているのだと思います。
その他には、Service Workerと連携したPrefetchingのサポートが厚めに入っていたり、それをデバッグするDevtoolsなんかも面白い感じです。
あとは、最近のJamstackでは巨大なサイトだとビルド時間が問題となるため、Incremental Static Regeneration(ISR)やDistributed Persistent Rendering(DPR)などがありますが、Layer0はISRとPrerenderingに対応しています。
次の動画でもこの辺のビルドのスケールについて話しています。
📝 もともと、JamstackのDistributed Persistent Rendering (DPR) · Discussion #549 · jamstack/jamstack.orgの議論で、Layer0の人が出てきたので、そこを起点に調べてはじめました
簡単なアプリケーションをLayer0にデプロイする
JSer.infoのアーカイブデータを全文検索するシンプルなアプリケーションをLayer0で動かしてみました。
Next.jsとNext.jsのAPIを使ってシンプルに巨大なJSONをインメモリ検索するアプリケーションです。 初期表示はSSRで30コのアイテムを描画して、入力するごとにAPIを叩いてマッチするアイテムを描画するだけです。
https://t.co/TYYYLueDuq
— azu (@azu_re) April 24, 2021
Layer0 + Next.jsで https://t.co/CXy3hOXJ8q のアーカイブデータを全文検索するサービス作った。
コードは何も工夫してないやつだけど、この速度で動くの面白いなーhttps://t.co/MPPFp6ildj pic.twitter.com/5JlpmC0at0
殆どそのままな感じのアプリケーションですが、Documentは30ms-50msぐらいで返ってきます。 検索するAPIは十数MBのJSONからインメモリ検索する単純なやつですが、ローカルだと10m-30msぐらいで返るのが、Layer0だと300-400msぐらいで返ってきます。
また、管理画面でキャッシュのHit Rateが見れたりするのが、Fastly Partnerだなーって感じがして面白いです。
今回は特になにもしてないですが、Service Workerでのキャッシュとプリフェッチの組み込みとか、CDNキャッシュを手動で削除したり、デプロイごとのCDNキャッシュを維持できたり(デフォルトは消える)と結構細かいことができるが面白いところです。 この辺はNetlifyやVercelよりも、CloudflareなどのCDNよりな感じな気がします。
導入方法
最近リブランディングしたからかちょこちょこ動かないところがあったりするので、 この記事で書いてもすぐ古くなりそうなので、導入方法は公式ページを参照してください。
基本的にはNext.jsのアプリケーションを作って、layer0 init
をするとフレームワークなどを判定していい感じにlayer0.config.js
とroutes.ts
を作成してくれます。
npm i -g @layer0/cli
layer0 init
📝 Next.jsのアプリの場合は
layer0.config.js
でroutes
とconnector
に@layer0/next
を設定されているかを確認する。(試したときはinit
だと壊れててnpm create layer0-app
の方を参考にした)
あとは layer0 deploy
するだけで動きます。
layer0 deploy
GitHub連携は、GitHub Ationsからlayer0 deploy
相当のことをやっているだけです。
(この辺はGitHub Appとかが今後できたりするのかもしれないです。)
- https://github.com/jser/jser.info/blob/gh-pages/.github/workflows/layer0.yaml
- Layer0 Documentation - Deploying
ローカルでデバッグするときは、layer0 dev
コマンドを叩くとLayer0のRoute.ts
ベースのプロキシサーバとNext.jsのアプリが立ち上がって、
プロキシサーバの方にアクセスするだけです。(キャッシュとか関係ないならNext.jsのアプリを直接見ても問題なさそう)
layer0 dev
serverless(pages/api
)の方は、何もしなくても動いたので、特に調べてません。
おわりに
Layer0を簡単に試したので、その感想を書いてみました。
まだドキュメントや知見などが少ないため、NetlifyやVercelと同じレベルの簡単さではないですが、機能的には遜色ないと思います。
また、NetlifyやVercelでは手が届かない部分/Cloudflare Workersでは手を入れないと使いにくい部分が、Routingという形である種ユースケースを決めた形で使えるのがちょうどよい感覚です。
この辺のサービスは最近競争が盛んなので、何かベストなのかは難しいですが、試してみると面白いサービスだと思いました。
(2021-04-26時点) 料金プランはCommunity($0)/Hyper($500)/Enterpriseの3段階で、ドメイン数以外はCommunityでも十分使えそうな感じがします。 もともと大規模なコマースサイトにフォーカスしていたみたいなので、こういうプランなんだと思います。
Open Source Projects向けのプランもあるみたいので、もっと使う場合は聞いてみると良いかもしれません。
お知らせ欄
JavaScript Primerの書籍版がAmazonで購入できます。
JavaScriptに関する最新情報は週一でJSer.infoを更新しています。
GitHub Sponsorsでの支援を募集しています。