1 ๋ถ„ ์†Œ์š”

๐Ÿ“ฑ [PHOBUM] ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ ๋ฐ ์ˆ˜์ • ๊ธฐ๋Šฅ ๊ฐœ์„ 

์ตœ๊ทผ PHOBUM ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ ๋ฐ ์ˆ˜์ • ๊ธฐ๋Šฅ ์ „๋ฐ˜์— ๋Œ€ํ•œ ๋ฆฌํŒฉํ† ๋ง ์ž‘์—…์„ ์ง„ํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค.
์ดˆ๊ธฐ ๊ตฌ์กฐ์—์„œ๋Š” image-upload ํด๋” ๋‚ด๋ถ€์— ๋ชจ๋“  ๋กœ์ง์ด ๋ชฐ๋ ค ์žˆ์–ด ์œ ์ง€๋ณด์ˆ˜์— ์–ด๋ ค์›€์ด ์žˆ์—ˆ๊ณ , ์‚ฌ์šฉ์ž ๊ฒฝํ—˜๋„ ๋ถ€์กฑํ•œ ์ ์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

์ด๋ฒˆ ๊ฐœ์„  ์ž‘์—…์—์„œ๋Š” ์ปดํฌ๋„ŒํŠธ ๊ตฌ์กฐ ๋ถ„๋ฆฌ, ์ƒํƒœ ๊ด€๋ฆฌ ์ตœ์ ํ™”, ๋ Œ๋”๋ง ์„ฑ๋Šฅ ํ–ฅ์ƒ, ๊ทธ๋ฆฌ๊ณ  ์ฆ‰๊ฐ์ ์ธ ์‚ฌ์šฉ์ž ํ”ผ๋“œ๋ฐฑ ์ œ๊ณต์„ ์ค‘์‹ฌ์œผ๋กœ ๊ฐœ์„ ํ–ˆ์Šต๋‹ˆ๋‹ค.


โœ… ์ปดํฌ๋„ŒํŠธ ๊ตฌ์กฐ ๊ฐœ์„ 

๐Ÿ”น CardDetail ์ปดํฌ๋„ŒํŠธ

  • ์ด๋ฏธ์ง€ ์ˆ˜์ • ํ›„ ์ฆ‰์‹œ UI์— ๋ฐ˜์˜๋˜๋„๋ก ์ฒ˜๋ฆฌ
  • useMemo, useCallback์„ ์ ๊ทน ํ™œ์šฉํ•˜์—ฌ ์—ฐ์‚ฐ ์ตœ์ ํ™”
  • ์ƒํƒœ ๋กœ์ง ๋‹จ์ˆœํ™” ๋ฐ ์ฝ”๋“œ ๊ฐ€๋…์„ฑ ํ–ฅ์ƒ

๐Ÿ”น CardModify ์ปดํฌ๋„ŒํŠธ

  • ํŒŒ์ผ ์„ ํƒ ์ฆ‰์‹œ ๋ฏธ๋ฆฌ๋ณด๊ธฐ ์ œ๊ณต
  • ์ €์žฅ ์‹œ์—๋Š” ๋ฐฑ์—”๋“œ์— ๋น„๋™๊ธฐ ์š”์ฒญ โ†’ ๋ฐ˜์˜ ํ›„ ์ƒํƒœ ์—…๋ฐ์ดํŠธ
  • ๋ถˆํ•„์š”ํ•œ ์ƒํƒœ ์ค‘๋ณต ์ œ๊ฑฐ ๋ฐ ์ปดํŒฉํŠธํ•œ ํ๋ฆ„ ๊ตฌ์„ฑ

๐Ÿ”น Album ์ปดํฌ๋„ŒํŠธ

  • Intersection Observer ํ™œ์šฉ โ†’ ๋ณด์ด๋Š” ์ด๋ฏธ์ง€ ์œ„์ฃผ ํ”„๋ฆฌ๋กœ๋”ฉ
  • ์ด๋ฏธ์ง€ ๋ชฉ๋ก ์ƒํƒœ๋ฅผ ๋ถ„๋ฆฌํ•˜์—ฌ ๋ถˆํ•„์š”ํ•œ ์ „์ฒด ๋ Œ๋”๋ง ๋ฐฉ์ง€

