๋ด๋ณด๋ด๋ฒ(๋ด๊ฐ ๋ณด๋ ค๊ณ ๋ด๊ฐ ๋ฒ์ญํ...) ์ํฐํด
โป ์์ด ์ ๊ณต์๋ ํด์ธ ์ ํํ๋ ์๋๊ธฐ์ ๋ฒ์ญ์๋ ์์ญ, ์ค์ญ, ๊ตฌ๊ธ ๋ฒ์ญ์ด ๋ฌด์ํ ๋ง์ ์ ์์ผ๋ฉฐ, ๊ฐ์ธ์ ์ธ ๊ณต๋ถ ๋ชฉ์ ์ผ๋ก ๋ฒ์ญํ๋ค ๋ณด๋ ์คํ๋ ๋ง์ ์ ์๋ค. ์ ํํ ๋ด์ฉ์ ํด๋น ์ํฐํด์ ์ง์ ์ดํด๋ณด๊ฑฐ๋ ๋ค๋ฅธ ์ ๋ณด๋ค์ ๋ ์ฐพ์๋ณด๋ ๊ฒ์ ์ถ์ฒํ๋ค.
(ํ์ง๋ง ๋๊ธ ํผ๋๋ฐฑ๋ ํ์ํฉ๋๋ค๐ ๊ธ์ ์ฝ์ด๋ณด์๊ณ ๋์์ ์ป์ผ์ จ๋ค๋ฉด ์ํฐํด ์ ์์ ๋ธ๋ก๊ทธ์์ ์ข์์๋ ๋๋ฌ์ฃผ์ธ์.)
How to choose between Next.js CSR, SSR, SSG, and ISR by Theodorus Clarence ์๋ฌธ ์ฝ๊ธฐ >>
Introduction
On my last blog, you have explored the technical side of how does it work underneath, now what you will need is how to choose between them. I'll give you 4 metrics and some use cases to help you decide.
์ง๋ ํฌ์คํธ์์ Next.js์ CSR, SSR, SSG, ISR์ด ์ด๋ป๊ฒ ๋์ํ๋์ง ๊ธฐ์ ์ ์ธ ์ธก๋ฉด์ ๋ํด์ ์์๋ณด์๋ค๋ฉด ์ด์ ๋ ๊ทธ๋ค ์ค ์ด๋ป๊ฒ ๊ณ ๋ฅด๋๋ํ๋ ๊ฒ์ด ํ์ํ ๊ฒ์ด๋ค. 4๊ฐ์ง์ ์ธก์ ํญ๋ชฉ๊ณผ ๊ฒฐ์ ํ๋๋ฐ ๋์์ด ๋ ๋งํ ๋ช ๊ฐ์ง ์ฌ์ฉ ์ฌ๋ก๋ค์ ๋ํด ์ด์ผ๊ธฐํด๋ณด๊ฒ ๋ค.
These metrics will generally work for most of the cases but there might be some cases that are not fit with this metric.
์ด ์ธก์ ํญ๋ชฉ๋ค์ ๋ณดํต ๋๋ค์์ ๊ฒฝ์ฐ์ ์ฌ์ฉ๋ ์ ์์ง๋ง ์ด ์ธก์ ํญ๋ชฉ๊ณผ ์ ๋ง์ง ์๋ ๊ฒฝ์ฐ๋ค๋ ์์ ์ ์๋ค.
Prerequisites
This post will not cover the technical difference between Client-Side Rendering, Server-Side Rendering, Static Site Generator, and Incremental Static Regeneration.
์ด ํฌ์คํธ์์๋ Client-Side Rendering, Server-Side Rendering, Static Site Generator, ๊ทธ๋ฆฌ๊ณ Incremental Static Regeneration ์ฌ์ด์ ๊ธฐ์ ์ ์ธ ์ฐจ์ด์ ๋ํด์๋ ๋ค๋ฃจ์ง ์์ ๊ฒ์ด๋ค.
You are encouraged to read my blog about Understanding Next.js Data Fetching (CSR, SSR, SSG, ISR) first.
๋จผ์ Understanding Next.js Data Fetching (CSR, SSR, SSG, ISR) ์ด ํฌ์คํธ๋ฅผ ์ฝ๊ณ ์ค๋ ๊ฒ์ ์ถ์ฒํ๋ค.
Something to note
Please do note that when we are talking about a website, you can use more than 1 fetch method. Use the necessary fetch method for each page.
์น์ฌ์ดํธ์ ๋ํด์ ์ด์ผ๊ธฐํ ๋ 1๊ฐ ์ด์์ ํจ์น ๋ฉ์๋๋ฅผ ์ฌ์ฉํ ์ ์๋ค๋ ์ ์ ์ผ๋์ ๋๋ผ. ๊ฐ ํ์ด์ง ๋ณ๋ก ํ์ํ ํจ์น ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ผ.
Review
Let's review the last blog to remember what are the characteristics of each.
๊ธฐ์ต์ ๋์ด๋ฆฌ๊ธฐ ์ํด์ ์ง๋ ํฌ์คํธ์์ ๋ค๋ฃฌ ๊ฐ๊ฐ์ ํน์ฑ์ ๋ํด์ ๋ณต์ตํด๋ณด์.
- Client-Side Rendering (useEffect) → the data is fetched after every single render
- Server-Side Rendering → the data is fetched before every single render
- Static Site Generator → the data is fetched once at build time
- Incremental Static Regeneration → the data is fetched once on build time and will be fetched again after a certain cooldown and served on the second visit.
- Client-Side Rendering (useEffect) → ๋ฐ์ดํฐ๋ ๋งค๋ฒ ๋ ๋ ํ์ ํจ์น๋๋ค
- Server-Side Rendering → ๋ฐ์ดํฐ๋ ๋งค๋ฒ ๋ ๋ ์ ์ ํจ์น๋๋ค
- Static Site Generator → ๋ฐ์ดํฐ๋ ๋น๋ ์๊ฐ์ ํจ์น๋๋ค
- Incremental Static Regeneration → ๋ฐ์ดํฐ๋ ๋น๋ ์๊ฐ์ ํจ์น๋๊ณ ํน์ ์ฟจ๋ค์ด ๊ธฐ๊ฐ ํ์ ๋ค์ ํจ์น๋๊ณ ๋๋ฒ์งธ ๋ฐฉ๋ฌธ ์์ ๋ณด์ฌ์ง๋ค.
Keep an eye on the frequency of each fetch method.
๊ฐ ํจ์น ๋ฉ์๋์ ๋น๋์ ์ฃผ์ํด๋ณด๋ผ.
Metrics
Usually, when I'm deciding what fetch method I should use, I consider these 4 metrics.
๋ณดํต ์ด๋ค ํจ์น ๋ฉ์๋๋ฅผ ์ฌ์ฉํด์ผํ ์ง ๊ณ ๋ฏผํ ๋ ๋๋ ์ด 4๊ฐ์ง ์ธก์ ํญ๋ชฉ์ ๋ํด์ ๊ณ ๋ คํ๋ค.
Metric 1: ๐ Data Integrity
Data integrity is how fresh do you want the data to be.
๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ์ ๋ฐ์ดํฐ๊ฐ ์ผ๋ง๋ ์ต์ ์ํ๋ก ์ ์ง๋๊ธฐ๋ฅผ ์ํ๋๊ฐ์ด๋ค.
High
High integrity means that we want fresh data—the most updated one—every single render. This is usually crucial for pages that are interactive and contain some critical value that can't be stale.
๋์ ๋ฌด๊ฒฐ์ฑ์ ์ฐ๋ฆฌ๊ฐ ๋งค๋ฒ ๋ ๋์ ๋ง๋ค ๊ฐ์ฅ ์ต์ ์ ๋ฐ์ดํฐ๋ฅผ ์ํ๋ค๋ ์๋ฏธ์ด๋ค. ์ด๊ฒ์ ์ฃผ๋ก ์ธํฐ๋ํฐ๋ธํ๊ณ ์ค๋๋์ด์๋ ์๋๋ ์ค์ํ ๊ฐ๋ค์ ํฌํจํ๋ ํ์ด์ง๋ค์ ์ค์ํ๋ค.
Simply put:
We need the most updated data, every. single. time.
์ฐ๋ฆฌ๋ ๋งค. ๋ฒ. ๊ฐ์ฅ ์ต์ ์ ๋ฐ์ดํฐ๊ฐ ํ์ํ๋ค.
Sites that benefit high data integrity:
๋์ ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ์ ์ ๊ณตํ๋ ์ฌ์ดํธ:
- Products page that contains price → imagine you have a product page, and the price shown is not the most updated one. You might lose some dough.
- The comment section on Twitter → we want to see the most recent comment
- Social media → we want to see the most up-to-date content obviously.
- ๊ฐ๊ฒฉ์ ํฌํจํ๋ ์ ํ ํ์ด์ง → ๋น์ ์๊ฒ ์ ํ ํ์ด์ง๊ฐ ์๊ณ ๋ณด์ฌ์ง๋ ๊ฐ๊ฒฉ์ด ๊ฐ์ฅ ์ต์ ์ ๊ฐ์ด ์๋๋ผ๊ณ ์์ํด๋ณด๋ผ. ์ํด๋ฅผ ๋ณผ์ง๋ ๋ชจ๋ฅธ๋ค.
- ํธ์ํฐ์ ๋๊ธ ์น์ → ์ฐ๋ฆฌ๋ ๊ฐ์ฅ ์ต๊ทผ์ ๋๊ธ์ ํ์ธํ๊ธธ ์ํ๋ค.
- ์์ ๋ฏธ๋์ด → ์ฐ๋ฆฌ๋ ๋น์ฐํ ๊ฐ์ฅ ์ต์ ์ ์ปจํ ์ธ ๋ฅผ ๋ณด๊ณ ์ถ๋ค.
Medium
Medium integrity means that we want to serve fresh data, but it is not much of a problem if some users get stale data.
์ค๊ฐ ์์ค์ ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ์ ์ต์ ๋ฐ์ดํฐ๋ฅผ ์ํ๊ธดํ์ง๋ง ์ฌ์ฉ์๊ฐ ์ค๋๋ ๋ฐ์ดํฐ๋ฅผ ๋ณธ๋คํด๋ ํฌ๊ฒ ๋ฌธ์ ๊ฐ ๋์ง ์๋ ๊ฒฝ์ฐ๋ฅผ ์๋ฏธํ๋ค.
Simply put:
We should get fresh data, but it's okay if some still see the stale one.
์ต์ ๋ฐ์ดํฐ๊ฐ ์์ด์ผ์ง๋ง ์ฌ์ ํ ์ค๋๋ ๋ฐ์ดํฐ ๊ฐ๋ ๋ณด์ฌ๋ ๊ด์ฐฎ๋ค.
Sites that benefit medium data integrity:
์ค๊ฐ ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ์ ์ ๊ณตํ๋ ์ฌ์ดํธ:
- Blog post with CMS → you can tolerate it when someone gets the stale page with minor typos
- Profile page → it is rarely updated and it is not that critical
- CMS๋ฅผ ์ฌ์ฉํ๋ ๋ธ๋ก๊ทธ ํฌ์คํธ → ๋๊ตฐ๊ฐ๊ฐ ๋ช๊ฐ์ ์คํ๊ฐ ๊ฐฑ์ ์ด ๋์ง ์์ ํ์ด์ง๋ฅผ ๋ณด๊ฒ ๋๋ ๊ฒ์ ์์ฉํ ์ ์๋ค.
- Profile page → ์ ๋ฐ์ดํธ๊ฐ ๊ฑฐ์ ์ผ์ด๋์ง ์๊ณ ๊ทธ๋ ๊ฒ ์น๋ช ์ ์ด์ง๋ ์๋ค.
Please note that only you can decide what is critical. If you are mainly making a website to showcase your profile and portfolio with a high update rate, then it can be considered critical.
๋ฌด์์ด ์น๋ช ์ ์ธ์ง์ ๋ํด์๋ ๋น์ ์์ ๋ง์ด ๊ฒฐ์ ํ ์ ์๋ค๋ ์ ์ ์ ์ํ๊ธธ ๋ฐ๋๋ค. ๋ง์ฝ ๋น์ ์ด ์์ฃผ ์ ๋ฐ์ด๋๋ ํ๋กํ๊ณผ ํฌํธํด๋ฆฌ์ค๋ฅผ ๋ณด์ฌ์ฃผ๊ธฐ ์ํ ์ฌ์ดํธ๋ฅผ ์ฃผ๋ก ๋ง๋ค๊ณ ์๋ค๋ฉด, ๊ทธ ์ฌ์ดํธ๋ ์น๋ช ์ ์ด๋ผ๊ณ ๊ณ ๋ ค๋ ์ ์๋ค.
Low to none
Pages that fall into this category usually won't change or rarely change.
๋ณดํต ๋ณ๊ฒฝ์ฌํญ์ด ์๊ฑฐ๋ ๊ฑฐ์ ๋ณ๊ฒฝ๋์ง ์๋ ํ์ด์ง์ ์ํ๋ ๊ฒฝ์ฐ.
Simply put:
We don't really care, just fetch and show it.
์ฐ๋ฆฌ๋ ๋ณ๋ก ์ ๊ฒฝ์์ฐ๊ณ ๊ทธ๋ฅ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์์ ๋ณด์ฌ์ฃผ๊ธฐ๋ง ํ๋ฉด ๋๋ค.
Sites that benefit low to none data integrity:
๋ฎ์ ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ์ด๋ ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ ๋ณด์ฅ์ด ํ์์๋ ์ฌ์ดํธ๋ฅผ:
- About page
- A page with fixed data that won't change → ex: a pokemon stat page (we will use this as an example later)
- About ํ์ด์ง
- ๋ฐ์ดํฐ๊ฐ ๋ณ๊ฒฝ๋์ง ์๋ ๊ณ ์ ๋ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ๋ ํ์ด์ง → ์์: ํฌ์ผ๋ชฌ ์คํฏ ํ์ด์ง (์ถํ์ ์ด ์์ ๋ฅผ ์ฌ์ฉํ ๊ฒ์)
Table Result
As we can see on the illustration:
์ฝํ์์ ๋ณผ ์ ์๋ฏ์ด:
- High: CSR and SSR, as it fetches on every render
- Medium: ISR, we still can get the fresh data, but some user will still get the stale one
- Low to none: SSG, it is only fetched on build time
- ๋์: CSR์ SSR, ๋งค๋ฒ ๋ ๋์๋ง๋ค ๊ฐ์ ธ์์ผํจ์ผ๋ก
- ์ค๊ฐ: ISR, ์ฌ์ ํ ์ต์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ธด ํ์ง๋ง ๋ช๋ช ์ฌ์ฉ์๋ ์ค๋๋ ๋ฐ์ดํฐ๋ฅผ ๋ณด๊ฒ๋จ
- ๋ฎ์์์ ๋ฌด๊ด: SSG, ์ค์ง ๋น๋ ์๊ฐ์๋ง ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ด
Metric 2: ๐ SEO
SEO (Search Engine Optimization) is going to be useful when we want our content to be easily found on google and bringing in that good organic visitors.
SEO(๊ฒ์ ์์ง ์ต์ ํ) ๋ ์ฐ๋ฆฌ์ ์ปจํ ์ธ ๋ฅผ ๊ตฌ๊ธ์์ ์ฝ๊ฒ ์ฐพ์ ์ ์๊ณ ์ข์ ์์ฐ์ค๋ฌ์ด ๋ฐฉ๋ฌธ์*๋ค์ ์ ์ ํ๊ธฐ๋ฅผ ์ํ ๋ ์ ์ฉํ๋ค.
(*Organic traffic is those visitors that land on your website from unpaid sources, aka essentially free traffic. Organic sources here include search engines like Google, Yahoo, or Bing. - ์ถ์ฒ useinsider)
I only have 2 categories for this, which are SEO Friendly and Not SEO Friendly.
์ด ์ธก์ ํญ๋ชฉ์์๋ 2๊ฐ์ ์นดํ ๊ณ ๋ฆฌ๋ง ์กด์ฌํ๋๋ฐ, SEO ์นํ์ ๊ทธ๋ฆฌ๊ณ SEO ๋น์นํ์ ์ด๋ค.
SEO Friendly
This category is expected when we are pre-rendering the content on the website, the general difference is when we are doing pre-render, we can see the content on the page source. This type of rendering will help search engines index our page and might put us up on the SEO ranking.
์ด ์นดํ ๊ณ ๋ฆฌ๋ ์ฐ๋ฆฌ๊ฐ ์น์ฌ์ดํธ์ ์๋ ์ปจํ ์ธ ๋ฅผ ํ๋ฆฌ ๋ ๋๋งํ ๋ ๊ธฐ๋ํ ์ ์๋๋ฐ, ๊ธฐ๋ณธ์ ์ธ ์ฐจ์ด์ ์ ํ๋ฆฌ๋ ๋๋ง์ ํ ๋, ํ์ด์ ์์ค์์ ์ปจํ ์ธ ๋ฅผ ๋ณผ ์ ์๋ค๋ ๊ฒ์ด๋ค. ์ด ๋ ๋๋ง ํ์ ์ ๊ฒ์ ์์ง์ด ์ฐ๋ฆฌ์ ํ์ด์ง๋ฅผ ์ธ๋ฑ์ฑํ๊ณ SEO ๋ญํน์ ์ฌ๋ฆด ์๋ ์๋ค.
SSR, SSG, ISG categorizes as SEO Friendly because the HTML is prefilled with the content without having to fetch it on the client-side.
SSR, SSG, *ISR ๋ SEO ์นํ์ ์ผ๋ก ๋ถ๋ฅํ๋๋ฐ ํด๋ผ์ด์ธํธ ์ธก์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค์ง ์์๋ HTML์ด ์ปจํ ์ธ ๋ก ๋ฏธ๋ฆฌ ์ฑ์์ ธ ์๊ธฐ ๋๋ฌธ์ด๋ค.
(*๋ณธ๋ฌธ์ ISG๊ฐ ์คํ๋ก ์๊ฐ๋์ด ISR๋ก ์์ )
Sites that can benefit SEO
SEO๊ฐ ๋์์ด ๋๋ ์ฌ์ดํธ
- Shopping website → it will be great if our products show up on search engine
- Quora-type website → site that provides an answer of course relies on SEO. You probably not going to search something directly from quora or stack overflow, but you start on google.
- Social media → contents need to be able to be searched on the internet
- ์ผํ ์น์ฌ์ดํธ → ์ฐ๋ฆฌ์ ์ ํ์ด ๊ฒ์ ์์ง์ ๋ณด์ฌ์ง๋ ๊ฒ์ด ์ข์ ๊ฒ์
- Quoraํ ์น์ฌ์ดํธ → ๋ต๋ณ์ ์ ๊ณตํด์ฃผ๋ ์ฌ์ดํธ๋ ๋น์ฐํ SEO์ ์์กดํด์๋ค. ๋น์ ์ ์๋ง๋ Quora๋ Stack Overflow์์ ๋ฌด์ธ๊ฐ๋ฅผ ๋ฐ๋ก ๊ฒ์ํ์ง ์๊ณ Google์์ ๊ฒ์ ํ ๊ฒ์ด๋ค.
- Social media → ์ปจํ ์ธ ๋ ์ธํฐ๋ท์์ ๊ฒ์๋ ์ ์์ด์ผ ํ๋ค.
Not SEO Friendly
It is definitely not bad. Although we don't get any content on the page source, it doesn't mean that the search engine crawler can't index your page. The search engine can still index it, but it is not as friendly as the pre-rendered pages.
์ด๊ฒ์ ํ์คํ ๋์์ง ์๋ค. ํ์ด์ง ์์ค์ ์ด๋ค ์ปจํ ์ธ ๋ ์๊ธด ํ์ง๋ง ๊ฒ์ ์์ง ํฌ๋กค๋ฌ๊ฐ ๋น์ ์ ํ์ด์ง๋ฅผ ์ธ๋ฑ์ฑ ํ ์ ์๋ค๋ ๋ป์ ์๋๋ค. ๊ฒ์ ์์ง์ ์ฌ์ ํ ์ธ๋ฑ์ฑ ํ ์ ์์ง๋ง ํ๋ฆฌ๋ ๋๋ ํ์ด์ง๋งํผ ์นํ์ ์ด์ง๋ ์์ ๊ฒ์ด๋ค.
CSR is categorized as Not SEO Friendly because we do not get any content until after the page renders.
CSR์ SEO ๋น์นํ์ ์ผ๋ก ๋ถ๋ฅ๋๋๋ฐ ํ์ด์ง๊ฐ ๋ ๋๋ ํ๊น์ง ์๋ฌด ์ปจํ ์ธ ๋ ๊ฐ์ ธ์ค์ง ๋ชปํ๊ธฐ ๋๋ฌธ์ด๋ค.
Sites that don't really need SEO
SEO๊ฐ ๊ทธ๋ค์ง ํ์ํ์ง ์์ ์ฌ์ดํธ
- Authentication Gated Apps → things like a dashboard, premium content, or paid courses.
- Registration page
- ์ธ์ฆ์ด ํ์ํ ์ฑ → ๋์๋ณด๋, ํ๋ฆฌ๋ฏธ์ ์ปจํ ์ธ ํน์ ์ ๋ฃ ์ฝ์ค์ ๊ฐ์ ๊ฒ๋ค.
- ๊ฐ์ ํ์ด์ง
Table Result
- SEO Friendly: SSR, SSG, and ISR all have very great SEO because they pre-render the fetched content
- Not SEO Friendly: CSR is not that good because we only get the data after render
- SEO ์นํ์ : SSR, SSG ๊ทธ๋ฆฌ๊ณ ISR ๋ชจ๋ ๋งค์ฐ ์ข์ SEO๋ฅผ ์ ๊ณตํ๋๋ฐ ํจ์น๋ ์ปจํ ์ธ ๋ฅผ ํ๋ฆฌ๋ ๋๋งํ๊ธฐ ๋๋ฌธ
- SEO ๋น์นํ์ : CSR์ ๊ทธ๋ค์ง ์ข์ง ์์๋ฐ ๋ ๋ ํ์์์ผ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ๋๋ฌธ
Metric 3: โฉ Performance
Performance is whether it is loading when we visit the page or not. It should be very easy to differentiate now if you have read the first blog.
์ฑ๋ฅ์ ์ฐ๋ฆฌ๊ฐ ํ์ด์ง๋ฅผ ๋ฐฉ๋ฌธํ์ ๋ ๋ก๋ฉ ์ค์ธ๊ฐ ๊ทธ๋ ์ง ์์๊ฐ๋ฅผ ์๋ฏธํ๋ค. ์ฒซ ํฌ์คํธ๋ฅผ ์ฝ์๋ค๋ฉด ๋งค์ฐ ์ฝ๊ฒ ๊ตฌ๋ถํ ์ ์์ ๊ฒ์ด๋ค.
Please note that performance in this metrics strictly means to the load time before First Contentful Paint, not to be generalized to the whole application performance.
์ด ์ธก์ ํญ๋ชฉ ์ค ์ฑ๋ฅ์ ์๋ฐํ ๋งํ๋ฉด First Contentful Paint ์ ์ ๋ก๋ ์๊ฐ์ด๊ณ ์ ์ฒด ์ดํ๋ฆฌ์ผ์ด์ ์ฑ๋ฅ์ผ๋ก ์ผ๋ฐํ๋์ง ์๋๋ค๋ ์ ์ ์ฐธ๊ณ ํด๋์.
Instant
Instantly loads because the fetching does not happen when we request.
์ฆ์ ๋ก๋๋๋ค. ๋ฐ์ดํฐ ํจ์นญ์ ์ฐ๋ฆฌ๊ฐ ์์ฒญํ์ ๋ ๋ฐ์ํ์ง ์๊ธฐ ๋๋ฌธ์ด๋ค.
Loads before/after render
There will be a slight loading on before or after renders.
๋ ๋ ์ ์ด๋ ํ์ ์ ๊น์ ๋ก๋ฉ์ด ์๋ค.
Table Result
Well, we obviously want better performance, so this is not something that you choose as the main metrics, but rather to consider.
์ฐ๋ฆฌ๋ ๋น์ฐํ ๋ ๋์ ์ฑ๋ฅ์ ์ํ๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ์ฃผ์ ์ธก์ ํญ๋ชฉ์ผ๋ก ์ ํํ๋ ๊ฒ์ด๋ผ๊ธฐ ๋ณด๋ค ๊ณ ๋ คํด์ผ ํ๋ ๊ฒ์ด๋ค.
- Instant: SSG & ISR
- Loads before/after render: CSR & SSR
- ์ฆ์: SSG & ISR
- ๋ ๋ ์ ํ๋ก ๋ก๋: CSR & SSR
Editorial
Addition by Delba de Oliveira.
This expands on how rendering/data fetching (bringing together your application code and data) affects performance
์ด๊ฒ์ ๋ ๋๋ง / ๋ฐ์ดํฐ ํจ์นญ ( ์ดํ๋ฆฌ์ผ์ด์ ์ฝ๋์ ๋ฐ์ดํฐ๋ฅผ ํจ๊ป ๊ฐ์ ธ์ค๋ ๊ฒ) ์ด ์ฑ๋ฅ์ ๋ฏธ์น๋ ์ํฅ์ ํ์ฅํ๋ค
- CSR: Rendering happens on the browser, so users may see a loading spinner while the application is being rendered. The performance (initial load) depends on the size of the application and how much JS is shipped to the browser.
- SSR: Rendering happens on the server before the result is sent to the browser. There may be latency (depending on the server's location) because the request has to go to the server and back.
- SSG: Rendering happens at a built time on the server, the result is cached in CDNs closer to users. This helps improve performance because rendering happens once and the result is stored closer to users (solving latency issues).
- ISR: Rendering happens at time intervals and is cached, so it's still performant but using ISR ensures data doesn't become stale.
- CSR: ๋ ๋๋ง์ ๋ธ๋ผ์ฐ์ ์์ ๋ฐ์ํ๊ณ ์ฌ์ฉ์๋ ์ ํ๋ฆฌ์ผ์ด์ ์ด ๋ ๋๋๋ ๋์ ๋ก๋ฉ ์คํผ๋๋ฅผ ๋ณด๊ฒ๋ ๊ฒ์ด๋ค. ์ฑ๋ฅ์ (์ด๊ธฐ ๋ก๋) ์ ํ๋ฆฌ์ผ์ด์ ์ ํฌ๊ธฐ์ ์ผ๋ง๋ ๋๋ JS๊ฐ ๋ธ๋ผ์ฐ์ ์ ์ ๊ณต๋๋๋์ ๋ฌ๋ ค์๋ค.
- SSR: ๋ ๋๋ง์ ๊ฒฐ๊ณผ๊ฐ ๋ธ๋ผ์ฐ์ ๋ก ๋ณด๋ด์ง๊ธฐ ์ ์ ์๋ฒ์์ ์ผ์ด๋๋ค. ์ง์ฐ์ด ์๊ธธ ์ ์๋๋ฐ (์๋ฒ์ ์์น์ ๋ฐ๋ผ์) ์์ฒญ์ด ์๋ฒ์ ๊ฐ๋ค๊ฐ ๋์์์ผํ๊ธฐ ๋๋ฌธ์ด๋ค.
- SSG: ๋ ๋๋ง์ด ๋น๋ ์๊ฐ์ ์๋ฒ์์ ๋ฐ์ํ๊ณ , ๊ฒฐ๊ณผ๋ ์ฌ์ฉ์์ ๊ฐ๊น์ด CDN์ ์บ์๋๋ค. ์ด๊ฒ์ ์ฑ๋ฅ ํฅ์์ ๋์์ด ๋๋๋ฐ ์๋ํ๋ฉด ๋ ๋๋ง์ด ํ๋ฒ๋ง ๋ฐ์ํ๊ณ ๊ฒฐ๊ณผ๋ ์ ์ ์ ๊ฐ๊น์ด ๊ณณ์ ์ ์ฅ๋๊ธฐ ๋๋ฌธ์ด๋ค(์ง์ฐ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํด์ค).
- ISR: ๋ ๋๋ง์ ์๊ฐ ๊ฐ๊ฒฉ์ผ๋ก ๋ฐ์ํ๊ณ ์บ์๋๋ค. ๊ทธ๋์ ์ฌ์ ํ ์ฑ๋ฅ์ด ๊ด์ฐฎ์ง๋ง ISR๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฐ์ดํฐ๊ฐ ์ค๋๋์ง ์๋๋ค.
Metric 4: โฐ Build Time
Build time is the amount of time it takes to build and deploy the website.
๋น๋ ์๊ฐ์ ์น์ฌ์ดํธ๋ฅผ ๋น๋ํ๊ณ ๋ฐฐํฌํ๋๋ฐ ์์๋๋ ์๊ฐ์ ์์ด๋ค.
This metric is to be considered when we are generating a bunch of pages with parameters, for example, product/[name] or pokemon/[name]
์ด ์ธก์ ํญ๋ชฉ์ ํ๋ผ๋ฏธํฐ๊ฐ ์๋ ๋ง์ ํ์ด์ง๋ค์ ์์ฑํ ๋ ๊ณ ๋ คํด์ผํ๋ค. ์๋ฅผ ๋ค๋ฉด product/[name]์ด๋ pokeman/[name]
Fast (only one page)
When we are using CSR and SSR, we only build 1 page because the data won't be fetched at build time.
CSR๊ณผ SSR์ ์ฌ์ฉํ ๋, ๋ฐ์ดํฐ๊ฐ ๋น๋ ์๊ฐ์ ํจ์น๋์ง ์๊ธฐ ๋๋ฌธ์ 1๊ฐ ํ์ด์ง๋ง ๋น๋ํ๋ค.
For example, if we are visiting /pokemon/bulbasaur then we will take that parameter and use it to fetch it before or after render.
์๋ฅผ ๋ค๋ฉด, /pokemon/bulbasaur๋ฅผ ๋ฐฉ๋ฌธํ๋ฉด ๊ทธ ํ๋ผ๋ฏธํฐ๋ฅผ ๊ฐ์ ธ๋ค ๋ ๋ ์ ์ด๋ ํ์ ํจ์นํ๊ธฐ ์ํด ์ฌ์ฉํ ๊ฒ์ด๋ค.
Slow (every single page)
When we are using SSG and ISR, we are fetching it on build time and creating a page out of the response. So if we have 1000 products, it will take quite some time.
SSG์ ISR์ ์ฌ์ฉํ ๋, ๋น๋ ์๊ฐ์ ํจ์นํ๊ณ ์๋ต์์ ํ์ด์ง๋ฅผ ์์ฑํ๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ์ฐ๋ฆฌ๊ฐ 1000๊ฐ์ ์ ํ์ด ์์ผ๋ฉด ์๊ฐ์ด ์ข ๊ฑธ๋ฆด ๊ฒ์ด๋ค.
Build Time Example
Alt:
- /ssr/poke/[name] only have 1 page even though it is serving 100 pokemon
- /ssg/poke/[name] have all of the pokemon names built into a page.
- /ssr/poke/[name] ์ 100์ข ์ ํฌ์ผ๋ชฌ์ ์ ๊ณตํ๋ค๊ณ ํด๋ 1๊ฐ์ ํ์ด์ง๋ง ์กด์ฌํ๋ค.
- /ssg/poke/[name] ๋ชจ๋ ํฌ์ผ๋ชฌ ์ด๋ฆ์ด ํ์ด์ง๋ก ๋ง๋ค์ด์ง๋ค.
This is something that you'll need to consider if you have thousands of products, or you want to show all of the pokemon out there. We can't wait for them to finish building, using CSR or SSR should be the right answer.
์ด ์ ์ ๋ง์ฝ ๋น์ ์ด ์์ฒ๊ฐ์ ์ ํ์ด ์๊ฑฐ๋ ์กด์ฌํ๋ ๋ชจ๋ ํฌ์ผ๋ชฌ์ ์ ๋ถ ๋ณด์ฌ์ฃผ๊ณ ์ถ๋ค๋ฉด ๊ณ ๋ คํด์ผ ํ ํ์๊ฐ ์์ ๊ฒ์ด๋ค. ๋น๋๊ฐ ๋๋๊ธฐ๋ฅผ ๊ธฐ๋ค๋ฆฌ๊ธฐ๋ง ํ ์๋ ์๋ค. CSR์ด๋ SSR์ด ์ฌ๋ฐ๋ฅธ ํด๊ฒฐ์ฑ ์ด ๋ ๊ฒ์ด๋ค.
Cheatsheet
Examples
CSR
https://next-usecase.thcl.dev/csr
Video:
- there is a loading indicator when visited
- the data (repository detail) that is served is the most up to date
- ๋ฐฉ๋ฌธํ์ ๋ ๋ก๋ฉ ํ์๊ฐ ์์
- ๋ฐ์ดํฐ (์ ์ฅ์ ์ธ๋ถ์ฌํญ)์ ๊ฐ์ฅ ์ต์ ์ผ๋ก ์ ๊ณต
It's ideal for a dashboard and authentication-gated website. We need the latest data, and we don't really care about SEO.
๋์๋ณด๋์ ์ธ์ฆ์ด ํ์ํ ์น์ฌ์ดํธ์ ์ด์์ ์ด๋ค. ์ฐ๋ฆฌ๋ ์ต์ ์ ๋ฐ์ดํฐ๊ฐ ํ์ํ๊ณ SEO์ ๋ํด ๊ทธ๋ค์ง ์ ๊ฒฝ์ฐ์ง ์๋๋ค.
SSG
I'll give SSG example first so we can compare it with SSR
SSG ์์๋ฅผ ๋จผ์ ๋ณด์ฌ์ฃผ์ด์ SSR๊ณผ ๋น๊ตํ ์ ์๋๋ก ํ๊ฒ ๋ค.
https://next-usecase.thcl.dev/ssg
Video:
- Data fetched on build time at 13:58:38, when the current time is already 2 hours late—16:28:30
- It is instant and has no loading
- There are 10 pokemon data to choose
- ๋ฐ์ดํฐ๋ ๋น๋ ์๊ฐ์ธ 13:58:38์ ํจ์น๋์๊ณ , ํ์ฌ ์๊ฐ์ 2์๊ฐ ๋ค์ธ 16:28:30
- ์ฆ๊ฐ์ ์ผ๋ก ๋ณด์ฌ์ฃผ๊ณ ๋ก๋ฉ์ด ์์
- ์ ํํ ์ ์๋ 10์ข ์ ํฌ์ผ๋ชฌ ๋ฐ์ดํฐ๊ฐ ์์
This one is great for pokemon data because the data probably won't change for quite some time. And maybe you have a question:
์ด๊ฒ์ ํฌ์ผ๋ชฌ ๋ฐ์ดํฐ์ ์์ฃผ ์ข์ ๋ฐฉ์์ด๋ค. ์๋ํ๋ฉด ๋ฐ์ดํฐ๋ ๊ฝค ์ค๋ซ๋์ ๋ฐ๋์ง ์์ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ด๋ค. ๊ทธ๋ฆฌ๊ณ ์ง๋ฌธ์ด ์๊ธธ ์๋ ์๋๋ฐ:
Why not just store it as JSON and create every page?
JSON์ผ๋ก ์ ์ฅํด์ ๋ชจ๋ ํ์ด์ง๋ฅผ ์์ฑํ์ง ์๋ ์ด์ ๋ ๋ญ์ฃ ?
We usually use SSG for convenience, adding hundreds of pages is quite repetitive and we can maintain it better if we use getStaticProps
ํธ์๋ฅผ ์ํด์ SSG๋ฅผ ๋ณดํต ์ฌ์ฉํ๋๋ฐ ์๋ฐฑ๊ฐ์ ํ์ด์ง๋ฅผ ์ถ๊ฐํ๋ ๊ฒ์ ๊ฝค ๋ฐ๋ณต์ ์ด๊ณ getStaticProps๋ฅผ ์ฌ์ฉํ๋ฉด ๋ ์ ์ ์งํ ์ ์๋ค
SSR
You probably notice and have it in mind that apps that have high data integrity and have a good SEO should use SSR, for example, products page, comment section. The obvious example should be Quora, Reddit, Facebook, etc.
๋์ ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ์ ๊ฐ์ง๊ณ ์๊ณ SEO๊ฐ ์ฐ์ํ ์ฑ๋ค์ SSR์ ์ฌ์ฉํด์ผํ๋ค๋ ์ ์ ์๊ณ ์ผ๋์ ๋ ๊ฒ์ด๋ค. ์๋ฅผ ๋ค๋ฉด, ์ ํ ํ์ด์ง, ๋๊ธ ์น์ ๊ณผ ๊ฐ์ด ๋ง์ด๋ค. ๋ช ๋ฐฑํ ์์๋ค๋ก Quora, Reddit, Facebook ๋ฑ์ด ์๋ค.
But it is not always the case, here is the same pokemon app using SSR:
ํ์ง๋ง ํญ์ ๊ทธ๋ฐ ๊ฒ์ ์๋๋ฐ ์๋์ ๋์ผํ ํฌ์ผ๋ชฌ ์ฑ์ SSR์ ์ฌ์ฉํ ๊ฒ์ด๋ค:
https://next-usecase.thcl.dev/ssr
Video:
- Clicking the page takes a second or two before the page shows up
- Fetch time is the current time (meaning the data is fresh)
- There are considerably a lot of pokemon to choose
- ํ์ด์ง๋ฅผ ํด๋ฆญํ๊ณ ํ์ด์ง๊ฐ ๋ณด์ฌ์ง๊ธฐ ์ ์ 1,2์ด ๊ฐ๋์ด ๊ฑธ๋ฆผ
- ํจ์น ์๊ฐ์ ํ์ฌ ์๊ฐ์(๋ฐ์ดํฐ๊ฐ ์ต์ ์ด๋ผ๋ ๊ฒ)
- ์ฌ๊ธฐ์๋ ๊ณ ๋ฅผ ์ ์๋ ๊ฝค ๋ง์ ํฌ์ผ๋ชฌ๋ค์ด ์์
This use case fits because there are about 900 pokemon, and if we build all of them using SSG, it is going to take a while. That is why you should also consider the build time metric.
์ด๋ฌํ ์ฌ์ฉ ์ญ์ ์ ์ ํ๋ฐ ์ฌ๊ธฐ์๋ ์ฝ 900์ข ์ ํฌ์ผ๋ชฌ์ด ์๊ณ ๋ชจ๋์ ๋ํด SSG๋ฅผ ์ฌ์ฉํ์ฌ ๋น๋ํ๋ค๋ฉด ์๊ฐ์ด ์ข ๊ฑธ๋ฆด ๊ฒ์ด๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ์ฐ๋ฆฌ๊ฐ ๋น๋ ์๊ฐ ์ธก์ ํญ๋ชฉ ์ญ์ ๊ณ ๋ คํด์ผ ํ๋ ์ด์ ์ด๋ค.
Well actually 900 is not that much, but imagine Amazon or eBay.
์ฌ์ค Amazon์ด๋ eBay๋ฅผ ์์ํด๋ณด๋ฉด 900์ ๊ทธ๋ ๊ฒ ๋ง์ ๊ฒ๋ ์๋๋ค.
ISR
ISR is quite fun and might be the common grounds between the 4 fetch methods, but we need to emphasize the data integrity. ISR can still give stale data, so it will be dangerous if you are using it on a critical process.
ISR์ ๊ฝค๋ ์ฌ๋ฐ๊ณ 4๊ฐ์ง ์ธก์ ํญ๋ชฉ ์ฌ์ด์์ ํฉ์์ ์ด ๋ ์ ์๋๋ฐ ์ฐ๋ฆฌ๋ ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ์ ๋ํด ๊ฐ์กฐํด์ผํ๋ค. ISR์ ์ฌ์ ํ ์ค๋๋ ๋ฐ์ดํฐ๋ฅผ ์ค ์ ์๊ณ ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ์ค์ํ ํ๋ก์ธ์ค์์ ์ฌ์ฉํ๋ ๊ฒ์ ์ํํ ์ ์๋ค.
For this example, I suggest you visit it yourself
์ด ์์ ์ ๋ํด์๋ ์ง์ ๋ฐฉ๋ฌธํด๋ณด๋ ๊ฒ์ ์ ์ํ๋ค
What to do:
- Try to star the repo that is linked in the demo page (disclosure: you are going to star my personal repository, kindly keep it starred if you like this post ๐)
- Wait for about 5-10 seconds
- Refresh the page twice (remember how ISR works)
- ๋ฐ๋ชจ ํ์ด์ง์ ๋งํฌ๋์ด ์๋ ๋ฆฌํฌ์งํ ๋ฆฌ์ ๋ณ์ ๋๋ฌ๋ผ (disclosure: ๋ด ๊ฐ์ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ ๋ณ์ ๋๋ฅด๊ฒ ๋๋ ๊ฒ์ธ๋ฐ ์ด ํฌ์คํธ๊ฐ ๋ง์์ ๋ค์๋ค๋ฉด ๊ณ์ ๋๋ฅธ์ฑ๋ก ๋์๊ธธ๐)
- 5~10์ด ์ ๋๋ฅผ ๊ธฐ๋ค๋ฆฐ๋ค
- ํ์ด์ง๋ฅผ ๋ ๋ฒ ์๋ก๊ณ ์นจ ํ๋ค (ISR๊ฐ ์ด๋ป๊ฒ ๋์ํ๋์ง ๊ธฐ์ตํด๋ณด๋ผ)
Demo page: https://next-usecase.thcl.dev/isr
You done? Cool!
We can see that the data will still update, but we can have medium data integrity and still have a good performance.
๋ฐ์ดํฐ๊ฐ ์ฌ์ ํ ์ ๋ฐ์ดํธ ๋๋ ๊ฒ์ ํ์ธํ ์ ์๋ค. ํ์ง๋ง ์ค๊ฐ ๋ฐ์ดํฐ ๋ฌด๊ฒฐ์ฑ๊ณผ ์ฌ์ ํ ์ข์ ์ฑ๋ฅ์ ์ป์ ์ ์๋ค.
This is very useful if you are creating a blog with CMS, and it will be updated without having to rebuild the whole site.
CMS ๋ธ๋ก๊ทธ๋ฅผ ๋ง๋๋๋ฐ ๋งค์ฐ ์ ์ฉํ๋ค. ๊ทธ๋ฆฌ๊ณ ์ ์ฒด ์ฌ์ดํธ๋ฅผ ์ฌ๋น๋ ํ์ง ์์๋ ์ ๋ฐ์ดํธ ๋ ๊ฒ์ด๋ค.
Additional Resource
There is a pattern that uses ISR and SWR library, it follows optimistic UI by mutating the value, and regenerating on the background.
ISR๊ณผ SWR ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ ํจํด์ด ์๋๋ฐ, ๊ฐ์ ๋ณ๊ฒฝํ๊ณ ๋ฐฑ๊ทธ๋ผ์ด๋์์ ์ฌ์ฑ์ฑํ์ฌ *optimistic UI๋ฅผ ๋ฐ๋ฅธ๋ค.
(*Optimistic UI is a pattern that you can use to simulate the results of a mutation and update the UI even before receiving a response from the server. - ์ถ์ฒ Apollo docs)
I'm not going to cover this topic, but Joe Bell has a really great article about it.
์ด ํ ํฝ์ ๋ํด์๋ ๋ค๋ฃจ์ง ์์ ๊ฒ์ด์ง๋ง Joe Bell์ด ์ด ์ ์ ๋ํด์ ํ๋ฅญํ ์ํฐํด์ ์์ฑํด๋์๋ค.
Conclusion
Save the 4 metrics cheatsheet, and try to consider each of them when you want to choose.
4๊ฐ์ง ์ธก์ ํญ๋ชฉ ์นํธ์ํธ๋ฅผ ์ ์ฅํด๋๊ณ ๊ณจ๋ผ์ผํ ๋ ๋น๊ตํด๋ณด๋ผ.
Remember you can use multiple fetch methods on different pages. You can use CSR on the dashboard, and also use SSR on the product page. Use the best one.
๋ค๋ฅธ ํ์ด์ง์ ๋ค์์ ํจ์น ๋ฉ์๋๋ฅผ ์ฌ์ฉํ ์ ์๋ค๋ ์ ์ ๊ธฐ์ตํ๋ผ. ๋์๋ณด๋์๋ CSR, ์ํ ํ์ด์ง์๋ SSR์ ์ฌ์ฉํ ์ ์๋ค. ๊ฐ์ฅ ์ ํฉํ ๊ฒ์ ์ฌ์ฉํ๋ผ.
(๊ธ์ด ์ ์ตํ์ จ์ผ๋ฉด ์ํฐํด ์ ์์ ๋ธ๋ก๊ทธ์์ ์ข์์๋ ๋๋ฌ์ฃผ์ธ์๐๐)
How to choose between Next.js CSR, SSR, SSG, and ISR by Theodorus Clarence
'Next.js' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[๋ด๋ณด๋ด๋ฒ] Next.js docs - next/image (v12.1.1) (0) | 2022.04.15 |
---|---|
[๋ด๋ณด๋ด๋ฒ] Understanding Next.js Data Fetching (CSR, SSR, SSG, ISR) (0) | 2022.03.06 |
[๋ด๋ณด๋ด๋ฒ] Next.js docs - Dynamic Import (2) | 2021.08.03 |
[๋ด๋ณด๋ด๋ฒ] Next.js docs - Authentication (2) | 2021.08.02 |
[๋ด๋ณด๋ด๋ฒ] Next.js docs - Deployment (0) | 2021.07.11 |