๐Ÿš€ [React] windowing ๊ธฐ๋ฒ•์„ ํ†ตํ•œ ์„ฑ๋Šฅ ์ตœ์ ํ™” feat.react-virtualized


DOM์— ๊ทธ๋ฆด ์—˜๋ฆฌ๋จผํŠธ๊ฐ€ ๋งค์šฐ๋งค์šฐ ๋งŽ์„ ๋•Œ ์™œ ๋ธŒ๋ผ์šฐ์ €์˜ ์„ฑ๋Šฅ์€ ์•ˆ์ข‹์•„์งˆ๊นŒ?

๋ฌธ์ œ ์ƒํ™ฉ

๊ฒ€์ƒ‰์–ด๋ฅผ ์ž…๋ ฅํ•  ์ˆ˜ ์žˆ๋Š” input๊ณผ ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ๊ฐ€ dropdown ๋‚ด๋ถ€์— ๋ณด์—ฌ์ง€๋Š” ์ปดํฌ๋„ŒํŠธ์—์„œ, ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ๊ฐ€ ๋งŽ์„ ๊ฒฝ์šฐ(1000๋ช… ์ด์ƒ) ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋ˆˆ์— ๋„๊ฒŒ ๋Š๋ ค์ง€๋ฉฐ ์‚ฌ์šฉ์ž์˜ ์ธํ„ฐ๋ ‰์…˜์— ์˜ํ•œ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ๊ฐ€ ๋งค์šฐ ๋Š๋ ค์ง€๋Š” ํ˜„์ƒ์ด ๋ฐœ์ƒํ–ˆ๋‹ค.

Input์— ํฌ์ปค์Šค๊ฐ€ ์žกํžˆ๋Š” ์†๋„, ๊ฒ€์ƒ‰์–ด ์ž…๋ ฅ ํ›„ ๋ฐ˜์˜๋˜๋Š” ์†๋„, ์ž…๋ ฅ์ด ์™„๋ฃŒ๋œ ์ดํ›„ ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜์˜ํ•˜๋Š” ์†๋„(์ด๊ฑด ๋„ˆ๋ฌด ๋Š๋ ค์„œ ์•„์˜ˆ ๊ฒฐ๊ณผ๋„ ๋ณด์—ฌ์ง€์ง€ ์•Š์•˜์Œ)๊ฐ€ ๋งค์šฐ ๋Š๋ ธ๋Š”๋ฐ, ์ฒ˜์Œ ํ•ด๋‹น ๋ฌธ์ œ๋ฅผ ๋งˆ์ฃผํ–ˆ์„ ๋–„๋Š” DOM์— ๋ถ™์€ ์—˜๋ฆฌ๋จผํŠธ 1000๊ฐœ๋Š” ์ปดํ“จํ„ฐ ์ž…์žฅ์—์„œ ๊ทธ๋ ‡๊ฒŒ ๋งŽ์€ ๊ฒƒ๋„ ์•„๋‹ํ…๋ฐ ๋„๋Œ€์ฒด ์™œ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ(์ธํ„ฐ๋ ‰์…˜)์ด ์ด๋ ‡๊ฒŒ๊นŒ์ง€ ๋Š๋ ค์กŒ์ง€? ๋ผ๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ๋‹ค.

์ธก์ •ํ•  ์ˆ˜ ์—†์œผ๋ฉดโ€ฆ

์šฐ์„  ์–ด๋–ค ์ƒํ™ฉ์ธ์ง€ ์ •ํ™•ํ•˜๊ฒŒ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ํฌ๋กฌ ๊ฐœ๋ฐœ์ž๋„๊ตฌ๋ฅผ ์—ด์—ˆ๋‹ค.

์ธก์ • ๋„๊ตฌ: chorme dev tools - lighthouse, performance
๋ฐ์ดํ„ฐ ๊ฐœ์ˆ˜(dropdown item): ์•ฝ 1,300๊ฐœ
์‹œ๋‚˜๋ฆฌ์˜ค: 
์ฒซ ๋ Œ๋”๋ง ์ดํ›„ input ํด๋ฆญ > ๋“œ๋กญ๋‹ค์šด์ด ์—ด๋ฆฌ๋ฉด ๊ฒ€์ƒ‰์–ด ์ž…๋ ฅ > ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ ๊ธฐ๋‹ค๋ฆฐ ํ›„ ์ข…๋ฃŒ

