ETC.

after

์‘๋‹ต ๋ฐ ์‚ฌ์ „ ๋ Œ๋”๋ง์ด ์™„๋ฃŒ๋œ ์ดํ›„์— ํ˜ธ์ถœ๋  ์ž‘์—…์„ ์˜ˆ์•ฝํ•˜๋Š” ํ›„์ฒ˜๋ฆฌ ๋ฉ”์„œ๋“œ

import { after } from 'next/server'

export default function Layout() {
  after(() => { // ์‹คํ–‰๋  ์ฝœ๋ฐฑ์„ ์ธ์ž๋กœ ๋ฐ›์Œ
    log();
  })
} 
  • ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ, ์„œ๋ฒ„ ์•ก์…˜, ๋ผ์šฐํŠธ ํ•ธ๋“ค๋Ÿฌ, ๋ฏธ๋“ค์›จ์–ด์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅ

    • ์‘๋‹ต ๋ฐ ์‚ฌ์ „ ๋ Œ๋”๋ง์ด ์™„๋ฃŒ๋œ ์ดํ›„์— ํ˜ธ์ถœ๋  ์ž‘์—…(์ฝœ๋ฐฑ)์„ ์˜ˆ์•ฝํ•˜๋Š” ํ›„์ฒ˜๋ฆฌ ๋ฉ”์„œ๋“œ

    • ์‚ฌ์ „ ๋ Œ๋”๋ง (์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ)

    • ์‘๋‹ต (์„œ๋ฒ„ ์•ก์…˜, ๋ผ์šฐํŠธ ํ•ธ๋“ค๋Ÿฌ, ๋ฏธ๋“ค์›จ์–ด)

  • ๋กœ๊น…์ด๋‚˜ ๋ถ„์„ ๊ฐ™์ด ์ž‘์—…์ด ๋ธ”๋ฝ๋˜์ง€ ์•Š์•„์•ผํ•  ์ž‘์—…๋“ค์— ์œ ์šฉ

  • ๋™์  API๊ฐ€ ์•„๋‹ˆ๋ฏ€๋กœ after api๋ฅผ ์‚ฌ์šฉํ•œ๋‹คํ•˜๋”๋ผ๋„ ์ •์  ํŽ˜์ด์ง€๊ฐ€ ๋™์  ํŽ˜์ด์ง€๋กœ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์Œ

    • ์ •์  ํŽ˜์ด์ง€์˜ ๊ฒฝ์šฐ ๋นŒ๋“œ์‹œ, ํŽ˜์ด์ง€ ์žฌ๊ฒ€์ฆ ๋งˆ๋‹ค ์‹คํ–‰๋จ

  • ์‘๋‹ต์ด ์„ฑ๊ณต์ ์œผ๋กœ ์™„๋ฃŒ๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ(๋ฆฌ๋””๋ ‰์…˜, ๋‚ซํŒŒ์šด๋“œ)์—๋„ ์‹คํ–‰ํ•จ

  • ์„œ๋ฒ„ ์•ก์…˜์ด๋‚˜, ๋ผ์šฐํŠธ ํ•ธ๋“ค๋Ÿฌ์—์„œ request API (ํ—ค๋”, ์ฟ ํ‚ค)๋ฅผ after ๋‚ด๋ถ€์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅ

    • ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์—์„œ๋Š” ์‚ฌ์šฉ ๋ถˆ๊ฐ€

      • Next.js๋Š” PPR์„ ์œ„ํ•ด ๋นŒ๋“œ ํƒ€์ž„ ๋˜๋Š” ์š”์ฒญ ์ฒ˜๋ฆฌ ์ดˆ๊ธฐ์— request API ์‚ฌ์šฉ ์—ฌ๋ถ€๋ฅผ ํŒŒ์•…ํ•ด์•ผ ํ•จ.

      • ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์˜ after()๋Š” React ์‚ฌ์ „ ๋ Œ๋”๋ง์ด ๋๋‚œ ํ›„ (์ฆ‰, ํด๋ผ์ด์–ธํŠธ๋กœ ์ŠคํŠธ๋ฆฌ๋ฐํ•˜๊ธฐ ์ง์ „์—) ์‹คํ–‰๋˜๋ฏ€๋กœ,

      • ์ด ์‹œ์ ์— request API๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด Next.js๋Š” ์ด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋™์ ์ด๋ผ๋Š” ๊ฑธ ์‚ฌ์ „์— ์•Œ ์ˆ˜ ์—†์Œ โ†’ PPR ์ตœ์ ํ™” ์‹คํŒจ

      • after(async () => {  
          const userAgent = (await headers().get('user-agent')) || 'unknown'
          const sessionCookie =
            (await cookies().get('session-id'))?.value || 'anonymous'
         
            logUserAction({ sessionCookie, userAgent })
        })

instrumentation.js

