# 今週何知った? week:18 ## 各自発表 > [name=ken3ypa] ### Elasticsearch における MAX_RESULT_WINDOW #### MAX_RESULT_WINDOW 検索結果の最大表示可能件数。デフォルトは10,000件 https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules.html#:~:text=the%20refresh%20interval.-,index.max_result_window,-The%20maximum%20value これを超えて取得しようとすると `query_phase_execution_exception` が発生する。 10,000件以上に設定すれば取得は可能だが、検索性能劣化が起こりうる。 ではエラーを出さないためにはどう考えればよいか ##### パターン1:検索性能劣化が起こることを承知の上で上限を増やす - 他社事例:https://techblog.zozo.com/entry/search-performance-improvement#:~:text=%E3%81%A3%E3%81%9F%E5%A4%89%E6%9B%B4%E7%82%B9-,max_result_window,-Elasticsearch%E3%81%AEindex - 条件が変わって気づいたら性能劣化ということも考えられるので、事前の性能調査・定期的なモニタリングは必要そう ##### パターン2:取得件数が10,000件を超えないよう調整してリクエストする - 事例:https://qiita.com/highwide/items/99ee85bd1d646963beb1#max_result_window-%E3%81%AE%E8%80%83%E6%85%AE - リクエスト結果と異なる結果を表示することになるため、ユーザー向けの文言は必要そう > [name=makicamel] ## SWR ### SWR とは - データ取得のための React Hooks ライブラリ - [SWR](https://swr.vercel.app/ja) - [HTTP RFC 5861](https://datatracker.ietf.org/doc/html/rfc5861) で提唱された HTTP キャッシュ無効化戦略の `stale-while-revalidate` に由来 - 仕組み 1. キャッシュからデータを返す(stale) 2. フェッチリクエストを送る(revalidate) 3. 最新のデータを持ってくる - Next.js と同じチームが開発している ### 例 ```javascript import useSWR from 'swr' function Profile() { const { data, error } = useSWR('/api/user', fetcher) if (error) return <div> failed to load</div> if (!data) return <div>loading...</div> return <div> hello {data.name}!</div> } ``` - `fetcher` はデータを返す任意の非同期関数 - `fetch` `Axios` `GraphQL` などを利用できる ### 特徴 - SSR / ISR / SSG をサポート ### 嬉しいこと - リクエストのみっつの状態("loading" 、 "ready" 、 "error")を考慮せず宣言的に書ける ```javascript function useUser (id) { const { data, error } = useSWR(`/api/user/${id}`, fetcher) return { user: data, isLoading: !error && !data, isError: error } } function Avatar ({ id }) { const { user, isLoading, isError } = useUser(id) if (isLoading) return <Spinner /> if (isError) return <Error /> return <img src={user.avatar} /> } ``` - 再利用性 - API リクエストの数を減らせる - SWR キーを使用してキャッシュ・共有されるため <details><summary>SWR を使用しない場合</summary> ```javascript // ページコンポーネント function Page () { const [user, setUser] = useState(null) // トップレベルのコンポーネントでデータを取得 useEffect(() => { fetch('/api/user') .then(res => res.json()) .then(data => setUser(data)) }, []) // ローディング中はローディングコンポーネントを表示 if (!user) return <Spinner/> return <div> <Navbar user={user} /> <Content user={user} /> </div> } // 子コンポーネントに props を渡す function Navbar ({ user }) { return <div> ... <Avatar user={user} /> </div> } function Content ({ user }) { return <h1>Welcome back, {user.name}</h1> } function Avatar ({ user }) { return <img src={user.avatar} alt={user.name} /> } ``` </details> <details><summary>SWR を使用した場合</summary> ```javascript // ページコンポーネント // 子コンポーネントがどのようなデータを必要としているかを知らなくて済む function Page () { return <div> <Navbar /> <Content /> </div> } // 子コンポーネント function Navbar () { return <div> ... <Avatar /> </div> } function Content () { const { user, isLoading } = useUser() if (isLoading) return <Spinner /> return <h1>Welcome back, {user.name}</h1> } function Avatar () { const { user, isLoading } = useUser() if (isLoading) return <Spinner /> return <img src={user.avatar} alt={user.name} /> } ``` </details> - フォーカス時・再接続時に再検証する - 定期的に再検証する ### プリレンダリング Next.js ではページ毎に SSR, SSG を選択できる #### CSR - Client Side Rendering - 非プリレンダリング - アクセスがあった際にブラウザ側で HTML を作成する - パフォーマンスはユーザの環境依存 - 「検索エンジンのクローラが対応していないと SEO では不利」「最近(とは)のクローラは CSR に対応しているので関係ない」と言われる #### SSR - Server Side Rendering - プリレンダリング - Next.js ではデフォルトで全てのページでプリレンダリングが有効化されている - **アクセスした際に**サーバ側で HTML を生成し、レンダリング済の HTML をブラウザに提供する - サーバでレンダリングするので早いがサーバに負荷がかかる - リクエスト毎に HTML を生成するので常に最新の情報をユーザに提供できる #### SSG - Static Site Generation - プリレンダリング - アプリのビルド時に HTML を生成する - 事前ビルドした HTML を返却するので SSR よりも高速 - 更新頻度の高いページには不向き ## メモ欄