๐ŸŒ• F-lab ๋ฉ˜ํ† ๋ง ๊ธฐ๋ก

๋ฉ˜ํ† ๋ง ์ดํ›„ ๋ถ€์กฑํ•œ ๋ถ€๋ถ„์„ ์ฑ„์šฐ๊ธฐ ์œ„ํ•œ ๊ธฐ๋ก

DOM์ด๋ž€?

  • Document Object Model์˜ ์•ฝ์ž๋กœ HTML ๋ฌธ์„œ์˜ ๊ณ„์ธต ๊ตฌ์กฐ์™€ ์ •๋ณด๋ฅผ ํ‘œํ˜„ํ•˜๊ณ  ์ด๋ฅผ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋Š” API(ํ”„๋กœํผํ‹ฐ, ๋ฉ”์„œ๋“œ)๋ฅผ ์ œ๊ณตํ•˜๋Š” ํŠธ๋ฆฌ ์ž๋ฃŒ๊ตฌ์กฐ

SPA๋ž€?

  • Single Page Application์˜ ์•ฝ์ž๋กœ ์–ด๋–ค ์›น ์‚ฌ์ดํŠธ์˜ ์ „์ฒด ํŽ˜์ด์ง€๋ฅผ ํ•˜๋‚˜์˜ ํŽ˜์ด์ง€์— ๋‹ด์•„ ๋™์ ์œผ๋กœ ํ™”๋ฉด์„ ๋ฐ”๊ฟ”๊ฐ€๋ฉฐ ํ‘œํ˜„ํ•˜๋Š” ๊ฒƒ
  • ๊ณผ๊ฑฐ ์›น ์‚ฌ์ดํŠธ์˜ ๊ทœ๋ชจ๊ฐ€ ์ž‘์„ ๋•Œ, ์–ด๋–ค ์š”์†Œ๋ฅผ ํด๋ฆญ ์‹œ ์„œ๋ฒ„์—์„œ ๋งค๋ฒˆ ์ „์ฒด html ํŒŒ์ผ์„ ์ „์†กํ•ด์ฃผ์—ˆ๋‹ค.
  • ๊ทธ๋Ÿฌ๋‚˜ ์ ์  ์›น ์‚ฌ์ดํŠธ์˜ ๊ทœ๋ชจ๊ฐ€ ์ปค์ง€๋ฉด์„œ ์š”์†Œ ํ•˜๋‚˜๋ฅผ ๋ณ€๊ฒฝํ•˜๊ธฐ ์œ„ํ•ด ์ „์ฒด๋ฅผ ๋ณด๋‚ด๋Š” ๊ฒƒ์ด ๋„ˆ๋ฌด ๋น„ํšจ์œจ์ 
  • ๊ทธ๋ž˜์„œ ๋“ฑ์žฅํ•œ ๊ฒƒ์ด SPA

SPA์—์„œ SEO๊ฐ€ ๋™์ž‘ํ•˜๊ธฐ ์–ด๋ ค์šด ์ด์œ ?

  • ํ•˜๋‚˜์˜ ํŽ˜์ด์ง€์— ์—ฌ๋Ÿฌ ํŽ˜์ด์ง€๋ฅผ ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ์—์„œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ๊ตฌํ˜„(Client Side Rendering; CSR)ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ฝ์ง€ ๋ชปํ•˜๋Š” ๊ฒ€์ƒ‰ ์—”์ง„์— ๋Œ€ํ•ด์„œ๋Š” ํฌ๋กค๋ง์ด ๋˜์ง€ ์•Š์•„ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