์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•ด ์„ผํŠธ๋ฆฌ๊ฐ™์€ ๋ชจ๋‹ˆํ„ฐ๋ง, ๋กœ๊น… ๋„๊ตฌ๋ฅผ ์•ฑ์— ํ†ตํ•ฉํ•˜๋Š” ํ”„๋กœ์„ธ์Šค

  • ์„œ๋ฒ„์—์„œ ๋ฐœ์ƒํ•œ ๋ชจ๋“  ์˜ค๋ฅ˜์— ๋Œ€ํ•œ ์ปจํ…์ŠคํŠธ ์บก์ฒ˜

    • ํŽ˜์ด์ง€ ๋ผ์šฐํ„ฐ, ์•ฑ ๋ผ์šฐํ„ฐ ์‚ฌ์šฉ ๊ฐ€๋Šฅ

    • ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ, ์„œ๋ฒ„ ์•ก์…˜, ๋ผ์šฐํŠธ ํ•ธ๋“ค๋Ÿฌ, ๋ฏธ๋“ค์›จ์–ด ์‚ฌ์šฉ ๊ฐ€๋Šฅ

// src/instrumentation.js
export async function onRequestError(error, request, context) {
  await fetch('https://....' {
    method: 'POST',
    body: JSON.stringify({ message: error.message, request, context }),
    headers: { 'Content-Type': 'application/json' }
  })
}

// next ์„œ๋ฒ„ ์ธ์Šคํ„ด์Šค๊ฐ€ ์‹œ์ž‘๋  ๋•Œ ํ•œ๋ฒˆ ํ˜ธ์ถœ๋จ
export async function register() {
  //init sentry SDK
}
  • ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ์— instrumentation.js[ts] ์ƒ์„ฑ

Form Component

<form /> ์š”์†Œ๋ฅผ ํ™•์žฅํ•œ 'next/form' ์ปดํฌ๋„ŒํŠธ

ํผ ์ œ์ถœ์„ ํ†ตํ•ด ๋„ค๋น„๊ฒŒ์ด์…˜ ๋ฐ ์ฟผ๋ฆฌ ์—…๋ฐ์ดํŠธํ•˜๋Š” ๋ณด์ผ๋Ÿฌ ํ”Œ๋ ˆ์ดํŠธ ์ฝ”๋“œ๋“ค์„ ์ค„์ผ ์ˆ˜ ์žˆ์Œ ๐Ÿ‘

import Form from 'next/form';

export default function Page() {
  return (
   {/* action์— ์ „๋‹ฌํ•œ ๊ฒฝ๋กœ๋กœ ํŽ˜์ด์ง€ ์ „ํ™˜(client) */}
    <Form action='/search'>
      {/*  name='query' ์ธํ’‹์˜ ๋ฒจ๋ฅ˜๊ฐ€ URL ์ฟผ๋ฆฌ๋กœ ๋ถ™๊ฒŒ๋œ๋‹ค.*/}
      <input name='query' /> 
      <button type='submit'>Submit</button>
    </Form>
  )
}
  • Prefetching: ํ™”๋ฉด์— ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํ‘œ์‹œ๋˜๋ฉด, ํผ ์ œ์ถœํ›„ ์ „ํ™˜๋  ํŽ˜์ด์ง€์˜ Layout๊ณผ Loading UI๊ฐ€ ํ”„๋ฆฌํŒจ์นญ๋˜์–ด ํƒ์ƒ‰์†๋„๊ฐ€ ๋นจ๋ผ์ง

  • Client-Side Navigation: ํผ ์ œ์ถœ์‹œ ๊ณต์œ ๋œ ๋ ˆ์ด์•„์›ƒ๊ณผ, ํด๋ผ์ด์–ธํŠธ ์ƒํƒœ๊ฐ€ ๋ณด์กด๋จ

  • Progressive Enhancement: JS๊ฐ€ ๋กœ๋“œ๋˜๊ธฐ ์ „์—๋„ ์ž‘๋™ํ•จ -> <form /> ์ œ์ถœ ๊ธฐ๋Šฅ์€ ์›๋ž˜ html ๊ธฐ๋Šฅ์ด๊ธฐ ๋•Œ๋ฌธ

Optimizing bundling of extenral packages

  • ์™ธ๋ถ€ ํŒจํ‚ค์ง€๋ฅผ ๋ฒˆ๋“ค๋งํ•˜๋ฉด ์•ฑ์˜ ์ฝœ๋“œ ์Šคํƒ€ํŠธ(์บ์‹œ๊ฐ€ ์•ˆ ๋œ ์ƒํƒœ์—์„œ์˜ ์ฒซ ๋กœ๋“œ) ์„ฑ๋Šฅ์ด ํ–ฅ์ƒ๋จ

  • App Routing ์—์„  ๊ธฐ๋ณธ์ ์œผ๋กœ ์™ธ๋ถ€ ํŒจํ‚ค์ง€๋ฅผ ๋ฒˆ๋“ค๋ง

    • serverExternalPackages ์˜ต์…˜์„ ์ด์šฉํ•ด์„œ ํŠน์ • ํŒจํ‚ค์ง€๋ฅผ ์˜ตํŠธ์•„์›ƒ ๊ฐ€๋Šฅ

    • ๋ฐ˜๋Œ€๋กœ Pages Routing์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ์™ธ๋ถ€ ํŒจํ‚ค์ง€๋ฅผ ๋ฒˆ๋“ค๋งํ•˜์ง€ ์•Š๊ณ  transpilePackages ์˜ต์…˜์„ ์‚ฌ์šฉํ•ด์„œ ๋ฒˆ๋“ค๋งํ•  ํŒจํ‚ค์ง€๋ฅผ ์ •์˜ํ•จ

Last updated