<aside> ๐Ÿ”

Figma ๋””์ž์ธ ํŒŒ์ผ๊ณผ ์‹ค์ œ ๊ตฌํ˜„๋œ ์›น์‚ฌ์ดํŠธ๋ฅผ ํ”ฝ์…€ ๋‹จ์œ„๋กœ ๋น„๊ตํ•˜๋Š” ์„œ๋น„์Šค์ž…๋‹ˆ๋‹ค. URL๊ณผ Figma ํŒŒ์ผ ๊ฒฝ๋กœ๋ฅผ ์ž…๋ ฅํ•˜๋ฉด ์ž๋™์œผ๋กœ ์Šคํฌ๋ฆฐ์ƒท์„ ์บก์ฒ˜ํ•˜๊ณ , ์˜ค๋ฒ„๋ ˆ์ด/๋ถ„ํ•  ํ™”๋ฉด ๋ชจ๋“œ๋กœ ์ฐจ์ด๋ฅผ ์‹œ๊ฐํ™”ํ•ฉ๋‹ˆ๋‹ค.

</aside>

๐Ÿ‘‰ย ๋ฐ”๋กœ๊ฐ€๊ธฐ

ํ”„๋กœ์ ํŠธ ๊ฐœ์š”

๋””์ž์ด๋„ˆ์™€ ํ˜‘์—…ํ•˜๋ฉด์„œ "๋””์ž์ธ ํŒŒ์ผ๊ณผ ์™„์ „ํžˆ ๋™์ผํ•˜๊ฒŒ ๊ตฌํ˜„ํ–ˆ๋Š”๋ฐ ์™œ ํ”ผ๋“œ๋ฐฑ์ด ์˜ค์ง€?"๋ผ๋Š” ์ƒํ™ฉ์„ ์ž์ฃผ ๊ฒช์—ˆ์Šต๋‹ˆ๋‹ค. Figma๋ฅผ ๋ณด๋ฉด์„œ ์‹ค์ œ ์›น์‚ฌ์ดํŠธ๋ฅผ ๋ˆˆ์œผ๋กœ ๋น„๊ตํ•˜๋Š” ๊ฒƒ์€ ํ•œ๊ณ„๊ฐ€ ๋ช…ํ™•ํ•˜๊ณ , ์Šคํฌ๋ฆฐ์ƒท์„ ์ฐ์–ด์„œ Figma์— ๋ถ™์—ฌ๋„ฃ๊ณ  ๋น„๊ตํ•˜๋Š” ๊ฒƒ๋„ ๋ฒˆ๊ฑฐ๋กญ์Šต๋‹ˆ๋‹ค.

PixelDiff๋Š” ์ด ๊ณผ์ •์„ ์ž๋™ํ™”ํ•ฉ๋‹ˆ๋‹ค. URL๊ณผ Figma ํŒŒ์ผ ๊ฒฝ๋กœ๋ฅผ ์ž…๋ ฅํ•˜๋ฉด ๋‘ ์ด๋ฏธ์ง€๋ฅผ ์ฆ‰์‹œ ๋น„๊ตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ธฐ์ˆ  ์„ ํƒ๊ณผ ์ด์œ 

SSE (Server-Sent Events) ์„ ํƒ

๋ฌธ์ œ:

Figma API ๋ Œ๋”๋ง์ด ํ‰๊ท  20-30์ดˆ, ์ตœ๋Œ€ 55์ดˆ๊นŒ์ง€ ์†Œ์š”๋ฉ๋‹ˆ๋‹ค. ์ด ์‹œ๊ฐ„ ๋™์•ˆ ๋กœ๋”ฉ๋งŒ ๋Œ๋ฉด ์œ ์ €๋Š” ์ž‘์—…์ด ๋ฉˆ์ท„๋‹ค๊ณ  ์˜คํ•ดํ•˜๊ณ  ์ดํƒˆํ•ฉ๋‹ˆ๋‹ค.

๊ณ ๋ คํ•œ ์˜ต์…˜:

์„ ํƒ ์ด์œ :

์„œ๋ฒ„๊ฐ€ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์ง„ํ–‰๋ฅ ์„ ์ „์†กํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋˜๋ฏ€๋กœ ๋‹จ๋ฐฉํ–ฅ ํ†ต์‹ ์œผ๋กœ ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. SSE๋Š” HTTP ์ธํ”„๋ผ๋ฅผ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•˜๊ณ , EventSource API๊ฐ€ ์žฌ์—ฐ๊ฒฐ์„ ์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. WebSocket์€ ์ฑ„ํŒ…์ฒ˜๋Ÿผ ์–‘๋ฐฉํ–ฅ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ์— ์ ํ•ฉํ•˜์ง€๋งŒ ์—ฌ๊ธฐ์„œ๋Š” ์˜ค๋ฒ„์ŠคํŽ™์ž…๋‹ˆ๋‹ค.

const eventSource = new EventSource('/api/render/progress');
eventSource.onmessage = (event) => {
  const { stage, progress } = JSON.parse(event.data);
  setProgressState({ stage, progress });
};

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

Chrome Extension ์„ ํƒ

๋ฌธ์ œ:

  1. iframe ๋‚ด๋ถ€ ์ฝ˜ํ…์ธ  ๋†’์ด๋ฅผ ์•Œ ์ˆ˜ ์—†์Œ (Same-Origin Policy)