SEO๋ž€?

  • Search Engine Opimization์˜ ์•ฝ์ž๋กœ ๋ง ๊ทธ๋Œ€๋กœ ๊ฒ€์ƒ‰ ์—”์ง„์— ์ตœ์ ํ™”ํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.
  • ์œ„์˜ SPA์˜ ๊ฒฝ์šฐ ๊ฒ€์ƒ‰ ์—”์ง„์— ๋…ธ์ถœ๋˜๊ธฐ ์–ด๋ ต๊ธฐ์— ๊ฒ€์ƒ‰ ์—”์ง„์— ์ตœ์ ํ™”ํ•˜๋Š” ๋ฐฉ๋ฒ•๋“ค์ด ์กด์žฌํ•œ๋‹ค.
    • (1) SSR(Server Side Rendering)์œผ๋กœ ๊ตฌ์ถ•ํ•˜๊ธฐ
      • SPA์ด๋ฉด์„œ SSR ๋ฐฉ์‹์œผ๋กœ ์‚ฌ์ดํŠธ๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅ
        • React์˜ Next.js
        • Vue์˜ Nuxt
        • Angular์˜ Angular Universal
    • (2) ๋™์  ๋ Œ๋”๋ง(Dynamic Rendering)
      • ์ด๋ฏธ CSR ๋ฐฉ์‹์œผ๋กœ SPA๋ฅผ ๊ตฌํ˜„ํ•œ ๊ฒฝ์šฐ ์‚ฌ์šฉ
      • ์„œ๋ฒ„์—์„œ ์š”์ฒญํ•˜๋Š” ์ฃผ์ฒด๊ฐ€ ์‚ฌ๋žŒ์ธ์ง€, ํฌ๋กค๋Ÿฌ์ธ์ง€ ๊ตฌ๋ถ„
        • ์‚ฌ๋žŒ: HTML๊ณผ JS๋ฅผ ์ œ๊ณต
        • ํฌ๋กค๋Ÿฌ: ๋ Œ๋”๋ง๋œ HTML ๋ฒ„์ „์˜ ํŽ˜์ด์ง€๋ฅผ ์ œ๊ณต
      • react-helmet, prerender-spa-plugin, prerender.io, puppeteer, rendertron ๋“ฑ์ด ์žˆ๋‹ค.
    • (3) History API
      • SPA๋Š” ์›น ์‚ฌ์ดํŠธ ์ฃผ์†Œ๊ฐ€ ๋ฐ”๋€Œ์ง€ ์•Š๊ธฐ์—, SPA์ด์ง€๋งŒ ์ฃผ์†Œ๋ฅผ ๋ถ€์—ฌํ•˜๋Š” ๊ธฐ๋Šฅ

inline, block, inline-block ์ฐจ์ด

inline

  • ์ „ํ›„ ์ค„๋ฐ”๊ฟˆ ์—†์ด ํ•œ ์ค„์— ๋ฐฐ์น˜
  • width์™€ height ์†์„ฑ์„ ์ง€์ •ํ•ด๋„ ๋ฌด์‹œ๋จ(ํ•ด๋‹น ํƒœ๊ทธ์˜ ์ปจํ…์ธ  ํฌ๊ธฐ ๋งŒํผ ๊ณต๊ฐ„์„ ์ฐจ์ง€ํ•˜๊ธฐ ๋•Œ๋ฌธ)
  • margin๊ณผ padding ์‹œ ์ขŒ์šฐ ๊ฐ„๊ฒฉ๋งŒ ๋ฐ˜์˜(์ƒํ•˜ ๊ฐ„๊ฒฉ์€ ๋ฐ˜์˜๋˜์ง€ ์•Š์Œ)
  • span, a, em ๋“ฑ

block

  • ์ „ํ›„ ์ค„๋ฐ”๊ฟˆ์ด ์žˆ์–ด ๋งˆ์น˜ ์ƒ์ž๋ฅผ ์Œ“๋“ฏ์ด ๋ณธ์ธ์ด ํ•œ ์ค„์„ ์ฐจ์ง€ํ•จ
  • width, height, margin, padding ๋ชจ๋‘ ๋ฐ˜์˜๋จ
  • div, p, , h1~6 ๋“ฑ

inline-block

  • ๊ธฐ๋ณธ์ ์œผ๋กœ inline๊ณผ ๊ฐ™์ด ์ „ํ›„ ์ค„๋ฐ”๊ฟˆ ์—†์ด ํ•œ์ค„์— ๋ฐฐ์น˜
  • block์ฒ˜๋Ÿผ width, height, margin, padding ๋ชจ๋‘ ๋ฐ˜์˜๋จ
  • ์ฆ‰, ๋‚ด๋ถ€์ ์œผ๋กœ๋Š” block์ด์ง€๋งŒ ์™ธ๋ถ€์ ์œผ๋กœ๋Š” inline
  • button, input, select ๋“ฑ

์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง, ์ด๋ฒคํŠธ ์บก์ฒ˜๋ง