ํฌ๋กฌ ๊ฐœ๋ฐœ์ž ๋„๊ตฌ - Lighthouse๋ฅผ ํ†ตํ•ด ์ธก์ •ํ•œ ๋ณด๊ณ ์„œ lighthouse-before.html.zip

๋ญ”์ง„ ์ž˜ ๋ชฐ๋ผ๋„ ์ผ๋‹จ ํ™”๋ฉด์ด ๋Š๋ฆฌ๊ตฌ๋‚˜~ 9์ดˆ ์ •๋„ ์ง€์—ฐ์ด ์žˆ์—ˆ๊ฒ ๊ตฌ๋‚˜~ ๋ฅผ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

veryveryslow

๐Ÿง€ tl;dr

๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ๋“œ๋กญ ๋‹ค์šด์— 1000๊ฐœ ์ด์ƒ์˜ ๋ชฉ๋ก์„ ๊ทธ๋ฆฌ๊ฒŒ ๋˜๋ฉฐ DOM์— ๋ถ™์€ ์—˜๋ฆฌ๋จผํŠธ๋“ค์ด ๋งค์šฐ ๋งŽ์•„์ง€๊ณ , ์ด์— ๋”ฐ๋ผ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์‹คํ–‰ํ•ด์•ผ ํ•˜๋Š” ์Šคํฌ๋ฆฝํŠธ์˜ ์–‘์ด ์–ด๋งˆ๋ฌด์‹œํ•˜๊ฒŒ ์ฆ๊ฐ€ํ•จ.

๋ฌผ๋ก  ๊ทธ๋ƒฅ ํ…์ŠคํŠธ๋งŒ ๋“ค์–ด์žˆ๋Š” div ํƒœ๊ทธ๋ผ๋ฉด 1,000๊ฐœ๋“  2,000๊ฐœ๋“  ๊ทธ๋ ‡๊ฒŒ ๋ฌด๊ฑฐ์šด ์ž‘์—…์ด ์•„๋‹ˆ์ง€๋งŒ,

  • ๋“œ๋กญ๋‹ค์šด์œผ๋กœ ์—ด๋ฆฌ๋Š” ๋ฉ”๋‰ด ๋‚ด๋ถ€์˜ ์•„์ดํ…œ์ด๋ฏ€๋กœ ๋‹ค๋ฅธ ๊ฒฝ์šฐ์— ๋น„ํ•ด ์—ฐ์‚ฐํ•  ๊ฒƒ์ด ๋” ๋งŽ์Œ
  • Dropdown Item์—์„œ Text๋งŒ ์กด์žฌํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ทธ๋ฆฌ๊ณ  ์žˆ์Œ
    • <div>{item.name}<div>๋งŒ ๊ทธ๋ฆด ๊ฒฝ์šฐ ์ธํ„ฐ๋ž™์…˜ ์ง€์—ฐ์ด ํฌ๊ฒŒ ์—†์Œ justText

      ์—ฌ๊ธฐ์„œ CSS๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜, ์กฐ๊ธˆ๋งŒ ๋” ๋ฌด๊ฒ๊ฒŒ ๊ตฌ์„ฑํ•ด๋„ ๋ฐ”๋กœ ์ง€์—ฐ ์‹œ๊ฐ„์ด ๋Š˜์–ด๋‚˜๋Š” ๊ฒƒ๋„ ํ™•์ธํ–ˆ๋‹ค.

๊ฐ๊ฐ์˜ ์„ฑ๋Šฅ ์ธก์ • ์ง€ํ‘œ๋ฅผ ์กฐ๊ธˆ ๋” ์‚ดํŽด๋ณด์ž!

Total Blocking Time(TBT)

