# 今週何知った? 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 よりも高速
- 更新頻度の高いページには不向き
## メモ欄