์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง

  • ์ž์‹ ํƒœ๊ทธ(๋…ธ๋“œ)์— ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒ ์‹œ, ๊ทธ ์ด๋ฒคํŠธ๊ฐ€ ๋ถ€๋ชจ ํƒœ๊ทธ๋กœ ์˜ฌ๋ผ๊ฐ€๋ฉฐ ์ด๋ฒคํŠธ๊ฐ€ ์ „๋‹ฌ๋˜๋Š” ํ˜„์ƒ
  • ๋‹จ, focus์™€ ๊ฐ™์ด ๋ฒ„๋ธ”๋ง๋˜์ง€ ์•Š๋Š” ์ด๋ฒคํŠธ๋„ ์กด์žฌ. ๊ทธ๋Ÿฌ๋‚˜ ๊ฑฐ์˜ ๋ชจ๋“  ์ด๋ฒคํŠธ๋Š” ๋ฒ„๋ธ”๋ง์ด ์ผ์–ด๋‚œ๋‹ค.
  • body ํƒœ๊ทธ ๋ฟ ์•„๋‹ˆ๋ผ, html ํƒœ๊ทธ ์‹ฌ์ง€์–ด document ๊ฐ์ฒด๋ฅผ ๋งŒ๋‚  ๋•Œ ๊นŒ์ง€ ๋ชจ๋“  ๋…ธ๋“œ์—์„œ ๋ฐœ์ƒํ•˜๋ฉฐ ๋ช‡๋ช‡ ์ด๋ฒคํŠธ๋Š” window ๊ฐ์ฒด๊นŒ์ง€ ๊ฑฐ์Šฌ๋Ÿฌ ์˜ฌ๋ผ๊ฐ€๊ธฐ๋„ ํ•œ๋‹ค.

์ด๋ฒคํŠธ ์บก์ฒ˜๋ง

  • ์ด๋ฒคํŠธ๊ฐ€ ํ•˜์œ„ ์š”์†Œ๋กœ ์ „ํŒŒ๋˜๋Š” ๊ฒƒ
  • ์‹ค์ œ๋กœ ์ด๋ฒคํŠธ๊ฐ€ ์ผ์–ด๋‚˜๋Š” ๋‹จ๊ณ„๋Š”
    • (1) ์บก์ฒ˜๋ง ๋‹จ๊ณ„(๋ถ€๋ชจ์—์„œ ์ž์‹๋…ธ๋“œ๋กœ ์ด๋ฒคํŠธ๊ฐ€ ์ „๋‹ฌ๋จ)
    • (2) ํƒ€๊ฒŸ ๋‹จ๊ณ„(์ด๋ฒคํŠธ ํƒ€๊ฒŸ์—์„œ ์ด๋ฒคํŠธ ๋ฐœ์ƒ)
    • (3) ๋ฒ„๋ธ”๋ง ๋‹จ๊ณ„(์ž์‹์—์„œ ๋ถ€๋ชจ๋…ธ๋“œ๋กœ ์ด๋ฒคํŠธ ์ „๋‹ฌ๋จ)
  • ์ผ๋ฐ˜์ ์œผ๋กœ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ์—์„œ ์บก์ฒ˜๋ง ๋‹จ๊ณ„๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋น„ํ™œ์„ฑํ™”({capture: false})๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์บก์ฒ˜๋ง์€ ์ •๋ง ์›ฌ๋งŒํ•˜๋ฉด ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค.

event.stopPropagation()๊ณผ event.preventDefault()

event.stopPropagation()

  • ํŠน์ • ๋…ธ๋“œ์—์„œ ์ด๋ฒคํŠธ ๋ฒ„๋ธ”๋ง์„ ์ค‘๋‹จ์‹œํ‚ฌ ๋•Œ ์‚ฌ์šฉ
  • event.stopImmediatePropagation(): ํŠน์ • ์ด๋ฒคํŠธ๋ฟ ์•„๋‹ˆ๋ผ, ํ•ด๋‹น ์š”์†Œ์— ํ• ๋‹น๋œ ๋ชจ๋“  ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ์˜ ๋™์ž‘๋„ ๋ง‰์„ ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.
  • โญ ์ •๋ง ํŠน์ˆ˜ํ•œ ์ƒํ™ฉ์ด ์•„๋‹ˆ๋ผ๋ฉด ๋ฒ„๋ธ”๋ง์„ ๋ง‰๋Š” ํ–‰์œ„๋Š” ์ง€์–‘ํ•  ๊ฒƒ! ๋ฒ„๋ธ”๋ง์„ ๋ง‰์•˜๋‹ค๊ฐ€ ์ถ”ํ›„์— ์ƒ์œ„ ๋…ธ๋“œ์—์„œ ์ด๋ฒคํŠธ๋ฅผ ์ถ”๊ฐ€ํ•  ์ผ์ด ์ƒ๊ธธ ๋•Œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

event.preventDefault()

  • ๋ธŒ๋ผ์šฐ์ €์˜ ๊ธฐ๋ณธ ๋™์ž‘์„ ์ทจ์†Œํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ๋ฉ”์„œ๋“œ

