Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
Next.js×Prisma×GraphQL×Supabase (+WASM)でブログを⾃作した話 ⼤坂 友
Slide 2
Slide 2 text
© DMM 自己紹介 • 大坂 友 • 2023年4月新卒入社 • 所属:動画配信開発部プレミアムグループブラウザチーム • 出身:北海道 • 趣味:映画鑑賞・旅行・アニメ・趣味開発 etc 2
Slide 3
Slide 3 text
© DMM 今日お話すること・しないこと お話すること • なぜ自作したのか • 使用技術の紹介 ⭕フロントエンド、BFF、WASM ❌マークダウンパーサーの仕組みについて 3
Slide 4
Slide 4 text
© DMM 作ったもの 4
Slide 5
Slide 5 text
© DMM ブログの機能〜inspired Zenn〜 5 できること ⭕キーワード検索 ⭕タグ検索 ⭕記事の投稿 ⭕GitHubログイン(自分のみ) ⭕記事の削除 ⭕ダークモード できないこと ❌アイキャッチの設定 ❌記事の公開予約 ❌画像のアップロード
Slide 6
Slide 6 text
© DMM 6 つくったもの yud0uhu.work
Slide 7
Slide 7 text
© DMM 使用技術 7
Slide 8
Slide 8 text
© DMM 使用技術 8 JSフレームワーク / 言語 Next.js / Type Script 状態管理ライブラリ Apollo Client CSSライブラリ styled-components emotion mantine DB Supabase / Vercel postgress デプロイ先 Vercel 認証・認可 NextAuth ドメイン取得 Cloudflare Registrar
Slide 9
Slide 9 text
© DMM なぜ自作したのか? 9 車輪の再開発が好き • フレームワークは中身がブラックボックスになりがち • 自作すれば、仕組みを理解しながらものづくりができる • 自作はロマンがある • Rustでマークダウンパーサーを自作して、 WASM+Nuxt3+Viteで動かしてみた • Rustで作るリアルタイムOS
Slide 10
Slide 10 text
© DMM ライブラリ選定について 10 コードファースト • 言語固有のコードで SDL(schema.prisma)を書いて、 スキーマ定義ファイル (graphql.schema)を生成する方 法 スキーマファースト • スキーマ定義ファイル (graphql.schema)から SDL(schema.prisma)を生成す る方法
Slide 11
Slide 11 text
© DMM ライブラリ選定について 11 コードファースト • 言語固有のコードで SDL(schema.prisma)を書いて、 スキーマ定義ファイル (graphql.schema)を生成する方 法 スキーマファースト • スキーマ定義ファイル (graphql.schema)から SDL(schema.prisma)を生成す る方法
Slide 12
Slide 12 text
© DMM GraphQLのN+1問題 12 • サーバ実装で発生しがちなパフォーマンス上の課題 • GraphQLの強みは、クライアントが必要なデータのみをリクエスト し、一度に取得できること • この特性が原因で、N+1問題が発生する
Slide 13
Slide 13 text
© DMM GraphQLのN+1問題 13 以下のようなスキーマについて考える
Slide 14
Slide 14 text
© DMM GraphQLのN+1問題 14 以下のようなスキーマについて考える
Slide 15
Slide 15 text
© DMM GraphQLのN+1問題 15 以下のようなSQLクエリが発行される
Slide 16
Slide 16 text
© DMM GraphQLのN+1問題 16 • 1回のリクエストで、全ての作者を取得するクエリ(authors)が実 行される(1回のリクエスト) • 各作者ごとに、その作者が投稿した記事を取得するために個別のク エリpostsが発行される(5回のリクエスト) 計6回のリクエストが行われる(N+1)
Slide 17
Slide 17 text
© DMM GraphQLのN+1問題 17 • スケジューラでクエリのバッチ処理を効率化する • キャッシュを活用してデータの再取得を最小限にする • N+1問題を考慮したORMを用いて解決する etc
Slide 18
Slide 18 text
© DMM GraphQLのN+1問題 18 • スケジューラでクエリのバッチ処理を効率化する • キャッシュを活用してデータの再取得を最小限にする • N+1問題を考慮したORMを用いて解決する etc
Slide 19
Slide 19 text
© DMM Prismaについて 19 • Graphqlと高い親和性を持つORM
Slide 20
Slide 20 text
© DMM Prismaについて 20 • Prismaでは、モデル間のリレーションシップを簡単に定義できる仕 組みが提供されている • Nested reads • Eager Loading • 一度のクエリで、全ての作者とそれぞれの作者が投稿した記事の情 報を取得できる • リレーションのネスト構造が深すぎたり、大量のバッチ処理が必要 となった場合は、N+1問題を完全に解決することが難しい
Slide 21
Slide 21 text
© DMM Pothos(ポトス)について 21 • コードファーストにGraphQLサーバーの開発を行うためのライブラ リ • 元の名前はGiraphQL • 視認性・検索性の問題から改名された • Prismaと互換性があり、N+1問題の対策を強化することができる
Slide 22
Slide 22 text
© DMM supabaseについて 22 • Firebase代替として注目されているOSSのBaaS • 以下の機能を提供している • Database • PostgreSQLベースのRDB • Authentication • Storage • Edge Functions
Slide 23
Slide 23 text
© DMM supabaseについて 23 • Free Plan(従量課金なし) • APIリクエストは無制限 • 500MBまでのデータベース、1GBのファイルストレージが利用 可能 • 最大5GBの帯域幅 • 月間アクティブユーザーは最大50,000人まで • 同時リアルタイム接続の上限は200 • リアルタイムメッセージの上限は最大2,000,000件 • 7日間未利用の場合、サーバの一時停止 • 作成できるプロジェクト数は2つまで
Slide 24
Slide 24 text
© 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
Slide 25
Slide 25 text
© DMM supabaseについて 25 schema.prisma Schema Visualizer
Slide 26
Slide 26 text
© DMM prisma+supabase所見 26 • 一つの共通言語(SDL)からGraphQLのスキーマ・DBのテーブルが 一気に生成できて、ER図のビジュアル化ができるため開発体験が良 かった • NoSQLのFirerestoreに対して、supabaseはPostgreSQLベースな のがうれしい • supabaseはFree planでも、個人開発の素振りに使う分にはほどよ い
Slide 27
Slide 27 text
© DMM WASMをVercelでビルドする 27 • ビルドツールはwasm-pack を採用 • 静的アセットを生成するバンドラー • RustのコードからTypeScriptの型定義コードまでを吐き出 してくれる • 内部でwasm-bindgenを利用して、JavaScriptからRust APIを 呼び出すことができる
Slide 28
Slide 28 text
© DMM WASMをVercelでビルドする 28 WASMとPrismaのビルドの設定を行う手順 1. npx prisma generateを行うビルドスクリプトを書く 2. vercel.jsonでそれを実行するように設定する
Slide 29
Slide 29 text
© DMM WASMをVercelでビルドする 29 WASMとPrismaのビルドの設定を行う手順 1. npx prisma generateを行うビルドスクリプトを書く 2. vercel.jsonでそれを実行するように設定する
Slide 30
Slide 30 text
© DMM WASMをVercelでビルドする 30 3. Vercelでビルドする
Slide 31
Slide 31 text
© DMM Appendix 31
Slide 32
Slide 32 text
© DMM アクセシビリティ対策 32 • Next.jsのHTMLタグに動的にlangを設定する
Slide 33
Slide 33 text
© DMM アクセシビリティ対策 33 • Next.jsのpagesコンポーネントは、デフォルトでタグと タグを定義してくれる • そのため、_document.jsを作成し、デフォルトのDocumentをオー バーライドしてカスタマイズする
Slide 34
Slide 34 text
© DMM アクセシビリティ対策 34 • 今回はEmotionとstyled-componentsを使用しているため、以下の ドキュメントを参考にrenderPageのカスタマイズを行う • Routing: Custom Document | Next.js
Slide 35
Slide 35 text
© DMM アクセシビリティ対策 35 スコアが改善された🎉
Slide 36
Slide 36 text
© DMM ハイドレーションエラー対策 36
Slide 37
Slide 37 text
© DMM ハイドレーションエラー対策 37 ハイドレーションエラーはなぜ起こるのか • サーバーから事前にレンダリングされたReactツリーと、ブラウ ザーでの最初のレンダリング (Hydration/ハイドレーション) 中に レンダリングされたReactツリーの間に違いが生じたため • 今回のケースだと、classNameの不一致 参考記事 • hydrateRoot – React
Slide 38
Slide 38 text
© DMM ハイドレーションエラー対策 38 ハイドレーションとは • サーバから受け取った「乾いたHTML」に、クライアントサイドの インタラクティブな機能を注ぎ込むこと ハイドレーションエラーとは • 「サーバから受け取った初期HTML」と「クライアントサイドJSが 予期するHTML」が一致しない場合に起こるエラー 参考記事 • 7歳娘「パパ、ReactのHydration Errorってなんで起こるの?」 - Qiita
Slide 39
Slide 39 text
© DMM ハイドレーションエラー対策 39 対策:Pre-rendering and Data Fetching | Learn Next.js を参考に、 フックを使用してレンダリングのタイミングを意図的に制御
Slide 40
Slide 40 text
© DMM 40 まとめ 今後やりたいこと • LightHouseのスコア改善 • アプローチ→FirebaseやGoogle Analytics、New Relicなどで モニタリング&改善の試作 • 目標→スコアオール100点 • 機能拡張 • プロフィールページの作成など
Slide 41
Slide 41 text
© DMM ご静聴ありがとうございました🎉