Closed4

Next.jsの理解を深める!Chapter 10-11

nakamotonakamoto

Chapter 10

Combining Static and Dynamic Content
Currently, if you call a dynamic function inside your route (e.g. noStore(), cookies(), etc), your entire route becomes dynamic.

This is how most web apps are built today. You either choose between static and dynamic rendering for your entire application or for a specific route.

However, most routes are not fully static or dynamic. You may have a route that has both static and dynamic content. For example, consider an ecommerce site. You might be able to prerender the majority of the product page, but you may want to fetch the user's cart and recommended products dynamically on-demand.


What is Partial Prerendering?
Next.js 14 contains a preview of Partial Prerendering – an experimental feature that allows you to render a route with a static loading shell, while keeping some parts dynamic. In other words, you can isolate the dynamic parts of a route. For example:

When a user visits a route:

A static route shell is served, ensuring a initial load fast.
The shell leaves holes where dynamic content will load in asynchronous.
The async holes are streamed in parallel, reducing the overall load time of the page.
This is different from how your application behaves today, where entire routes are either entirely static or dynamic.

Partial Prerendering combines ultra-quick static edge delivery with fully dynamic capabilities and we believe it has the potential to become the default rendering model for web applications, bringing together the best of static site generation and dynamic delivery.

  • Partial PrerenderingはNext.js 14で導入された実験的な機能のこと。静的なローディングシェルを持ちながら、ルートの一部を動的にレンダリングできる。要するに、ルートの動的な部分を分離できる。例えば、ユーザーがルートにアクセスしたとき、最初のロードが速い静的なルートシェルが提供される。このシェルは、非同期にロードされる動的コンテンツのための「穴」を残す。
    非同期の穴は並列にストリーミングされ、ページの全体的なロード時間を短縮する。
    現在のアプリの動作とは異なり、ルートが完全に静的または動的であることとは異なる。

  • Partial Prerenderingは、超高速な静的なエッジ配信と完全に動的な機能を組み合わせており、静的サイト生成と動的配信のベストを組み合わせたWebアプリのデフォルトのレンダリングモデルになる可能性があると考えられる。


How does Partial Prerendering work?
Partial Prerendering leverages React's Concurrent APIs and uses Suspense to defer rendering parts of your application until some condition is met (e.g. data is loaded).

The fallback is embedded into the initial static file along with other static content. At build time (or during revalidation), the static parts of the route are prerendered, and the rest is postponed until the user requests the route.

It's worth noting that wrapping a component in Suspense doesn't make the component itself dynamic (remember you used unstable_noStore to achieve this behavior), but rather Suspense is used as a boundary between the static and dynamic parts of your route.

The great thing about Partial Prerendering is that you don't need to change your code to use it. As long as you're using Suspense to wrap the dynamic parts of your route, Next.js will know which parts of your route are static and which are dynamic.

Note: To learn more about how Partial Prerendering can be configured, see the Partial Prerendering (experimental) documentation or try the Partial Prerendering template and demo. It's important to note that this feature is experimental and not yet ready for production deployment.

  • Partial PrerenderingはReactのConcurrent APIを利用し、Suspenseを使用してアプリの一部のレンダリングを条件が満たされるまで遅延させる(例えば、データがロードされるまで)。初期の静的ファイルには、他の静的コンテンツとともにフォールバックが埋め込まれる。ビルド時(又は再検証時)にルートの静的部分が事前にレンダリングされて、残りの部分はユーザーがルートをリクエストするまで延期される。Suspenseを使うことでルートの静的部分と動的部分の間の境界を作成する。Partial Prerenderingのメリットは、これを使用するためにコードを変更する必要がないこと。ルートの動的部分をSuspenseでラップしている限り、Next.jsはルートのどの部分が静的でどの部分が動的であるかを識別できる。但し、この機能は実験的であり、まだ本番環境へのデプロイには適していない点に注意が必要。
nakamotonakamoto

Chapter 11(first)

Why use URL search params?
As mentioned above, you'll be using URL search params to manage the search state. This pattern may be new if you're used to doing it with client side state.

There are a couple of benefits of implementing search with URL params:

Bookmarkable and Shareable URLs: Since the search parameters are in the URL, users can bookmark the current state of the application, including their search queries and filters, for future reference or sharing.
Server-Side Rendering and Initial Load: URL parameters can be directly consumed on the server to render the initial state, making it easier to handle server rendering.
Analytics and Tracking: Having search queries and filters directly in the URL makes it easier to track user behavior without requiring additional client-side logic.

  • URL検索パラメーターを使用する理由はいくつかある。まず、URLに検索パラメーターを含めるとユーザーが現在のアプリの状態(検索クエリやフィルター)をブックマークしたり共有できる。
    これにより、将来的な参照や共有が容易になる。また、URLパラメーターはサーバー側で直接利用できるため、初期状態のレンダリングやサーバーサイドレンダリングを簡単に処理できる。さらに検索クエリやフィルターがURLに直接含まれると、サーバー側でユーザー行動を追跡しやすくなりクライアント側のロジックが不要になる。

Adding the search functionality
These are the Next.js client hooks that you'll use to implement the search functionality:

useSearchParams- Allows you to access the parameters of the current URL. For example, the search params for this URL /dashboard/invoices?page=1&query=pending would look like this: {page: '1', query: 'pending'}.
usePathname - Lets you read the current URL's pathname. For example, for the route /dashboard/invoices, usePathname would return '/dashboard/invoices'.
useRouter - Enables navigation between routes within client components programmatically. There are multiple methods you can use.

  • useSearchParamsによって現在のURLのパラメーターにアクセスできる。
  • usePathnameによって現在のURLのパス名を読み取れる。
  • useRouterによってクライアントコンポーネント内でルート間のナビゲーションを実現できる。

https://github.com/47ng/nuqs

  • next-usequerystateを使ったら検索ロジックを簡単に実装できる。
nakamotonakamoto

Chapter 11(second)

You're updating the URL on every keystroke, and therefore querying your database on every keystroke! This isn't a problem as our application is small, but imagine if your application had thousands of users, each sending a new request to your database on each keystroke.

Debouncing is a programming practice that limits the rate at which a function can fire. In our case, you only want to query the database when the user has stopped typing.

How Debouncing Works:

Trigger Event: When an event that should be debounced (like a keystroke in the search box) occurs, a timer starts.
Wait: If a new event occurs before the timer expires, the timer is reset.
Execution: If the timer reaches the end of its countdown, the debounced function is executed.
You can implement debouncing in a few ways, including manually creating your own debounce function. To keep things simple, we'll use a library called use-debounce.

  • Debounceを使わないとキーストロークごとにURLを更新し、それに伴いデータベースへのクエリもキーストロークごとに行ってる。このアプローチは小規模なアプリなら問題なくても、何千人もユーザーがいる場合、キーストロークごとに新しいリクエストがデータベースに送信されると問題になる可能性がある。
  • Debounceは、関数の発火率を制限するプログラミング手法。このケースでは、ユーザーが入力を停止したときのみデータベースをクエリする。
/app/ui/search.tsx
// ...
import { useDebouncedCallback } from 'use-debounce';
 
// Inside the Search Component...
const handleSearch = useDebouncedCallback((term) => {
  console.log(`Searching... ${term}`);
 
  const params = new URLSearchParams(searchParams);
  if (term) {
    params.set('query', term);
  } else {
    params.delete('query');
  }
  replace(`${pathname}?${params.toString()}`);
}, 300);
  • next-usequerystatethrottleMsを使ってもDebounceできる。
このスクラップは2024/01/21にクローズされました