TBT๋Š” ๋งˆ์šฐ์Šค ํด๋ฆญ, ํ™”๋ฉด ํƒญ ๋˜๋Š” ํ‚ค๋ณด๋“œ ๋ˆ„๋ฆ„๊ณผ ๊ฐ™์€ ์‚ฌ์šฉ์ž ์ž…๋ ฅ์œผ๋กœ๋ถ€ํ„ฐ ํŽ˜์ด์ง€๊ฐ€ ์‘๋‹ตํ•˜์ง€ ๋ชปํ•˜๋„๋ก ์ฐจ๋‹จ๋œ ์ด ์‹œ๊ฐ„์„ ์ธก์ •ํ•ฉ๋‹ˆ๋‹ค.

tbt

scripting ์ž‘์—…์œผ๋กœ ๋ถ„๋ฅ˜๋˜๋Š” Script Evaluation ์ž‘์—…์œผ๋กœ ์ธํ•ด Input์˜ ์ธํ„ฐ๋ ‰์…˜์ด ์ง€์—ฐ๋˜๊ณ  ์žˆ๋Š” ์ƒํ™ฉ

Interaction to Next Paint (INP)

INP๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ํŽ˜์ด์ง€์—์„œ ์ˆ˜ํ–‰ํ•œ ๋ชจ๋“  ์ƒํ˜ธ ์ž‘์šฉ์˜ ๋Œ€๊ธฐ ์‹œ๊ฐ„์„ ๊ด€์ฐฐํ•˜๊ณ  ๋ชจ๋“ (๋˜๋Š” ๊ฑฐ์˜ ๋ชจ๋“ ) ์ƒํ˜ธ ์ž‘์šฉ์ด ์•„๋ž˜์— ์žˆ๋Š” ๋‹จ์ผ ๊ฐ’์„ ๋ณด๊ณ ํ•ฉ๋‹ˆ๋‹ค.

  • ์ข‹์€ INP๋Š”?