๐Ÿ›  ๊ธฐ์ˆ ์  ๊ฐœ์„  ์‚ฌํ•ญ

๐Ÿ“Œ ์ƒํƒœ ๊ด€๋ฆฌ ์ตœ์ ํ™”

  • useCallback, useMemo๋กœ ๋ฆฌ๋ Œ๋”๋ง ์ตœ์†Œํ™”
  • ์ƒํƒœ ์—…๋ฐ์ดํŠธ๋„ ๋ถ€๋ถ„์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜์—ฌ ์„ฑ๋Šฅ ์ตœ์ ํ™”

๐Ÿ“Œ ์ด๋ฏธ์ง€ ์ฒ˜๋ฆฌ ๋ฐฉ์‹ ๋‹จ์ˆœํ™”

const handleModifySave = async (updatedImage: ImageUpdateRequest) => {
  const response = await imagesApi.update(currentImage.id, updatedImage);
  const newImage = {
    ...currentImage,
    ...response.data
  };
  setCurrentImage(newImage);
  onEdit?.(newImage);
};
  • API ์‘๋‹ต ๊ธฐ๋ฐ˜์œผ๋กœ ์ƒํƒœ ๊ฐฑ์‹  โ†’ ์ฆ‰์‹œ ๋ฐ˜์˜
  • ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ์—๋„ ์ฝœ๋ฐฑ์œผ๋กœ ์—…๋ฐ์ดํŠธ ์ „๋‹ฌ

๐Ÿ“Œ ๋ Œ๋”๋ง ๋ฐ ๋ฉ”๋ชจ๋ฆฌ ์ตœ์ ํ™”

  • ์ด๋ฏธ์ง€ ํ”„๋ฆฌ๋กœ๋”ฉ ๋„์ž…
  • cleanup ํ•จ์ˆ˜ ์ถ”๊ฐ€๋กœ ๋ถˆํ•„์š”ํ•œ ๋ฆฌ์Šค๋„ˆ ์ œ๊ฑฐ
  • ์ค‘๋ณต API ํ˜ธ์ถœ ๋ฐฉ์ง€ ๋ฐ ๋ Œ๋”๋ง ํšจ์œจ ๊ฐœ์„  (์•ฝ 20~30% ์„ฑ๋Šฅ ํ–ฅ์ƒ ์ฒด๊ฐ)

๐ŸŽฏ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜ ๊ฐœ์„ 

์ฆ‰๊ฐ์ ์ธ UI ๋ฐ˜์˜

  • ์ˆ˜์ • ์ฆ‰์‹œ ์ด๋ฏธ์ง€ ๊ฐฑ์‹  โ†’ ์‹ค์‹œ๊ฐ„ ํ”ผ๋“œ๋ฐฑ
  • ๋กœ๋”ฉ ์ค‘์—๋Š” ์Šคํ”ผ๋„ˆ ๋˜๋Š” ์ง„ํ–‰ ํ‘œ์‹œ
  • ์˜ค๋ฅ˜ ์‹œ ๋ช…ํ™•ํ•œ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ์ œ๊ณต

์ด๋ฏธ์ง€ ์—…๋กœ๋“œ UX ํ–ฅ์ƒ

  • ์„ ํƒ ์ฆ‰์‹œ ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋กœ ์ด๋ฏธ์ง€ ํ™•์ธ ๊ฐ€๋Šฅ
  • ์—…๋กœ๋“œ ์ค‘ ์‹œ๊ฐ์  ์ƒํƒœ ํ‘œ์‹œ
  • ์ˆ˜์ •/์ €์žฅ/์ทจ์†Œ ๋ฒ„ํŠผ ๋ช…ํ™•ํžˆ ๋ถ„๋ฆฌํ•ด ์ž‘์—… ํ˜ผ๋™ ๋ฐฉ์ง€