์ด ๋‘˜์˜ ์ฐจ์ด์— ๋Œ€ํ•ด์„œ๋Š” ์ฐธ๊ณ ์—์„œ ๋” ์ž์„ธํžˆ ๋ณด๋Š” ๊ฒƒ์„ ์ถ”์ฒœ!

๊ฐ€์ƒ DOM

  • DOM์€ ์›น ํŽ˜์ด์ง€๋ฅผ ์ด๋ฃจ๋Š” HTMLํƒœ๊ทธ๋ฅผ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์ด์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ๋” ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ํŠธ๋ฆฌ๊ตฌ์กฐ๋กœ ๋งŒ๋“  ๊ฐ์ฒด ๋ชจ๋ธ
  • ์›น์˜ ๊ทœ๋ชจ๊ฐ€ ์ปค์ง€๋ฉด์„œ ๊ทธ ๋•Œ ๊ทธ ๋•Œ DOM์— ์ง์ ‘ ์ ‘๊ทผํ•˜์—ฌ ๋ณ€ํ™”๋ฅผ ์ฃผ๊ฒŒ ๋˜๋ฉด ์„ฑ๋Šฅ ์ด์Šˆ๊ฐ€ ๋ฐœ์ƒ
  • DOM ์ž์ฒด๋Š” ๋น ๋ฅด์ง€๋งŒ, ์›น ๋ธŒ๋ผ์šฐ์ € ๋‹จ์—์„œ DOM์˜ ๋ณ€ํ™”์— ๋”ฐ๋ผ ๋žœ๋”๋งํ•˜๋Š” ๊ณผ์ •์—์„œ ์‹œ๊ฐ„์ด ๋” ์†Œ๋ชจ๋˜๋Š” ๊ฒƒ

์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋“ฑ์žฅํ•œ ๊ฒƒ์ด ๊ฐ€์ƒ DOM!!!

์˜ˆ์‹œ) ๋ฆฌ์•กํŠธ์—์„œ ๊ฐ€์ƒ DOM์„ ๋ฐ˜์˜ํ•˜๋Š” ์ ˆ์ฐจ

  • ๋ฐ์ดํ„ฐ ์—…๋ฐ์ดํŠธ ์‹œ, ์ „์ฒด UI๋ฅผ ๊ฐ€์ƒ DOM์— ๋ฆฌ๋žœ๋”๋ง
  • ์ด์ „ ๊ฐ€์ƒ DOM๊ณผ ํ˜„์žฌ์˜ ๊ฐ€์ƒ DOM์„ ๋น„๊ต(๊ฐ์ฒด์˜ ๋น„๊ต -> ๋ถˆ๋ณ€ ๊ฐ์ฒด๊ฐ€ ์ค‘์š”ํ•œ ์ด์œ )
  • ๋ณ€ํ™”ํ•œ ๋ถ€๋ถ„๋งŒ ์‹ค์ œ DOM์— ์ผ๊ด„ ์—…๋ฐ์ดํŠธ -> ๋ ˆ์ด์•„์›ƒ ๊ณ„์‚ฐ์ด ํ•œ๋ฒˆ์— ํ•œ๋ฒˆ๋งŒ ์ด๋ค„์ง
  • ์ฆ‰, ์ž‘์€ ๊ทœ๋ชจ์˜ DOM ๋ณ€ํ™”๊ฐ€ ์—ฌ๋Ÿฌ๋ฒˆ ์ผ์–ด๋‚˜๋Š” ๊ฒƒ๋ณด๋‹ค ํฐ ๊ทœ๋ชจ์˜ ๋ ˆ์ด์•„์›ƒ ๋ณ€ํ™”๋ฅผ ํ•œ ๋ฒˆ ๋ฐœ์ƒ์‹œํ‚ด์œผ๋กœ์จ ์„ฑ๋Šฅ ํ–ฅ์ƒ์„ ๊ธฐ๋Œ€ํ•  ์ˆ˜ ์žˆ๋‹ค.

JSON

  • JavaScript Object Notation์˜ ์•ฝ์ž๋กœ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ๊ฐ์ฒด ํ˜•ํƒœ๋ฅผ ์˜๋ฏธ
  • ์‚ฌ๋žŒ๊ณผ ์ปดํ“จํ„ฐ๊ฐ€ ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๊ณ  ์šฉ๋Ÿ‰์ด ์ž‘์•„ ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•  ๋•Œ, XML์ด ์•„๋‹Œ JSON ํ˜•ํƒœ๋ฅผ ์ฃผ๋กœ ์‚ฌ์šฉํ•œ๋‹ค.
  • ํŠน์ • ์–ธ์–ด์— ์ข…์†๋˜์ง€ ์•Š๊ณ , ๋ชจ๋“  ์–ธ์–ด์—์„œ JSON ๋ฐ์ดํ„ฐ๋ฅผ ํ•ธ๋“ค๋งํ•  ์ˆ˜ ์žˆ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

