Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Next.js×Prisma×GraphQL×Supabase +WASMでブログを自作した話
Search
yud0uhu
September 12, 2023
Technology
0
1.2k
Next.js×Prisma×GraphQL×Supabase +WASMでブログを自作した話
Think ! FrontEnd by DMM #5 の登壇資料です。
https://dmm.connpass.com/event/291641/
yud0uhu
September 12, 2023
Tweet
Share
More Decks by yud0uhu
See All by yud0uhu
Webブラウザ向け動画配信プレイヤーの 大規模リプレイスから得た知見と学び
yud0uhu
0
120
早朝の渋谷の青さ、あるいは溺れた人を助ける為に飛び込んだ海の向こう側に見る、自己覚知と自己開示の尊さ
yud0uhu
1
590
動画配信サービスのフロントエンド実装に学ぶ設計原則
yud0uhu
1
320
非デザイナーのフロントエンドエンジニアがOOUIを考える
yud0uhu
9
5.5k
2023年の ゼロランタイムCSS in JS⚡️ を考える
yud0uhu
5
4.8k
Vue3/Electronで自作したマークダウンエディタをVue3/Tauriにリプレイスした話
yud0uhu
2
2.8k
入社半年を迎える新米エンジニアがカンファレンス・勉強会から得た学び
yud0uhu
0
1k
Rustでつくって学ぶProtocol Buffers
yud0uhu
1
180
ブログを自作した話
yud0uhu
1
28
Other Decks in Technology
See All in Technology
Kubernetes における cgroup driver のしくみ: runwasi の bugfix より
z63d
2
110
生成AI時代のデータ基盤
shibuiwilliam
4
2k
生成AI時代のデータ基盤設計〜ペースレイヤリングで実現する高速開発と持続性〜 / Levtech Meetup_Session_2
sansan_randd
1
110
まだ間に合う! StrandsとBedrock AgentCoreでAIエージェント構築に入門しよう
minorun365
PRO
11
710
個人CLAUDE.md紹介と設定から学んだこと/introduce-my-claude-md
shibayu36
0
160
「魔法少女まどか☆マギカ Magia Exedra」の必殺技演出を徹底解剖! -キャラクターの魅力を最大限にファンに届けるためのこだわり-
gree_tech
PRO
0
430
サンドボックス技術でAI利活用を促進する
koh_naga
0
150
新規案件の立ち上げ専門チームから見たAI駆動開発の始め方
shuyakinjo
0
640
DDD集約とサービスコンテキスト境界との関係性
pandayumi
2
210
「魔法少女まどか☆マギカ Magia Exedra」のグローバル展開を支える、開発チームと翻訳チームの「意識しない協創」を実現するローカライズシステム
gree_tech
PRO
0
430
Vault meets Kubernetes
mochizuki875
0
150
オブザーバビリティが広げる AIOps の世界 / The World of AIOps Expanded by Observability
aoto
PRO
0
250
Featured
See All Featured
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.4k
Fireside Chat
paigeccino
39
3.6k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
29
1.9k
How to train your dragon (web standard)
notwaldorf
96
6.2k
YesSQL, Process and Tooling at Scale
rocio
173
14k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.4k
Writing Fast Ruby
sferik
628
62k
Designing for humans not robots
tammielis
253
25k
Scaling GitHub
holman
463
140k
Rails Girls Zürich Keynote
gr2m
95
14k
Practical Orchestrator
shlominoach
190
11k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
51
5.6k
Transcript
Next.js×Prisma×GraphQL×Supabase (+WASM)でブログを⾃作した話 ⼤坂 友
© DMM 自己紹介 • 大坂 友 • 2023年4月新卒入社 • 所属:動画配信開発部プレミアムグループブラウザチーム
• 出身:北海道 • 趣味:映画鑑賞・旅行・アニメ・趣味開発 etc 2
© DMM 今日お話すること・しないこと お話すること • なぜ自作したのか • 使用技術の紹介 ⭕フロントエンド、BFF、WASM ❌マークダウンパーサーの仕組みについて
3
© DMM 作ったもの 4
© DMM ブログの機能〜inspired Zenn〜 5 できること ⭕キーワード検索 ⭕タグ検索 ⭕記事の投稿 ⭕GitHubログイン(自分のみ)
⭕記事の削除 ⭕ダークモード できないこと ❌アイキャッチの設定 ❌記事の公開予約 ❌画像のアップロード
© DMM 6 つくったもの yud0uhu.work
© DMM 使用技術 7
© DMM 使用技術 8 JSフレームワーク / 言語 Next.js / Type
Script 状態管理ライブラリ Apollo Client CSSライブラリ styled-components emotion mantine DB Supabase / Vercel postgress デプロイ先 Vercel 認証・認可 NextAuth ドメイン取得 Cloudflare Registrar
© DMM なぜ自作したのか? 9 車輪の再開発が好き • フレームワークは中身がブラックボックスになりがち • 自作すれば、仕組みを理解しながらものづくりができる •
自作はロマンがある • Rustでマークダウンパーサーを自作して、 WASM+Nuxt3+Viteで動かしてみた • Rustで作るリアルタイムOS
© DMM ライブラリ選定について 10 コードファースト • 言語固有のコードで SDL(schema.prisma)を書いて、 スキーマ定義ファイル (graphql.schema)を生成する方
法 スキーマファースト • スキーマ定義ファイル (graphql.schema)から SDL(schema.prisma)を生成す る方法
© DMM ライブラリ選定について 11 コードファースト • 言語固有のコードで SDL(schema.prisma)を書いて、 スキーマ定義ファイル (graphql.schema)を生成する方
法 スキーマファースト • スキーマ定義ファイル (graphql.schema)から SDL(schema.prisma)を生成す る方法
© DMM GraphQLのN+1問題 12 • サーバ実装で発生しがちなパフォーマンス上の課題 • GraphQLの強みは、クライアントが必要なデータのみをリクエスト し、一度に取得できること •
この特性が原因で、N+1問題が発生する
© DMM GraphQLのN+1問題 13 以下のようなスキーマについて考える
© DMM GraphQLのN+1問題 14 以下のようなスキーマについて考える
© DMM GraphQLのN+1問題 15 以下のようなSQLクエリが発行される
© DMM GraphQLのN+1問題 16 • 1回のリクエストで、全ての作者を取得するクエリ(authors)が実 行される(1回のリクエスト) • 各作者ごとに、その作者が投稿した記事を取得するために個別のク エリpostsが発行される(5回のリクエスト)
計6回のリクエストが行われる(N+1)
© DMM GraphQLのN+1問題 17 • スケジューラでクエリのバッチ処理を効率化する • キャッシュを活用してデータの再取得を最小限にする • N+1問題を考慮したORMを用いて解決する
etc
© DMM GraphQLのN+1問題 18 • スケジューラでクエリのバッチ処理を効率化する • キャッシュを活用してデータの再取得を最小限にする • N+1問題を考慮したORMを用いて解決する
etc
© DMM Prismaについて 19 • Graphqlと高い親和性を持つORM
© DMM Prismaについて 20 • Prismaでは、モデル間のリレーションシップを簡単に定義できる仕 組みが提供されている • Nested reads
• Eager Loading • 一度のクエリで、全ての作者とそれぞれの作者が投稿した記事の情 報を取得できる • リレーションのネスト構造が深すぎたり、大量のバッチ処理が必要 となった場合は、N+1問題を完全に解決することが難しい
© DMM Pothos(ポトス)について 21 • コードファーストにGraphQLサーバーの開発を行うためのライブラ リ • 元の名前はGiraphQL •
視認性・検索性の問題から改名された • Prismaと互換性があり、N+1問題の対策を強化することができる
© DMM supabaseについて 22 • Firebase代替として注目されているOSSのBaaS • 以下の機能を提供している • Database
• PostgreSQLベースのRDB • Authentication • Storage • Edge Functions
© DMM supabaseについて 23 • Free Plan(従量課金なし) • APIリクエストは無制限 •
500MBまでのデータベース、1GBのファイルストレージが利用 可能 • 最大5GBの帯域幅 • 月間アクティブユーザーは最大50,000人まで • 同時リアルタイム接続の上限は200 • リアルタイムメッセージの上限は最大2,000,000件 • 7日間未利用の場合、サーバの一時停止 • 作成できるプロジェクト数は2つまで
© DMM supabaseについて 24 • Vercel Postgres(hobbby plan)との比較 supabse free
plan vercel postgres 1ヶ月のAPIリクエスト数 無制限 30,000 1ヶ月のストレージ容量 1GB 256 MB 1ヶ月のデータ転送量 5GB 256 MB 作成できるデータベース数 1 2
© DMM supabaseについて 25 schema.prisma Schema Visualizer
© DMM prisma+supabase所見 26 • 一つの共通言語(SDL)からGraphQLのスキーマ・DBのテーブルが 一気に生成できて、ER図のビジュアル化ができるため開発体験が良 かった • NoSQLのFirerestoreに対して、supabaseはPostgreSQLベースな
のがうれしい • supabaseはFree planでも、個人開発の素振りに使う分にはほどよ い
© DMM WASMをVercelでビルドする 27 • ビルドツールはwasm-pack を採用 • 静的アセットを生成するバンドラー •
RustのコードからTypeScriptの型定義コードまでを吐き出 してくれる • 内部でwasm-bindgenを利用して、JavaScriptからRust APIを 呼び出すことができる
© DMM WASMをVercelでビルドする 28 WASMとPrismaのビルドの設定を行う手順 1. npx prisma generateを行うビルドスクリプトを書く 2.
vercel.jsonでそれを実行するように設定する
© DMM WASMをVercelでビルドする 29 WASMとPrismaのビルドの設定を行う手順 1. npx prisma generateを行うビルドスクリプトを書く 2.
vercel.jsonでそれを実行するように設定する
© DMM WASMをVercelでビルドする 30 3. Vercelでビルドする
© DMM Appendix 31
© DMM アクセシビリティ対策 32 • Next.jsのHTMLタグに動的にlangを設定する
© DMM アクセシビリティ対策 33 • Next.jsのpagesコンポーネントは、デフォルトで<head>タグと <body>タグを定義してくれる • そのため、_document.jsを作成し、デフォルトのDocumentをオー バーライドしてカスタマイズする
© DMM アクセシビリティ対策 34 • 今回はEmotionとstyled-componentsを使用しているため、以下の ドキュメントを参考にrenderPageのカスタマイズを行う • Routing: Custom
Document | Next.js
© DMM アクセシビリティ対策 35 スコアが改善された🎉
© DMM ハイドレーションエラー対策 36
© DMM ハイドレーションエラー対策 37 ハイドレーションエラーはなぜ起こるのか • サーバーから事前にレンダリングされたReactツリーと、ブラウ ザーでの最初のレンダリング (Hydration/ハイドレーション) 中に
レンダリングされたReactツリーの間に違いが生じたため • 今回のケースだと、classNameの不一致 参考記事 • hydrateRoot – React
© DMM ハイドレーションエラー対策 38 ハイドレーションとは • サーバから受け取った「乾いたHTML」に、クライアントサイドの インタラクティブな機能を注ぎ込むこと ハイドレーションエラーとは •
「サーバから受け取った初期HTML」と「クライアントサイドJSが 予期するHTML」が一致しない場合に起こるエラー 参考記事 • 7歳娘「パパ、ReactのHydration Errorってなんで起こるの?」 - Qiita
© DMM ハイドレーションエラー対策 39 対策:Pre-rendering and Data Fetching | Learn
Next.js を参考に、 フックを使用してレンダリングのタイミングを意図的に制御
© DMM 40 まとめ 今後やりたいこと • LightHouseのスコア改善 • アプローチ→FirebaseやGoogle Analytics、New
Relicなどで モニタリング&改善の試作 • 目標→スコアオール100点 • 機能拡張 • プロフィールページの作成など
© DMM ご静聴ありがとうございました🎉