๐Ÿ”ญ ํ–ฅํ›„ ๊ฐœ์„  ์˜ˆ์ • ์‚ฌํ•ญ

๊ฐœ์„  ํ•ญ๋ชฉ ์„ธ๋ถ€ ๋‚ด์šฉ
์ด๋ฏธ์ง€ ์ตœ์ ํ™” WebP ์ž๋™ ๋ณ€ํ™˜, ์—…๋กœ๋“œ ์‹œ ์••์ถ•
์บ์‹ฑ ์ „๋žต ํด๋ผ์ด์–ธํŠธยท์„œ๋ฒ„ ์–‘์ชฝ์—์„œ ์ ์šฉ
์„ฑ๋Šฅ ๋ชจ๋‹ˆํ„ฐ๋ง Sentry, React Profiler, Lighthouse ๋“ฑ ์—ฐ๋™
๋ Œ๋”๋ง ๋ถ„์„ ๋ฉ”๋ชจ๋ฆฌ/์‹œ๊ฐ„/๋„คํŠธ์›Œํฌ ์š”์ฒญ ๊ฐœ์„  ๋ชฉํ‘œ

๐Ÿงพ ๊ฒฐ๋ก  ๋ฐ ์ •๋ฆฌ

์ด๋ฒˆ ์ด๋ฏธ์ง€ ๊ธฐ๋Šฅ ๋ฆฌํŒฉํ† ๋ง์„ ํ†ตํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํšจ๊ณผ๋ฅผ ์–ป์—ˆ์Šต๋‹ˆ๋‹ค:

  • ๐Ÿ’ก ์ปดํฌ๋„ŒํŠธ ๊ตฌ์กฐ ๊ฐœ์„  โ†’ ์œ ์ง€๋ณด์ˆ˜์„ฑ ํ–ฅ์ƒ
  • ๐Ÿš€ ๋ Œ๋”๋ง/API ํ˜ธ์ถœ ์„ฑ๋Šฅ ํ–ฅ์ƒ
  • ๐Ÿ™Œ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜ ์ „๋ฐ˜์˜ ์งˆ์  ํ–ฅ์ƒ

๐Ÿ“Œ ๋‹ค์Œ ๋‹จ๊ณ„

  • ๊ธฐ๋Šฅ๋ณ„ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ถ”๊ฐ€
  • ๊ฐœ์„ ๋œ ๋กœ์ง ๊ธฐ๋ฐ˜์œผ๋กœ ๊ธฐ์ˆ  ๋ฌธ์„œํ™”
  • ๋ชจ๋‹ˆํ„ฐ๋ง ํ™˜๊ฒฝ ๊ตฌ์ถ• ๋ฐ ์ง€์†์ ์ธ ์„ฑ๋Šฅ ํŠธ๋ž˜ํ‚น

์ด์ œ๋Š” ๋‹จ์ˆœํžˆ โ€œ์ž‘๋™ํ•˜๋Š” ๊ธฐ๋Šฅโ€์„ ๋„˜์–ด์„œ, ์„ฑ๋Šฅ๊ณผ ๊ฒฝํ—˜ ๋ชจ๋‘๋ฅผ ๋งŒ์กฑ์‹œํ‚ค๋Š” ๊ตฌ์กฐ๋กœ ๋„์•ฝํ–ˆ์Šต๋‹ˆ๋‹ค. PHOBUM์˜ ์ด๋ฏธ์ง€ ์ฒ˜๋ฆฌ ๊ธฐ๋Šฅ์€ ์•ž์œผ๋กœ๋„ ๊ณ„์† ๋ฐœ์ „ํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. ๐Ÿ’ช

์นดํ…Œ๊ณ ๋ฆฌ:

์—…๋ฐ์ดํŠธ:

๋Œ“๊ธ€๋‚จ๊ธฐ๊ธฐ