![inpStandard](https://user-images.githubusercontent.com/89910087/231199303-fa9cb995-b83a-4d8c-9368-fab4114a258e.png)

poorInp

์œ„ ๊ธ€์— ๋”ฐ๋ฅด๋ฉด 500ms ๋งŒ ๋„˜์–ด๋„ POOR Responsiveness๋ผ๋Š”๋ฐ ์—ฌ๊ธฐ๋Š” ๋ฌด๋ ค 6,400ms..

๋ณด๊ณ ์„œ์— ๋”ฐ๋ฅด๋ฉด ๊ฐ€์žฅ ๋งŽ์€ ๋ณ‘๋ชฉ์ด ์ผ์–ด๋‚˜๊ณ  ์žˆ๋Š” ๋ถ€๋ถ„์ด Scripting ์ž‘์—…, ์ •ํ™•ํ•˜๊ฒŒ๋Š” Script Evaluation ์ž‘์—…์ด๋‹ค. ์ด๋กœ ์ธํ•ด Input์˜ ์ด๋ฒคํŠธ๊ฐ€ ์ง€์—ฐ๋˜๊ณ  ์žˆ๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ๊ฒ ๋‹ค.

poor-perfomance-crop

๊ทธ๋ ‡๋‹ค๋ฉด Script Evaluation ์ž‘์—…์„ ์ค„์ธ๋‹ค๋ฉด ์ธํ„ฐ๋ ‰์…˜ ์ง€์—ฐ๋„ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ํ•ด๊ฒฐ ๋  ๊ฒƒ ๊ฐ™๋‹ค!

  • Script evaluation์ด ๋ญ˜ ํ•˜๋Š” ์ž‘์—…์ธ๋ฐ?

    GPT์—๊ฒŒ ๋ฌผ์–ด๋ดค์Šต๋‹ˆ๋‹ค.

    ์Šคํฌ๋ฆฝํŠธ ํฌ๊ธฐ๊ฐ€ ๋งค์šฐ ํด ๊ฒฝ์šฐ script evaluation ์ž‘์—…์— ๋งค์šฐ ๋งŽ์€ ์‹œ๊ฐ„์ด ์†Œ์š”๋˜๋ฏ€๋กœ ํŽ˜์ด์ง€๊ฐ€ ๋Š๋ ค์งˆ ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

    gpt-script-evaluation

  • ๊ทธ๋ž˜์„œ ์ตœ์ ํ™”๊ฐ€ ๊ฐ€๋Šฅํ•ด?

    • ๋„ค, ์—ฌ๊ธฐ์—์„œ ๋งค์šฐ ๋งŽ๊ณ  ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์„ ์†Œ๊ฐœํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค!
    • ์ถ”๊ฐ€๋กœ, ์ด์นœ๊ตฌ๋„ ๋‹ต๋ณ€ ์•„์ฃผ ์ž˜ ํ•ด์ค๋‹ˆ๋‹ค. ์ œ์ผ ์ฒ˜์Œ์œผ๋กœ ์†Œ๊ฐœํ•˜๋Š” ๋ฐฉ๋ฒ•์ด Limiting the number of DOM elements ๋„ค์š”.

    gpt-improve-method

๋ชฉํ‘œ๋Š”

๊ฐ•์˜์ž ๊ฒ€์ƒ‰ ํด๋ฆญ ์‹œ ๋“œ๋กญ๋‹ค์šด์ด ์ง€์ฒด ์—†์ด ๊ทธ๋ ค์ง€๊ณ  ์ดํ›„ ๊ฒ€์ƒ‰์–ด๋ฅผ ์ž…๋ ฅํ•  ๋•Œ๋„ ์‚ฌ์šฉ์ž ์ž…์žฅ์—์„œ ๋ณ„๋„์˜ ์ง€์—ฐ์„ ๋Š๋ผ์ง€ ์•Š๋„๋ก INP์‹œ๊ฐ„์„ ๊ฐœ์„ ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

  • 1์ฐจ ๋ชฉํ‘œ: 500ms ์ดํ•˜์˜ interection latency
  • 2์ฐจ ๋ชฉํ‘œ: 200ms ์ดํ•˜์˜ interection latency

๋ณธ๊ฒฉ์ ์œผ๋กœ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ด๋ณด์ž

์œ„ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ณ  ํ”„๋กœ์ ํŠธ ๋ชฉํ‘œ๋ฅผ ๋‹ฌ์„ฑํ•˜๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ๊ฒƒ์€ ๋ฌด์—‡์ธ๊ฐ€์š”?


์œ„์—์„œ ์‚ดํŽด๋ดค๋˜ TBT๋ฅผ ๊ฐœ์„ ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋ฌด์—‡์ด ์žˆ์„๊นŒ? ๊ณต์‹ ๋ฌธ์„œ์— ๋”ฐ๋ฅด๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ๋ฐฉ์•ˆ์„ ์ œ์‹œํ•œ๋‹ค.

improveTBT

๋ถˆํ•„์š”ํ•œ JS ๋กœ๋”ฉ ๋ฐ ์‹คํ–‰??ย ยป> windowing!

๊ณต์‹ ๋ฌธ์„œ - ์„ฑ๋Šฅ ์ตœ์ ํ™” ํŒŒํŠธ์—์„œ๋„ Windowing ๊ธฐ๋ฒ•(List Virtualization์ด๋ผ๊ณ ๋„ ํ•จ)์„ ์†Œ๊ฐœํ•˜๊ณ  ์žˆ๋‹ค.

windowing ์ด๋ž€?

concept of only rendering or write the visible portion in the currentย โ€œwindowโ€ to theย DOM. The number of items that rendered at first time are smaller than the original one.

๊ทธ๋ ค์•ผ ํ•  ์—˜๋ฆฌ๋จผํŠธ๊ฐ€ ์•„๋ฌด๋ฆฌ ๋งŽ์•„๋„ ์‹ค์ œ๋กœ DOM์— ๋ถ™๋Š” ์š”์†Œ๋Š” ํ•œ์ •๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ชฉ๋ก ๊ฐœ์ˆ˜๊ฐ€ ๋” ๋งŽ์•„์ง€๋”๋ผ๋„ ์„ฑ๋Šฅ์— ์ฐจ์ด๊ฐ€ ์—†๋‹ค.

๊ธฐ์กด ํ”„๋กœ์ ํŠธ ๋‚ด์— react-virtualized๊ฐ€ ์ด๋ฏธ ์„ค์น˜ ๋˜์–ด ์žˆ์–ด ํ•ด๋‹น ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค. (react-window๊ฐ€ ๋” ์ž‘๊ณ  ๊ฐ€๋ณ์ง€๋งŒ ์ง€์›ํ•˜๋Š” ๊ธฐ๋Šฅ์ด ์ ์Œ. react-virtualized๊ฐ€ ์‚ฌ์šฉ๋Ÿ‰์ด ๋” ๋งŽ์Œ)

์ƒ๊ฐํ•ด๋ดค๋˜ ๋‹ค๋ฅธ ํ•ด๊ฒฐ์ฑ…

  • API ์‘๋‹ต ์‘๋‹ต ํŽ˜์ด์ง€๋„ค์ด์…˜
    • ํŽ˜์ด์ง€๋„ค์ด์…˜๋„ ํ•˜๋‚˜์˜ ๋ฐฉ๋ฒ•์ด๊ฒ ์ง€๋งŒ, ๋ณ„๋„ ์žฅ์น˜ ์—†์ด ํŽ˜์ด์ง€๋„ค์ด์…˜๋งŒ ์ ์šฉํ•  ๊ฒฝ์šฐ ๋ชฉ๋ก ๊ฐ€์žฅ ํ•˜๋‹จ๊นŒ์ง€ ์ •๋ณด๋ฅผ ๋ถˆ๋Ÿฌ์˜จ ๊ฒฝ์šฐ ๋˜‘๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒŒ ๋จ. ๋”ฐ๋ผ์„œ ๋‹ค๋ฅธ ๋ฐฉ์•ˆ์„ ์ฐพ๊ฒŒ ๋˜์—ˆ๊ณ , windowing ์ ์šฉ์œผ๋กœ ์ตœ์ข… ๊ฒฐ์ •

๊ฒฐ๊ณผ

windowing ์ ์šฉํ•œ ํŽ˜์ด์ง€์— ๋Œ€ํ•œ ๋ณด๊ณ ์„œ

lighthouse-after.html.zip

after

๋ชฉํ‘œํ–ˆ๋˜ INP 200ms ์ดํ•˜๋กœ ๊ฐœ์„ ๋˜์—ˆ๊ณ , ์‹ค์ œ๋กœ๋„ ์—ฌ๋Ÿฌ ์ด๋ฒคํŠธ๋“ค์— ๋Œ€ํ•œ ์ง€์—ฐ์ด ์ „ํ˜€ ๋Š๊ปด์ง€์ง€ ์•Š์•˜๋‹ค!

Before

performance-before

After

performace-after

performance ํƒญ์—์„œ๋„ ์ฐจ์ด๋ฅผ ์‰ฝ๊ฒŒ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

  • ๋ˆˆ์— ๋„๋Š” ๊ธด task๋“ค์ด ๋ชจ๋‘ ์‚ฌ๋ผ์ง
  • ๊ฐ task๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ์†๋„๊ฐ€ ๋งค์šฐ ๋นจ๋ผ์ง
  • ์ƒ๋‹จ ํƒ€์ž„๋ผ์ธ(box ์˜์—ญ)์„ ๊ฐ€๋“ ์ฑ„์šฐ๋˜ ๋…ธ๋ž€์ƒ‰ ์˜์—ญ๋“ค(์•„๋ž˜ ํŒŒ์ด์ฐจํŠธ์—์„œ ๋ณด์ด๋Š” scripting ์ž‘์—…)์ด ๋งค์šฐ ์ค„์–ด๋“ฌ

โ†’ ์ˆ˜์น˜์ƒ์œผ๋กœ ์•ฝ 90% ์ด์ƒ ๋นจ๋ผ์ง




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