์ตœ์ ํ™”๋œ ์›น์‚ฌ์ดํŠธ๋ฅผ ๋งŒ๋“œ๋Š”๋ฐ ์ ์ ˆํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์›น์‚ฌ์ดํŠธ๊ฐ€ ๋กœ๋“œ๋  ๋•Œ, HTML๊ณผ CSS๋Š” ๋™์‹œ์— ํŒŒ์‹ฑ๋˜์–ด ๊ฐ๊ฐ DOM๊ณผ CSSOM์„ ๋งŒ๋“ค๊ฒŒ ๋˜๋Š”๋ฐ, ์›น์‚ฌ์ดํŠธ์˜ ์‹œ๊ฐ์  ์š”์†Œ๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋‘ ๊ฐ€์ง€ ๋ชจ๋‘ ํ•„์š”ํ•˜๋‹ค. HTML๊ณผ CSS๊ฐ€ ํŒŒ์‹ฑ๋˜๋ฉฐ first meanigful paint๋ฅผ ํ•˜๊ฒŒ ๋œ๋‹ค.
(first meaningful paint๋Š” ์‚ฌ์ดํŠธ์˜ ์„ฑ๋Šฅ ์ง€ํ‘œ ์ค‘ ํ•˜๋‚˜์ด๋‹ค.)
์ฆ‰, ๋ฌธ์„œ ์ตœํ•˜๋‹จ์— stylesheet link๋ฅผ ๋‘๋Š” ๊ฒƒ์€ ์ด๋Ÿฐ ์„ฑ๋Šฅ์„ ๋–จ์–ด๋œจ๋ฆฌ๋Š” ์š”์ธ์ด ๋œ๋‹ค.

(์ถ”๊ฐ€) ๋ฐ˜์‘ํ˜• vs ์ ์‘ํ˜•

๋ฐ˜์‘ํ˜•

  • ํ•˜๋‚˜์˜ ํ…œํ”Œ๋ฆฟ์—์„œ ๋ฏธ๋””์–ด ์ฟผ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํฌ๊ธฐ ๋ณ€๊ฒฝ ์‹œ ๊ทธ ํฌ๊ธฐ์— ๋ฐ˜์‘ํ•ด์„œ ์ž‘๋™ํ•˜๋„๋ก ํ•˜๋Š” ์›น์‚ฌ์ดํŠธ
  • ์–ด๋–ค ๊ธฐ๊ธฐ๋“  ๋ชจ๋“  ์ปจํ…์ธ ๋ฅผ ๋‹ค์šด๋กœ๋“œ ํ›„ ๋ฏธ๋””์–ด ์ฟผ๋ฆฌ์— ๋”ฐ๋ผ ์กฐ์ ˆํ•˜๋ฏ€๋กœ ์†๋„๊ฐ€ ๋Š๋ฆฌ๋‹ค.

์ ์‘ํ˜•

  • ์ผ์ • ํ™”๋ฉด ํฌ๊ธฐ์— ๋งž๊ฒŒ ๊ฐ๊ฐ ๋‹ค๋ฅธ ํ…œํ”Œ๋ฆฟ์„ ์ ์šฉํ•จ์œผ๋กœ์จ ๊ฐ๊ฐ์˜ ํ™”๋ฉด ํฌ๊ธฐ์— ๋Œ€์‘ํ•  ์ˆ˜ ์žˆ๋Š” ์›น์‚ฌ์ดํŠธ
  • ์—ฌ๋Ÿฌ ํ…œํ”Œ๋ฆฟ์„ ์ค€๋น„ํ•ด๋‘๊ณ  ์• ์ดˆ์— ํ•ด๋‹น ๊ธฐ๊ธฐ์˜ ์ •๋ณด๋ฅผ ์„œ๋ฒ„ ํ˜น์€ ๋ธŒ๋ผ์šฐ์ €์—์„œ ๊ฐ์ง€ํ•˜์—ฌ ๊ธฐ๊ธฐ์— ๋งž๋Š” ํ…œํ”Œ๋ฆฟ, ์ปจํ…์ธ ๋งŒ ๋‹ค์šด๋กœ๋“œํ•˜๋ฏ€๋กœ ์†๋„๊ฐ€ ๋น ๋ฅด๋‹ค.