Frontend
μμ ui
λ₯Ό λ λλ§νλ λ°©μμ λ€μκ³Ό κ°μ΄ 4κ°μ§λ‘ ν¬κ² ꡬλΆν μ μλ€.
- SSG (Static Site Generators)
- SSR (Server-Side Rendering)
- CSR (Client-Side Rendering)
- ISR (Incremental Static Regeneration) (λλ ISGλΌκ³ λ νλ€)
κ° λ°©μλ§λ€ μ₯λ¨μ μ΄ μκ³ μ§μνλ library
/frameworkλ
λ€λ₯΄λ€. λν νλ‘μ νΈμ κΈ°νμ΄λ UX design
μ λ°λΌμλ μ΄λ€ λ°©μμ μ μ©ν μ§ λ¬λΌμ§ μ μλ€. νλμ μλΉμ€μ νκ°μ§ λ°©λ²λ§μ μ¬μ©νμ§ μμλ λλ€. μ΄λ€ νμ΄μ§λ SSG
, λ λ€λ₯Έ νμ΄μ§λ SSR
μ μ¬μ©ν μλ μλ€.
본격μ μΌλ‘ λ λλ§μ μ΄μΌκΈ°νκΈ° μ μ, SPA
(Single page application
)μ λν΄μ μμ보μ. SPA
λ 2010λ
μ΄λ°, νλ‘ νΈμλ κ°λ°μλ€μ΄ κ° νμ΄μ§μ λν΄μ κΈ°μ‘΄ HTML/CSS/JS
μ‘°ν©μ μ¬μ©νλ λμ μ 체 μ± μ»¨ν
μΈ νλ¦μ javascript
λ§μΌλ‘ ꡬννκΈ°λ₯Ό μνμ¬ νμνκ² λμλ€. λ°λΌμ μλ‘ λ€λ₯Έ CSS
μ javascript
리μμ€λ₯Ό λ‘λνλ μ¬λ¬ HTML
μ 보μ νκ³ , browser
κ° λ§ν¬λ₯Ό μ¬μ©ν΄ νμ΄μ§ μ¬μ΄λ₯Ό νμνλ λμ μ, SPA
λ₯Ό μ΄μ©νμ¬ μ»¨ν
μΈ κ° μλ λ¨μΌ HTML
νμ΄μ§λ₯Ό μ¬μ©νμ¬ νλ μ΄μμ javascript
νμΌμ λ‘λν μ μκ² λ κ²μ΄λ€. SPA
μ λ±μ₯μΌλ‘ λ€μκ³Ό κ°μ μ΄μ μ΄ μκΈ°κΈ°λ νλ€.
- μνλ λ°©μμΌλ‘μ μ½λ μ€κ³/λ°°ν¬λ₯Ό λ¨μΌ ν¨ν€μ§λ‘ ꡬμΆ
application
μ΄ νλ²μ λͺ¨λ λ‘λλλ―λ‘ νμ λ°interaction
μ μΌλ°μ μΌλ‘ μΆκ°μ μΈ λ¦¬μμ€ λ‘λ©μ΄ νμνμ§ μμ λΉ λ₯Έ μλSPA
λapi
λ₯Ό μ¬μ©ν΄content
λ₯Όquery
νκΈ° λλ¬Έμdata
μui
κ°μdecoupling
μΌλ‘ κ΄μ¬μ¬ λΆλ¦¬
νμ§λ§ λμμ λ€μμ κ°μ νκ³μ λ λ°μνμλ€.
app bundle
μ μ 체 ν¬κΈ°κ° μλΉν μ»€μ Έ μ΄κΈ°λ‘λ©μλκ° λλ €μ§ -> μ±λ₯λΆλ΄μΌλ‘ λ°μ - νμ΄μ§ νμμ μνκ΄λ¦¬κ° 볡μ‘ν΄μ§μ μλ κ°λ₯μ±
- κΉλ€λ‘μ΄
SEO
μ΅μ ν *
νΉν SEO
κ° μ μ μ€μν μν μ νκ² λλ©΄μ SPA
μ νκ³μ μ€ νλμΈ SEO
μ΅μ νλ₯Ό 컀λ²νκΈ° μν΄ μ¬λ¬κ°μ§ rendering
λ°©μμ΄ λ±μ₯νκ² λμλ€.
SSG (Static Site Generators)
μ΄κΈ° SSG
λ 2008
λ
λΆν° λ±μ₯νμΌλ©° CMS(Content Management System)
κΈ°λ°μ application
μ λν μλ‘μ΄ λμμ μ μνλ €κ³ νλ€. μ€μ λ‘ λ§μ μΉμ¬μ΄νΈμμλ CMS
(ex Wordpress
)λ‘ νΈμ§λ μ½ν
μΈ λ₯Ό λͺ¨λ μ¬μ©μμκ² serving
νλ€. μ½ν
μΈ κ° runtime
μ μμ±λλ―λ‘ CMS
μ λ³κ²½ μ¬νμ μ¬μ©μμκ² μ§μ λ°°ν¬ν μ μλ€. μ΅κ·Όμλ react
/vue
κΈ°λ°μ Gatsby
κ° λνμ μΈ SSG framework
λ‘ μ¬μ©λκ³ μλ€.
Nextjs
λ κΈ°λ³Έμ μΌλ‘ SSG
λ₯Ό pre-rendering
μ΄λΌκ³ μκ°νλ€. κ° νμ΄μ§λ₯Ό 미리 HTML
μ λ¬Έμλ‘ μμ±νμ¬ κ°μ§κ³ μλ κ²μ΄λ€. client
λ¨μμ μΆκ°λ λλ§μ΄ λ°μνμ§ μμΌλ©° Nextjs
μ rendering
μμ default
κ°μΌλ‘ μ μ©λλ€.
SPA
λμ SSG
λ₯Ό μ¬μ©ν κ²½μ° λ€μκ³Ό κ°μ μ΄μ μ κ°μ§λ€.
- λ λμ
SEO
: μ¬λ¬HTML
νμ΄μ§λ‘ ꡬμ±λμ΄ μμΌλ―λ‘crawling
μ΄ λ μ½κ³ μ½ν μΈ μindex
κ° μ μμ±λλ€ - μ±λ₯ ν₯μ: μ΅μ
SSG
λꡬμλ μμ²ν νμ΄μ§λ₯Ό μ€ννλ λ° νμνJS
/CSS
μ½λλ§ ν¬ν¨λμ΄ μμΌλ©° μ¬μ©μκ° μΉ μ¬μ΄νΈλ₯Ό νμνλ©΄ μΆκ° μ½λλ₯Όload
νλ€ - λ€μ€ μμ€ μ½ν
μΈ :
SSG
λheadless CMS
(Contentful
,Strapi
), λ‘컬markup
νμΌκ°μ λ€μ€ μ½ν μΈ μμ€ ν΅ν©μ μ 곡νλ€
νμ§λ§ λ¨μ λ μ‘΄μ¬νλ©° λ€μκ³Ό κ°λ€.
- μ¬μ©μ λ§μΆ€ν μ½ν μΈ : λͺ¨λ μ¬μ©μκ° λμΌνλ€κ³ μκ°νκ³ κ°μ£Όνκ² λλ€. κ·Έλ μ§ μμΌλ©΄ κ° μ¬μ©μμ λν΄ μ μ μ½ν μΈ λ₯Ό λ§λ€μ΄μ€μΌ νλ©° μ©λμ΄λ 보μ λ±μ λ¬Έμ κ° μκΈ΄λ€
learning curve
:Gatsby
κ°μ κ²½μ°react
κΈ°λ°μμλ λΆκ΅¬νκ³ μ½ν μΈ μΏΌλ¦¬μgraphQL
μ μ¬μ©νλ―λ‘ μ΄λ₯Ό μμΈν μ΄ν΄λ³΄μμΌνλ€- μ¦κ°μ μΈ λ°μ μ΄λ €μ: μ΅μ μνμ μΉ μ»¨ν
μΈ λ₯Ό 보μ¬μ£ΌκΈ° μν΄μλ λ°°ν¬λ₯Ό μ§νν΄μΌ νκ³ κ·Έλ§νΌμ μκ°μ μμνκ² λλ€. λ§μ½
CI/CD
μ 10λΆμ΄ κ±Έλ¦°λ€λ©΄ μ¬μ©μλ 10λΆ νμ νμ¬μ 컨ν μΈ λ₯Ό λ³΄κ² λ κ²μ΄λ€
SSR (Server Side Rendering)
rendering
μμ μ΅μ νΈλ λλ SSR
μΌ κ²μ΄λ€. μ¬μ€ κ·Έλμ SSR
μ μ€λ«λμ μ¬μ©λμ΄ μλ€.
<div>Hello <?php echo 'world'; ?></div> <!-- μ΄λ₯Ό μ½λ κΈ°μ΅νλκ° ? -->
SSR
μ server
λ¨μμ HTML
컨ν
μΈ λ₯Ό rendering
νλκ²μ μλ―Ένλ€. JEE
, ASP.NET
, PHP
λ±μ μΌλ°μ μΈ MVC framework
λ SSR
μ κ°λ₯νκ²νλ template
κΈ°λ°μ engine
μ κ°μ§κ³ μλ€.
μ΄λ¬ν SSR
μ νκ°μ§ μ νμ¬νμ΄ μλ€. client
λ¨μμμ interaction
μ server
μμ μ²λ¦¬ν μ μμΌλ©°, λΈλΌμ°μ μ νμλλ 컨ν
μΈ λ μ΄κΈ° server
μμ μμ±λ 컨ν
μΈ λ‘ μ νλλ€λ κ²μ΄λ€.
κ·Έ λ€μ λμλ€μ javascript
νμΌμ μμ±λμ΄μΌ νλ€. νμ§λ§ Nodejs
μ λ±μ₯μΌλ‘ μ΄μ λ server
λ¨κ³Ό client
λ¨ λͺ¨λ javascript
λ₯Ό μ€νν μ μκ² λμκ³ , rendering
곡μ κ° κ°λ₯ν΄μ‘λ€. μ¦, Nextjs
, Nuxt
λ±μ framework
κ° μ 곡νλκ²μ javascript
λ₯Ό νμ©νμ¬ server
λ¨μ μ΄κΈ° λ‘λμ client
λ¨μ interaction
μ ν΅ν©νμ¬ rendering
μ 곡μ νλ κ²μ΄λΌκ³ ν μ μλ€.
SSR
μ λ€μκ³Ό κ°μ μ₯λ¨μ μ κ°μ§λ€.
μ₯μ
SEO
μ μ 리: κ²μμμ§indexing
μ΄λsocial media
μ 곡μ ν μ μλ μ 보λ₯Ό κ°μ§κ³ μλ€- λΉ λ₯Έ μ±λ₯: μΌλ°μ μΈ
SPA
λ³΄λ€ λ¦¬μμ€ λ‘λμ λ λμ μ±λ₯μ κ°μ§λ€ - API
hosting
κ°λ₯:SSR
μ΄server
μμ μ€νλλ―λ‘SSR
μ μ¬μ©νμ¬API
λ₯Ό κ°λ°ν μλ μλ€
λ¨μ
server
κ° νμ:SSR
μ΄ μλνλ €λ©΄ λΉμ°νserver
κ° νμνλ€. μ΄λ μΆκ°μ μΈ λ¦¬μμ€ λΉμ©μΌλ‘ κ°μ£Όλλ€learning curve
:client
λ¨μμλ§ μμ νλκ²μ λΉν΄ λ§μ μλ‘μ΄ κ°λ κ³Ό λ΄μ©μ΄ λ§μΌλ―λ‘ μ¬μ νμ΅μ΄ νμνλ€client
κ³Ό λ€λ₯Έ λμ: μλ₯Όλ€μ΄window
κ°μ²΄λserver
μμλ μ¬μ©ν μ μμΌλ―λ‘ μ΄λ¬ν μ°¨μ΄λ₯Ό νμΈνμ¬ μ 체μ μΌλ‘ μ λμνλμ§ ν΅ν©μ μΈ ν μ€νΈκ° νμνλ€
CSR (Client Side Rendering)
CSR
μμλ νμ΄μ§μ κΈ°λ³Έ HTML
컨ν
μ΄λλ§ μλ²μ μν΄ rendering
λλ€. κ·Έλ¦¬κ³ νμ΄μ§μ 컨ν
μΈ λ₯Ό νμνκΈ° μν΄ νμν λ‘μ§μ΄λ data fetch
, routing
λ±μ μ€νλλ javascript
μ½λμ μν΄ μ²λ¦¬λλ€. SPA
μ μ±μ₯κ³Ό ν¨κ» CSR
λ μμ°μ€λ½κ² μΈκΈ°λ₯Ό μ»μλ€. frontend
κ°λ°μλ€μκ² κ°μ₯ μΉμνκ³ λ κΈ°λ³Έμ μΌλ‘ μ¬μ©νλ λ°©μμΌκ²μ΄λ€. κ°λ¨ν μ₯λ¨μ λ§ μ§κ³ λμ΄κ°λλ‘ νκ² λ€.
μ₯μ
- λ°μ΄λ μ¬μ©μ κ²½ν: νμ΄μ§ μλ‘κ³ μΉ¨ μμ΄ νμμ μ§μνκ³ , λ°μ΄λ μ¬μ©μ κ²½νμ μ 곡νλ
SPA
λ₯Ό κ°λ₯νκ² νλ©°, νμ΄μ§κ°routing
μ΄ μΌλ°μ μΌλ‘ λΉ λ₯΄κΈ° λλ¬Έμ λ°μμ±μ΄ μ’μ보μΈλ€ - κ΄μ¬μ¬μ λΆλ¦¬:
client
μ½λμserver
μ½λλ₯Ό λͺ ννκ² λΆλ¦¬ν μ μλ€
λ¨μ
SEO
μ΅μ νκ° μ΄λ €μ:CSR
μ κ²½μ° ν°payload
μnetwork
μμ²μΌλ‘ μλ―Έμλ μ½ν μΈ κ°crawler
κ°index
λ₯Ό μμ±ν λ§νΌ λΉ λ₯΄κ²rendering
λμ§ μμ μ μμΌλ―λ‘SEO
μ΅μ νμ μ΄λ €μμ΄ μ‘΄μ¬νλ€- λλ¦° μλ΅ μκ°:
server
λ‘μ μλ³΅μ΄ μκΈ° λλ¬Έμ μλ΅μκ°μ΄ λ리λ€. μΉνμ΄μ§κ°client
μΈ‘μμ μ½ν μΈ λ₯Ό μ²μμΌλ‘rendering
νλ €λ©΄javascript
κ° λ¨Όμ load
λκ³ , μ²λ¦¬κ° μμλ λκΉμ§ κΈ°λ€λ €μΌνλ€. λνapi
νΈμΆλ‘ λ°μ΄ν°λ₯Ό κ°μ Έμ¬ κ²½μ° μλ΅μκ°μ΄ 걸릴 μ μλ€
ISR (Incremental Static Regeneration)
ISR
μ κ°λ¨ν λ§ν΄, μ μ μμ±(static generation
)μΌλ‘ 미리 λ§λ€μ΄λμ νμ΄μ§λ μ
λ°μ΄νΈκ° κ°λ₯νλ€λ κ²μ΄λ€. κ·Έλ κ² λλ©΄ μ μ μμ±μ μ₯μ μ κ°μ Έκ°λ©΄μ λ¨μ μ 보μν μ μλ€. ISR
μ μΌμ μ£ΌκΈ°λ§λ€ μ
λ°μ΄νΈλ λ°μ΄ν°λ‘ μ μ νμ΄μ§λ₯Ό λ€μ μμ±ν΄μ£Όλ λ°©μμ΄λ€.
ꡬνλ°©μμ nextjs
κΈ°μ€μΌλ‘ 보μμλ, getStaticProps
μ revalidate
λ₯Ό μΆκ°νκ³ κ·Έ κ°μΌλ‘ κ°±μ μ£ΌκΈ°(μ΄λ¨μ)λ₯Ό μ λ¬ν΄μ£Όλ©΄ λλ€.
export async function getStaticProps(context) {
const data = await fetch(api);
return {
props: { data },
revalidate: 20, // (μλ²μκ° κΈ°μ€ 20μ΄λ§λ€ dataμ μ
λ°μ΄νΈλ₯Ό κ²μ¬)
};
}
revalidate time
μ μ§μ νκΈ° λλ¬Έμ, μ
λ°μ΄νΈλ μ 보μ μμ΄ revalidate
κ°λ§νΌμ λλ μ΄κ° λ°μνκ² λλ€. μ¦, μ€μ λ‘ λ°μ΄ν°κ° μ
λ°μ΄νΈ λμλλΌλ μΌμ μκ°λμμ μ
λ°μ΄νΈλμ§ μμ νμμλ λ΄μ©μ μ¬μ©μλ€μ΄ λ³΄κ² λλ€λ κ²μ΄λ€. λν μ€μ μ
λ°μ΄νΈ μ¬λΆμλ κ΄κ³μμ΄ revalidate
κ° μ΄λ£¨μ΄μ§κΈ° λλ¬Έμ κ·Έλ§νΌμ νλ‘ νΈμλ 리μμ€κ° μ΄μ©λλ€λ λ¨μ μ΄ μ‘΄μ¬νλ€. μ΄λ¬ν λ¨μ μ 극볡ν μ μλ μλ‘μ΄ κΈ°λ₯μ΄ λ°λ‘ on-demand revalidate
μ΄λ€.
on-demand revalidate
λ°©μμ nextjs 12.2.0
λΆν° μ§μνκ³ , μ§μ ν interval time
μ΄μΈμλ μ
λ°μ΄νΈ μ΄λ²€νΈλ₯Ό μ λ¬ν΄μ£Όμ΄ revalidate
λ₯Ό μν€λ λ°©μμ΄λ€. api
λ₯Ό μ΄μ΄λ λ€μ μλμ²λΌ ꡬνμ΄ κ°λ₯νλ€. 곡μλ¬Έμμ°Έμ‘°
export default async function handler(req, res) {
// Check for secret to confirm this is a valid request
if (req.query.secret !== process.env.MY_SECRET_TOKEN) {
return res.status(401).json({ message: 'Invalid token' })
}
try {
// this should be the actual path not a rewritten path
// e.g. for "/blog/[slug]" this should be "/blog/post-1"
await res.revalidate('/path-to-revalidate')
return res.json({ revalidated: true })
} catch (err) {
// If there was an error, Next.js will continue
// to show the last successfully generated page
return res.status(500).send('Error revalidating')
}
}
- https://en.wikipedia.org/wiki/Content_management_system
- https://levelup.gitconnected.com/spa-ssg-ssr-and-jamstack-a-front-end-acronyms-guide-6add9543f24d
- https://www.patterns.dev/react/client-side-rendering/
- https://nextjs.org/docs/pages/building-your-application/data-fetching/incremental-static-regeneration
- https://nextjs.org/docs/pages/building-your-application/data-fetching/incremental-static-regeneration#using-on-demand-revalidation