Material-ui: ๋จธํ‹ฐ๋ฆฌ์–ผ UI ์„ฑ๋Šฅ ํ–ฅ์ƒ

์— ๋งŒ๋“  2018๋…„ 03์›” 23์ผ  ยท  93์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: mui-org/material-ui

๋จผ์ €, ์ด ๋ฉ‹์ง„ ๊ตฌ์„ฑ ์š”์†Œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋Œ€ํ•ด ๋Œ€๋‹จํžˆ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! ๋Œ€๋‹จํ•ด!

๋‚ด ์ƒˆ ์•ฑ์— ์„œ๋ž์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ฃผ๋กœ ์„œ๋ž ์˜ˆ์ œ๋ฅผ ๋ณต์‚ฌํ•˜์—ฌ ๋ถ™์—ฌ๋„ฃ์—ˆ์Šต๋‹ˆ๋‹ค. PoC๋ฅผ ์œ„ํ•ด ๊ณฑํ–ˆ์Šต๋‹ˆ๋‹ค.

        <Divider />
        <List>{mailFolderListItems}</List>

๋ถ€๋ถ„.

๊ทธ ํ›„์—๋Š” ํŠนํžˆ ๋ชจ๋ฐ”์ผ ์žฅ์น˜(nexus 4, ํšก๋‹จ ๋ณด๋„๊ฐ€ ์žˆ๋Š” ์ฝ”๋ฅด๋„๋ฐ” 20)์—์„œ ๋งค์šฐ ๋Š๋ฆฌ๊ฒŒ ๋Š๊ปด์ง‘๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ž ๋ชจ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋งŒ prod ๋ชจ๋“œ๋Š” ์†๋„๊ฐ€ ๋งŽ์ด ํ–ฅ์ƒ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋ฐ˜์‘ ๊ฐœ๋ฐœ ๋„๊ตฌ๋ฅผ ํ†ตํ•ด ๋‚˜๋Š” mailFolderListItems์˜ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ react-router์˜ ๋ชจ๋“  ๋งํฌ ํด๋ฆญ ๋˜๋Š” ๋ฉ”๋‰ด ์—ด๊ธฐ์—์„œ ๋ Œ๋”๋ง๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค. {mailFolderListItems} ๋ฅผ ๋‹ค์‹œ ๋ Œ๋”๋งํ•˜๋Š” ๋ฐ ์ตœ๋Œ€ 50-60ms๊ฐ€ ์†Œ์š”๋ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ์‚ฌ์šฉํ•œ๋‹ค

const modalProps = {
    keepMounted: true, // Better open performance on mobile.
};

๋‹ค๋ฅธ ์•ฑ ๊ตฌ์„ฑ ์š”์†Œ์˜ ๋ถˆํ™•์‹ค์„ฑ์„ ์—†์• ๊ธฐ ์œ„ํ•ด mailFolderListItems ๋ฅผ Component๋กœ ๋ณ€ํ™˜ํ•˜๊ณ  ๋‹ค์‹œ ๋ Œ๋”๋ง์„ ๋น„ํ™œ์„ฑํ™”ํ–ˆ์Šต๋‹ˆ๋‹ค.

class MailFolderListItems extends React.Component<{}, {}> {

    shouldComponentUpdate() {
        return false;
    }

    render() {
        return (
            <List>
                <Link to={Routes.Startpage.path}>
                    <ListItem>
                        <ListItemIcon>
                            <InboxIcon />
                        </ListItemIcon>
[...]


                <Divider />
                <MailFolderListItems />

๊ทธ ํ›„ ์ด ๋ถ€๋ถ„์€ ๊ดœ์ฐฎ๊ฒŒ ๋Š๊ปด์ง‘๋‹ˆ๋‹ค.

https://github.com/mui-org/material-ui/issues/5628 ์„ ์ฐพ์•˜์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ๋‹ค์‹œ ๋ฐฉ๋ฌธํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค . shouldComponentUpdate ์ตœ์ ํ™”๋Š” ์„ฑ๋Šฅ์„ ์–ป๊ธฐ ์œ„ํ•œ ๊ธฐ๋ณธ์ ์ด๊ณ  ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๋‹จ๊ณ„์ž…๋‹ˆ๋‹ค. PureComponent ๋Š” ๊ฐ€์žฅ ์ผ๋ฐ˜์ ์ธ ๋ฐ”๋กœ ๊ฐ€๊ธฐ์ž…๋‹ˆ๋‹ค.

๊ฒŒ๋‹ค๊ฐ€ WithStyles ์•„์ฃผ ๋งŽ์€ ์‹œ๊ฐ„(๋ชจ๋“  material-ui ๊ตฌ์„ฑ ์š”์†Œ์— ๋Œ€ํ•ด 1-2ms ์ด์ƒ)์ด ์†Œ๋น„๋œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์•˜์Šต๋‹ˆ๋‹ค.

  • [x] ์ด ์ €์žฅ์†Œ์˜ ๋ฌธ์ œ ๋ฅผ ๊ฒ€์ƒ‰ํ–ˆ์œผ๋ฉฐ ์ด๊ฒƒ์ด ์ค‘๋ณต๋˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ์ƒ๋˜๋Š” ๋™์ž‘

๋‚˜๋Š” ์ด ํ›Œ๋ฅญํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋Œ€ํ•ด ๊ฐ€๋Šฅํ•œ ๋ฐ˜์‘ ์„ฑ๋Šฅ์„ ์ตœ๋Œ€ํ•œ ์–ป์„ ๊ฒƒ์œผ๋กœ ๊ธฐ๋Œ€ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

ํ˜„์žฌ ํ–‰๋™

์•ฑ์€ ๋ชจ๋“  material-ui ๊ตฌ์„ฑ์š”์†Œ์™€ ํ•จ๊ป˜ ๋Š๋ ค์ง‘๋‹ˆ๋‹ค.

์žฌํ˜„ ๋‹จ๊ณ„(๋ฒ„๊ทธ์šฉ)

์ปดํฌ๋„ŒํŠธ ๋ฐ๋ชจ ํŽ˜์ด์ง€์—์„œ ๋ณต์‚ฌํ•˜์—ฌ ๋ถ™์—ฌ๋„ฃ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์•„์ง ์žฌํ˜„ ์˜ˆ์ œ๋ฅผ ์ œ๊ณตํ•˜์ง€ ์•Š์ง€๋งŒ ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์ฝ”๋“œ ๋ฐ ์ƒ์ž ๋ฐ๋ชจ๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ €์˜ ๊ฒฝ์šฐ ์„ฑ๋Šฅ ์„ค์ •์—์„œ 5๋ฐฐ ์ด์ƒ์œผ๋กœ ๋Š๋ ค์ง€๋Š” ๊ฒฝ์šฐ ๋ˆˆ์— ๋•๋‹ˆ๋‹ค.

๋‹น์‹ ์˜ ํ™˜๊ฒฝ

| ๊ธฐ์ˆ  | ๋ฒ„์ „ |
|----------------|---------|
| ๋จธํ‹ฐ๋ฆฌ์–ผ UI | 1.0.0-๋ฒ ํƒ€.38 |
| Material-UI ์•„์ด์ฝ˜ | 1.0.0-๋ฒ ํƒ€.36 |
| ๋ฐ˜์‘ | 16.2.0 |
| ๋ธŒ๋ผ์šฐ์ € | ์ฝ”๋ฅด๋„๋ฐ” ํšก๋‹จ ๋ณด๋„ 20(์•ˆ๋“œ๋กœ์ด๋“œ ํฌ๋กฌ 50๊ณผ ๋™์ผ) |

discussion performance

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

@oliviertassinari ํ›Œ๋ฅญํ•œ ๊ฐœ๋ฐœ์ž๋กœ์„œ ์–ด๋–ป๊ฒŒ ์ด๋Ÿฐ ๊ฒƒ์„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ์‚ฌ์‹ค์ด ์•„๋‹Œ ์ฃผ์žฅ์œผ๋กœ _๊ฐœ์ธ์ ์ธ ๊ฐ€์ •์„ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ๋‚˜๋Š” ์œ„์—์„œ ์ถฉ๋ถ„ํ•œ ์‚ฌ์‹ค์„ ์ œ์‹œํ–ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ด ํ”„๋กœ์ ํŠธ๋ฅผ ์ข‹์•„ํ•˜๊ณ  ๊ธฐ์—ฌํ•˜๊ณ  ์‹ถ๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๊ฒƒ์„ ๋ณด์—ฌ์ฃผ๊ธฐ ์œ„ํ•ด ๋ชจ๋“  ๊ฒƒ์„ ํ–ˆ๋‹ค. ์ถฉ๋ถ„ํ•˜์ง€ ์•Š๋‹ค? ์ž, ๊ทธ๋Ÿผ ๋” ๋งŽ์€ ์‚ฌ์‹ค ๊ณผ ๊ฐ€์ •์ด _no_ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹น์‹ ์„ ์œ„ํ•ด 10๊ฐœ์˜ ๋ฒ„ํŠผ์œผ๋กœ ์ค„์ž…๋‹ˆ๋‹ค. 10! ์ด๋Š” material-ui์˜ 10๊ฐœ ๊ตฌ์„ฑ์š”์†Œ(๋” ๋‚˜์œ ๊ฒƒ์€ ์ปจํ…Œ์ด๋„ˆ)๊ฐ€ ์•ฑ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์„ ๋•Œ๊นŒ์ง€ ์ „์ฒด ์•ฑ์˜ ์†๋„๋ฅผ ๋Šฆ์ถ”๋Š” ๊ฒƒ์„ ์˜๋ฏธ ํ•ฉ๋‹ˆ๋‹ค ! ์Šค๋กœํ‹€ ์—†์ด ํšก๋‹จ๋ณด๋„ 21/ํฌ๋กฌ 51์„ ์‚ฌ์šฉํ•˜์—ฌ ์‹ค์ œ ์žฅ์น˜์—์„œ ํ…Œ์ŠคํŠธ:

์ผ๋ฐ˜ ๋ฒ„ํŠผ:
image

ํ“จ์–ด๋ฒ„ํŠผ:
image

์ด๊ฒƒ์€ ์—ฌ์ „ํžˆ โ€‹โ€‹8๋ฐฐ ๊ฐœ์„ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค! ๊ทธ๊ฒƒ์€ ๊ฑฐ๋Œ€ํ•˜๋‹ค! ๋ชจ๋ฐ”์ผ ์žฅ์น˜์—์„œ ์ด๊ฒƒ์ด ์–ผ๋งˆ๋‚˜ ์ค‘์š”ํ•œ์ง€ ์ƒ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

ํ•œ ํŽ˜์ด์ง€์— 100๊ฐœ์˜ ๋ฒ„ํŠผ ๋Œ€์‹  ์ตœ๋Œ€ 10๊ฐœ์˜ ๋ฒ„ํŠผ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜๋„ 10๊ฐœ์˜ ๊ทธ๋ฆฌ๋“œ, 10๊ฐœ์˜ X ๋“ฑ์„ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Button์€ ๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ์ปดํฌ๋„ŒํŠธ ์ค‘ ํ•˜๋‚˜์ด๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค! ์„ฑ๋Šฅ ๊ด€์ ์—์„œ material-ui ๊ฐ€ ๊นจ์ ธ ์žˆ์Œ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ์ด์ œ AppBar, Toolbar, List, Drawer์™€ ๊ฐ™์€ ์ปจํ…Œ์ด๋„ˆ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์ƒ์ƒํ•ด๋ณด์‹ญ์‹œ์˜ค! ์ด๊ฒƒ์€ ๋” ๋‚˜์˜๋‹ค! ๋ชจ๋“  ํŽ˜์ด์ง€์— 20๊ฐœ์˜ ๊ตฌ์„ฑ ์š”์†Œ/์ปจํ…Œ์ด๋„ˆ๋ฅผ ๋งค์šฐ ๋น ๋ฅด๊ฒŒ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ฐ•๋ ฅํ•œ ๋ฐ์Šคํฌํƒ‘/๋งฅ์—์„œ ์–ด๋– ํ•œ ์†๋„ ์ €ํ•˜๋„ ๋งŒ๋ฃŒ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— material-ui๊ฐ€ ๋ฏฟ์„ ์ˆ˜ ์—†์„ ์ •๋„๋กœ ๋Š๋ฆฌ์ง€ ์•Š๋‹ค๋Š” ์˜๋ฏธ๋Š” ์•„๋‹™๋‹ˆ๋‹ค.

react-intl์—์„œ ์ด์ „ props์™€ ์ƒˆ props ๊ฐ„์˜ ๊ฒ€์‚ฌ๋Š” ํ•ญ์ƒ false์ž…๋‹ˆ๋‹ค. CPU ์ฃผ๊ธฐ๋ฅผ ๋‚ญ๋น„ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ x13 -> x0.8

์ฝ”๋“œ์ƒŒ๋“œ๋ฐ•์Šค์— ๋Œ€ํ•œ ์˜ˆ๋ฅผ ๋ณด์—ฌ์ฃผ์„ธ์š”. ์™œ ์ด๋Ÿฐ ์ผ์ด ์ผ์–ด๋‚˜์•ผ ํ•˜๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋ฐ˜์‘ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์ž˜๋ชป ์‚ฌ์šฉํ•  ๋•Œ๋งŒ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ณต์‹์ ์ธ ์˜ˆ ๋Š” react-intl ์ด ์ ์šฉ๋˜์ง€ ์•Š์€ context subscribers ์ฒ˜๋Ÿผ ๋ณด์ด๊ธฐ ๋•Œ๋ฌธ์— ์ž˜๋ชป๋œ ์‚ฌ์šฉ๋ฒ•์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค . ๊ทธ๋Ÿฌ๋‚˜ ์„ฑ๋Šฅ์„ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ๋ฐ˜์‘ ์ง€์นจ ๋ฐ ๋ชจ๋ฒ” ์‚ฌ๋ก€์™€ ์ผ์น˜ํ•˜๋Š” ๋‹ค๋ฅธ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ๋งŽ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

BTW: WithStyles๋Š” ๋ชจ๋ฐ”์ผ ์žฅ์น˜์˜ ๋ฒ„ํŠผ์— ๋Œ€ํ•ด ์ตœ๋Œ€ 2,27ms๋ฅผ ์†Œ๋น„ํ•ฉ๋‹ˆ๋‹ค. 8๊ฐœ์˜ ๊ตฌ์„ฑ ์š”์†Œ์™€ 60fps ๋ฏธ๋งŒ์ž…๋‹ˆ๋‹ค.

๋ชจ๋“  93 ๋Œ“๊ธ€

๋‚˜๋Š” ์ด ํ›Œ๋ฅญํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋Œ€ํ•ด ๊ฐ€๋Šฅํ•œ ๋ฐ˜์‘ ์„ฑ๋Šฅ์„ ์ตœ๋Œ€ํ•œ ์–ป์„ ๊ฒƒ์œผ๋กœ ๊ธฐ๋Œ€ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

@Bessonov Performance๋Š” v1 ๋ฆด๋ฆฌ์Šค ์ดํ›„์— ์ดˆ์ ์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๊ฐ€๋Šฅํ•œ ํ•œ ๋นจ๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ํ•ต์‹ฌ์„ ์œ ์ง€ํ•˜๋ ค๊ณ  ๋…ธ๋ ฅํ–ˆ์Šต๋‹ˆ๋‹ค. +90%์˜ ๊ฒฝ์šฐ์— ์ถฉ๋ถ„ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ ์–ด๋„ ์ง€๊ธˆ๊นŒ์ง€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•œ ๊ฒฝํ—˜์ž…๋‹ˆ๋‹ค. ์„ฑ๋Šฅ์ด ์ค‘์š”ํ•˜๋‹ค๋Š” ์‚ฌ์‹ค์— ๋Œ€ํ•ด ์ฃผ์˜๋ฅผ ํ™˜๊ธฐ์‹œํ‚ค๋Š” ๊ฒƒ ์™ธ์—๋Š” ์™ธ๋ถ€ ์ฐธ์กฐ๋ฅผ ์ œ๊ณตํ•˜์ง€ ์•Š์•˜์ง€๋งŒ ์ด ๋ฌธ์ œ๋ฅผ ์‹คํ–‰ ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋งŒ๋“ค ์ˆ˜๋Š” ์—†์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ์กฐ์‚ฌํ•  ์ˆ˜ ์žˆ๋Š” Material-UI์˜ ์„ฑ๋Šฅ ๋ฃจํŠธ ์ œํ•œ์„ ์‹๋ณ„ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ(์žฌ์ƒ ์ฝ”๋“œ ๋ฐ ์ƒ์ž ๋˜๋Š” ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ) ์ด๋ฅผ ๋†’์ด์‹ญ์‹œ์˜ค. ๊ทธ ์ „๊นŒ์ง€๋Š” ์ด์Šˆ๋ฅผ ์ข…๋ฃŒํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

@oliviertassinari ๋น ๋ฅธ ์‘๋‹ต์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค! ๋ฐœ๋งค ํ›„์— ๊ทธ ํผํฌ๋จผ์Šค๊ฐ€ ์ง‘์ค‘๋  ๊ฒƒ์ด๋ผ๋Š” ์†Œ์‹์„ ๋“ค์œผ๋‹ˆ ๋งค์šฐ ๊ธฐ์ฉ๋‹ˆ๋‹ค.

+90%์˜ ๊ฒฝ์šฐ์— ์ถฉ๋ถ„ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ ์–ด๋„ ์ง€๊ธˆ๊นŒ์ง€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•œ ๊ฒฝํ—˜์ž…๋‹ˆ๋‹ค.

๋ฐ์Šคํฌํƒ‘์—์„œ - ๊ทธ๋ ‡์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋ชจ๋ฐ”์ผ์—์„œ๋Š” ์ •๋ง ๋Š๋ฆฝ๋‹ˆ๋‹ค. ์„œ๋ž๊ณผ ์ผ๋ถ€ ๋ฒ„ํŠผ๋งŒ ์žˆ์œผ๋ฉด ์•ฑ์ด ๋Š๋ ค์ง‘๋‹ˆ๋‹ค. ์‘๋‹ตํ•˜์ง€ ์•Š์œผ๋ฉฐ ํ•„์š”์— ๋”ฐ๋ผ ๋” ๋งŽ์€ ์ „๋ ฅ์„ ์†Œ๋น„ํ•ฉ๋‹ˆ๋‹ค.

์„ฑ๋Šฅ์ด ์ค‘์š”ํ•˜๋‹ค๋Š” ์‚ฌ์‹ค์— ๋Œ€ํ•ด ์ฃผ์˜๋ฅผ ํ™˜๊ธฐ์‹œํ‚ค๋Š” ๊ฒƒ ์™ธ์—๋Š” ์™ธ๋ถ€ ์ฐธ์กฐ๋ฅผ ์ œ๊ณตํ•˜์ง€ ์•Š์•˜์ง€๋งŒ ์ด ๋ฌธ์ œ๋ฅผ ์‹คํ–‰ ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋งŒ๋“ค ์ˆ˜๋Š” ์—†์Šต๋‹ˆ๋‹ค.

์ด๋ฏธ ์ œ๊ธฐ๋œ ๋ฌธ์ œ์— ๋Œ€ํ•œ ์ฐธ์กฐ์™€ ๋ฐ˜์‘ ๋ฌธ์„œ์— ๋Œ€ํ•œ ์ฐธ์กฐ๋ฅผ ์ œ๊ณตํ–ˆ์Šต๋‹ˆ๋‹ค.

๋‹น์‚ฌ๊ฐ€ ์กฐ์‚ฌํ•  ์ˆ˜ ์žˆ๋Š” Material-UI์˜ ์„ฑ๋Šฅ ๋ฃจํŠธ ์ œํ•œ์„ ์‹๋ณ„ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ(๋ณต์ œ ์ฝ”๋“œ ๋ฐ ์ƒ์ž ๋˜๋Š” ์ €์žฅ์†Œ ์‚ฌ์šฉ)

๋‚ด๊ฐ€ ๋งํ–ˆ๋“ฏ์ด, ๋‚˜๋Š” ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ์€ ์ˆœ์ˆ˜ ์„ฑ๋ถ„๊ณผ ๋น„์ˆœ์ˆ˜ ์„ฑ๋ถ„์„ ๋น„๊ตํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์žฌํ˜„ ๋‹จ๊ณ„๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  1. ํฌ๋กฌ์„ ์‚ฌ์šฉํ•˜๊ณ  https://codesandbox.io/s/r1ov818nwm์œผ๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.
  2. ๋ฏธ๋ฆฌ๋ณด๊ธฐ ์ฐฝ์—์„œ "์ƒˆ ์ฐฝ์—์„œ ์—ด๊ธฐ" ํด๋ฆญ
  3. ๊ฐœ๋ฐœ ๋„๊ตฌ๋ฅผ ์—ด๊ณ  "์„ฑ๋Šฅ" ํƒญ์œผ๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.
  4. ๋ชจ๋ฐ”์ผ ์žฅ์น˜๋ฅผ ๋ฐ˜์˜ํ•˜๊ธฐ ์œ„ํ•ด CPU๋ฅผ ์ตœ์†Œ 5๋ฐฐ(PC์— ๋”ฐ๋ผ - 10๋ฐฐ๊นŒ์ง€ ๊ฐ€๋Šฅ)๋กœ ์กฐ์ ˆํ•ฉ๋‹ˆ๋‹ค.
  5. ๋ฒ„๊ฑฐ๋ฅผ ํด๋ฆญํ•˜๊ณ  ๋ฒ„๊ฑฐ๊ฐ€ ์–ด๋–ป๊ฒŒ ์ง€์—ฐ๋˜๋Š”์ง€ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.

๊ทธ๋ฆฌ๊ณ  ์ง€๊ธˆ:

  1. index.js
  2. pure ์„ true
  3. ๊ตฌํ•˜๋‹ค
  4. ์œ„์—์„œ๋ถ€ํ„ฐ ๋‹จ๊ณ„ ๋ฐ˜๋ณต
  5. ์ฆ๊ธฐ์„ธ์š”!

์ด ์˜ˆ์ œ๋Š” ๋„ˆ๋ฌด ๋งŽ์€ List ์š”์†Œ๋ฅผ ์‚ฝ์ž…ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์•ฝ๊ฐ„ ๋น„ํ˜„์‹ค์ ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‚ด๊ฐ€ ๋งํ–ˆ๋“ฏ์ด ๋ชจ๋ฐ”์ผ์—์„œ๋Š” ๋ชจ๋“  ํ–‰๋™์„ "๋Š๋ผ๋Š”" ์ง€์ ์„ ๋งค์šฐ ๋น ๋ฅด๊ฒŒ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค.

๋‹ค์Œ์€ WithStyles ๋‚ด ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. CPU ์กฐ์ ˆ ๊ธฐ๋Šฅ์ด ์žˆ๋Š” ๋ฐ์Šคํฌํƒ‘์— ์žˆ์Šต๋‹ˆ๋‹ค. ์›”์š”์ผ์— ์‹ค์ œ ์žฅ์น˜์˜ ์Šคํฌ๋ฆฐ์ƒท์„ ๊ฒŒ์‹œํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

WithStyles(ListItem) :
image

ListItem :
image

์ฐจ์ด๋Š” ListItem ๊ตฌ์„ฑ ์š”์†Œ์˜ ๊ฒฝ์šฐ์—๋งŒ 1.26ms์ž…๋‹ˆ๋‹ค. ์ด์™€ ๊ฐ™์€ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ 13๊ฐœ ์žˆ์œผ๋ฉด ๋” ์ด์ƒ 60fps๋กœ ๋ Œ๋”๋งํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด ๊ธฐ๊ฐ„์ด ํ•ญ์ƒ ์—ฌ๊ธฐ์— ์žˆ๋Š” ๊ฒƒ์€ ์•„๋‹˜์„ Desktop์—์„œ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค.

์ˆœ์ˆ˜ ์„ฑ๋ถ„๊ณผ ๋น„์ˆœ์ˆ˜ ์„ฑ๋ถ„์˜ ๋น„๊ต๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

Btw PureComponent๊ฐ€ ๋ชจ๋“  ์„ฑ๋Šฅ ๋ฌธ์ œ์— ๋Œ€ํ•œ ์†”๋ฃจ์…˜์ด๋ผ๊ณ  ๋งํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ๋ชจ๋ฐ”์ผ์—์„œ material-ui๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋Š” ์—ญํ•  ์ค‘ ํ•˜๋‚˜๊ฐ€ ๋  ์ˆ˜ ์žˆ๋‹ค๊ณ  ๋ง์”€๋“œ๋ฆฌ๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

์ฐจ์ด์ ์€ ListItem ๊ตฌ์„ฑ ์š”์†Œ์˜ ๊ฒฝ์šฐ์—๋งŒ 1.26ms์ž…๋‹ˆ๋‹ค.

@Bessonov WithStyles ๊ตฌ์„ฑ ์š”์†Œ๋Š” ๋™์ผํ•œ ๊ตฌ์„ฑ ์š”์†Œ์˜ ๋ฐ˜๋ณต์ ์ธ ์ธ์Šคํ„ด์Šค์— ๋Œ€ํ•ด ๋งค์šฐ ์ €๋ ดํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. CSS๋ฅผ ํ•œ ๋ฒˆ๋งŒ ์ฃผ์ž…ํ•ฉ๋‹ˆ๋‹ค.
React ํ•œ๊ณ„์™€ ๊ณ ์ฐจ ๊ตฌ์„ฑ ์š”์†Œ์˜ ๋น„์šฉ์— ๋„๋‹ฌํ–ˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
React์˜ ์„ฑ๋Šฅ ๋ฌธ์ œ๋ฅผ ์™„ํ™”ํ•˜๊ธฐ ์œ„ํ•œ ๋‹ค์–‘ํ•œ ์†”๋ฃจ์…˜์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์š”์†Œ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ๋ฐ ๊ฐ€์ƒํ™”๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ–ฅํ›„ ์„ฑ๋Šฅ ์กฐ์‚ฌ๋ฅผ ์œ„ํ•œ ์‹œ์ž‘์ ์œผ๋กœ ์ด ๋ฌธ์ œ๋ฅผ ์—ด์–ด๋‘๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
์ง€๊ธˆ ๋‹น์žฅ ์šฐ๋ฆฌ๊ฐ€ ํ•  ์ˆ˜ ์žˆ๋Š” ์ผ์€ ๋งŽ์ง€ ์•Š๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ ค๋ฅผ ์ œ๊ธฐํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

์ข‹์•„, ๊ทธ๊ฒƒ์€ ๋‹จ์ง€ ํ•œ ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค. ๋” ์ค‘์š”ํ•œ ๋ถ€๋ถ„์ธ shouldComponentUpdate ์ตœ์ ํ™”์— ๋Œ€ํ•ด ์–ด๋–ป๊ฒŒ ์ƒ๊ฐํ•˜์‹ญ๋‹ˆ๊นŒ?

ํŽธ์ง‘: ์ด ๋ฌธ์ œ๋ฅผ ๋‘ ๋ถ€๋ถ„์œผ๋กœ ๋‚˜๋ˆ„๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์ด ๋ถ€๋ถ„์€ shouldComponentUpdate ์— ๋Œ€ํ•œ ๊ฒƒ์ด๊ณ  ๋‹ค๋ฅธ ๋ถ€๋ถ„์€ WithStyles ์— ๋Œ€ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋” ๋งŽ์€ ์ •๋ณด๋ฅผ ๋ณด์—ฌ์ค„ ์ˆ˜ ์žˆ๋‹ค๋ฉด ๋ง์ด์ฃ . ๊ดœ์ฐฎ์Šต๋‹ˆ๊นŒ?

shouldComponentUpdate ์ตœ์ ํ™”

@Bessonov ์šฐ๋ฆฌ๋Š” ๋‘ ๊ฐ€์ง€ ์ด์œ ๋กœ Material-UI ์ธก์—์„œ ์ด๋Ÿฌํ•œ ๋กœ์ง ์„ ์˜๋„์  ์œผ๋กœ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

  1. ๋Œ€๋ถ€๋ถ„์˜ ๊ตฌ์„ฑ ์š”์†Œ๋Š” ๊ฐ ๋ Œ๋”์—์„œ ๋ฐ˜์‘ ์š”์†Œ ์ฐธ์กฐ ๋ณ€๊ฒฝ์ธ ๋ฐ˜์‘ ์š”์†Œ๋ฅผ ํ—ˆ์šฉํ•˜๋ฏ€๋กœ ๋…ผ๋ฆฌ๊ฐ€ CPU ์ฃผ๊ธฐ๋ฅผ ์ฒด๊ณ„์ ์œผ๋กœ ๋‚ญ๋น„ํ•˜๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
  2. shouldComponentUpdate ๋กœ์ง์ด React ํŠธ๋ฆฌ์˜ ๋ฃจํŠธ์—์„œ ๊ฐ€๊นŒ์šธ์ˆ˜๋ก ๋” ํšจ์œจ์ ์ž…๋‹ˆ๋‹ค. ๋‚ด ๋ง์€, ๋‚˜๋ฌด์—์„œ ๊ฐ€์ง€์น˜๊ธฐ๋ฅผ ๋งŽ์ด ํ• ์ˆ˜๋ก ๋” ์ข‹์Šต๋‹ˆ๋‹ค. Material-UI ๊ตฌ์„ฑ ์š”์†Œ๋Š” ๋‚ฎ์€ ์ˆ˜์ค€์ž…๋‹ˆ๋‹ค. ๋‚ฎ์€ ๋ ˆ๋ฒ„๋ฆฌ์ง€ ๊ธฐํšŒ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๊ฐ€ ์ฐพ์€ ์œ ์ผํ•œ ๊ธฐํšŒ๋Š” ์•„์ด์ฝ˜์ž…๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ๊ฒƒ์„ ์‹๋ณ„ํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์•Œ๋ ค์ฃผ์‹ญ์‹œ์˜ค.

WithStyles์˜ ๋‹ค๋ฅธ ๋ถ€๋ถ„

WithStyles์—์„œ ๋ณด๋‚ธ ์‹œ๊ฐ„์˜ +90%๋Š” ์‹ค์ œ๋กœ JSS ์—์„œ ์†Œ๋น„๋˜๋ฉฐ Material-UI ์ธก์—์„œ ์ด์— ๋Œ€ํ•ด ํ•  ์ˆ˜ ์žˆ๋Š” ์ผ์€ ๊ฑฐ์˜ ์—†์Šต๋‹ˆ๋‹ค.
์ ์–ด๋„ ์ตœ๊ทผ์—๋Š” ๋ฐ˜๋ณต์ ์ธ ๋ Œ๋”๋ง์—์„œ ์„ฑ๋Šฅ์„ ํฌ๊ฒŒ ํ–ฅ์ƒ์‹œํ‚ค๊ธฐ ์œ„ํ•ด ์„œ๋ฒ„ ์ธก ๋ Œ๋”๋ง์„ ์œ„ํ•œ ์บ์‹ฑ ๊ธฐํšŒ๋ฅผ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ทธ๊ฒƒ์€ ์„œ๋ฒ„ ์ธก์—์„œ๋งŒ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

๋Œ€๋ถ€๋ถ„์˜ ๊ตฌ์„ฑ ์š”์†Œ๋Š” ๊ฐ ๋ Œ๋”์—์„œ ๋ฐ˜์‘ ์š”์†Œ ์ฐธ์กฐ ๋ณ€๊ฒฝ์ธ ๋ฐ˜์‘ ์š”์†Œ๋ฅผ ํ—ˆ์šฉํ•˜๋ฏ€๋กœ ๋…ผ๋ฆฌ๊ฐ€ CPU ์ฃผ๊ธฐ๋ฅผ ์ฒด๊ณ„์ ์œผ๋กœ ๋‚ญ๋น„ํ•˜๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

์šฉ๋„์— ๋”ฐ๋ผ ๋‹ค๋ฅด๋ฉฐ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋‚˜ ์ž์‹ ์„ ๋ฒค์น˜๋งˆํ‚นํ•˜์ง€ ์•Š์ง€๋งŒ, ํŠนํžˆ ๋ถˆ๋ณ€ ๊ตฌ์กฐ์˜ ๊ฒฝ์šฐ ์˜ฌ๋ฐ”๋ฅธ ๊ตฌ์„ฑ ์š”์†Œ ์‚ฌ์šฉ๊ณผ ์ตœ์ ํ™”๋œ shouldComponentUpdate (์–•์€ ๋น„๊ต ํฌํ•จ)์ด ์ตœ์ ํ™”๋˜์ง€ ์•Š์€ ๊ตฌ์„ฑ ์š”์†Œ๋ณด๋‹ค ๋น„์šฉ์ด ๋œ ๋“ ๋‹ค๊ณ  ํ™•์‹ ํ•ฉ๋‹ˆ๋‹ค. ใ…‹). ๊ด€๋ จ ํ‹ฐ์ผ“: https://github.com/mui-org/material-ui/issues/4305

์˜ˆ๋ฅผ ๋“ค์–ด https://github.com/mui-org/material-ui/blob/v1-beta/docs/src/pages/demos/drawers/PermanentDrawer.js#L68์—์„œ ์ด๊ฒƒ์€ ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  PureComponent ๋งŒ๋“ญ๋‹ˆ๋‹ค.

        classes={{
          paper: classes.drawerPaper,
        }}

๋งค๋ฒˆ ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ:

const drawerClasses = {
    paper: classes.drawerPaper,
};
[...]
        classes={drawerClasses}

๊ตฌ์„ฑ ์š”์†Œ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค.

shouldComponentUpdate ๋กœ์ง์ด React ํŠธ๋ฆฌ์˜ ๋ฃจํŠธ์—์„œ ๊ฐ€๊นŒ์šธ์ˆ˜๋ก ๋” ํšจ์œจ์ ์ž…๋‹ˆ๋‹ค. ๋‚ด ๋ง์€, ๋‚˜๋ฌด์—์„œ ๊ฐ€์ง€์น˜๊ธฐ๋ฅผ ๋งŽ์ด ํ• ์ˆ˜๋ก ๋” ์ข‹์Šต๋‹ˆ๋‹ค.

๋„ค, ๋งž์Šต๋‹ˆ๋‹ค.

Material-UI ๊ตฌ์„ฑ ์š”์†Œ๋Š” ๋‚ฎ์€ ์ˆ˜์ค€์ž…๋‹ˆ๋‹ค. ๋‚ฎ์€ ๋ ˆ๋ฒ„๋ฆฌ์ง€ ๊ธฐํšŒ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๊ฒƒ์€ ๋ถ€๋ถ„์ ์œผ๋กœ ์‚ฌ์‹ค์ž…๋‹ˆ๋‹ค. https://codesandbox.io/s/r1ov818nwm ์—์„œ ๋ณผ ์ˆ˜ ์žˆ๋“ฏ์ด ์ €๋Š” List ๋ฅผ PureComponent ๊ฐ์Œ‰๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๊ฒƒ์€ ์—†์œผ๋ฉฐ ์ค‘์š”ํ•œ ์š”์†Œ๋กœ ์„œ๋ž ์†๋„๋ฅผ ๋†’์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ด๊ฒƒ์ด ์ ์–ด๋„ {this.props.children} ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“  ๊ตฌ์„ฑ ์š”์†Œ์— ๋Œ€ํ•ด ์‚ฌ์‹ค์ด๋ผ๊ณ  ์ฃผ์žฅํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๋ฐ๋ชจ๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. https://codesandbox.io/s/my7rmo2m4y

101๊ฐœ์˜ Button(pure = false)๊ณผ PureComponent๋กœ ๋ž˜ํ•‘๋œ Button(pure = true, Button ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„์น˜ ์ฐธ์กฐ)์ด ์žˆ์Šต๋‹ˆ๋‹ค. "ํด๋ฆญ" ๋ฒ„ํŠผ์„ ํด๋ฆญํ•ด๋„ ๋™์ผํ•œ ๊ฒŒ์ž„ ๊ฒฐ๊ณผ:

์ผ๋ฐ˜ ๋ฒ„ํŠผ:
image

๋ž˜ํ•‘๋œ ๋ฒ„ํŠผ(์˜ค๋ฒ„ํ—ค๋“œ ๋“ฑ ํฌํ•จ):
image

๋ณด์‹œ๋‹ค์‹œํ”ผ ์ผ๋ฐ˜ ๋ฒ„ํŠผ์—๋Š” 637ms โ€‹โ€‹๋Œ€ 47ms๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค! shouldComponentUpdate (๋˜๋Š” PureComponent )๋ฅผ ์ตœ์ ํ™”ํ•˜๋Š” ๊ฒƒ์ด ์—ฌ์ „ํžˆ ๊ฐ€์น˜๊ฐ€ ์—†๋‹ค๊ณ  ์ƒ๊ฐํ•˜์‹ญ๋‹ˆ๊นŒ? :)

ํŽธ์ง‘: ์ฒ˜์Œ์— ๋ฌธ๊ตฌ ์ˆ˜์ •

@oliviertassinari @oreqizer ํฅ๋ฏธ๋กœ์šด ์ ์„ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค. extends PureComponent ๋Š” Component ์™€ ๊ฐ™์ด ๋” ๋‚˜์€ ์„ฑ๋Šฅ์„ ๋ณด์ž…๋‹ˆ๋‹ค.

  shouldComponentUpdate() {
    return false;
  }

image

ํŽธ์ง‘: ๋‚˜๋Š” ์ด๊ฒƒ์ด ๋ฐ˜์‘ ๋‚ด๋ถ€ ์ตœ์ ํ™” ์ค‘ ํ•˜๋‚˜๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋ณด์‹œ๋‹ค์‹œํ”ผ ์ผ๋ฐ˜ ๋ฒ„ํŠผ์—๋Š” 637ms โ€‹โ€‹๋Œ€ 47ms๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค! ์•„์ง๋„ shouldComponentUpdate(๋˜๋Š” PureComponent)๋ฅผ ์ตœ์ ํ™”ํ•  ๊ฐ€์น˜๊ฐ€ ์—†๋‹ค๊ณ  ์ƒ๊ฐํ•˜์‹ญ๋‹ˆ๊นŒ? :)

@Bessonov ์ˆœ์ˆ˜ ๋…ผ๋ฆฌ์˜ ์ž ์žฌ๋ ฅ์„ ๋ณด์—ฌ์ฃผ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ, ๋งค์šฐ ์œ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค! x13 ๊ฐœ์„  ์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ์‹ค์ œ ์กฐ๊ฑด์— ๊ฐ€๊น๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

  • ํ•œ ํŽ˜์ด์ง€์— 100๊ฐœ์˜ ๋ฒ„ํŠผ ๋Œ€์‹  ์ตœ๋Œ€ 10๊ฐœ์˜ ๋ฒ„ํŠผ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜๋„ 10๊ฐœ์˜ ๊ทธ๋ฆฌ๋“œ, 10๊ฐœ์˜ X ๋“ฑ์„ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ํ•˜์œ„ ์ˆ˜์ค€ ์š”์†Œ์— ์ œ๊ณต๋˜๋Š” ๊ฐ„๋‹จํ•œ ์†์„ฑ ๋Œ€์‹  react-intl๊ณผ ๊ฐ™์€ ๊ฒƒ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด์ „ props ์™€ ์ƒˆ CPU ์ฃผ๊ธฐ๋ฅผ ๋‚ญ๋น„ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค . ๊ทธ๋ž˜์„œ x13 -> x0.8 ์ •๋„

@oliviertassinari ํ›Œ๋ฅญํ•œ ๊ฐœ๋ฐœ์ž๋กœ์„œ ์–ด๋–ป๊ฒŒ ์ด๋Ÿฐ ๊ฒƒ์„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ์‚ฌ์‹ค์ด ์•„๋‹Œ ์ฃผ์žฅ์œผ๋กœ _๊ฐœ์ธ์ ์ธ ๊ฐ€์ •์„ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ๋‚˜๋Š” ์œ„์—์„œ ์ถฉ๋ถ„ํ•œ ์‚ฌ์‹ค์„ ์ œ์‹œํ–ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ด ํ”„๋กœ์ ํŠธ๋ฅผ ์ข‹์•„ํ•˜๊ณ  ๊ธฐ์—ฌํ•˜๊ณ  ์‹ถ๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๊ฒƒ์„ ๋ณด์—ฌ์ฃผ๊ธฐ ์œ„ํ•ด ๋ชจ๋“  ๊ฒƒ์„ ํ–ˆ๋‹ค. ์ถฉ๋ถ„ํ•˜์ง€ ์•Š๋‹ค? ์ž, ๊ทธ๋Ÿผ ๋” ๋งŽ์€ ์‚ฌ์‹ค ๊ณผ ๊ฐ€์ •์ด _no_ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹น์‹ ์„ ์œ„ํ•ด 10๊ฐœ์˜ ๋ฒ„ํŠผ์œผ๋กœ ์ค„์ž…๋‹ˆ๋‹ค. 10! ์ด๋Š” material-ui์˜ 10๊ฐœ ๊ตฌ์„ฑ์š”์†Œ(๋” ๋‚˜์œ ๊ฒƒ์€ ์ปจํ…Œ์ด๋„ˆ)๊ฐ€ ์•ฑ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์„ ๋•Œ๊นŒ์ง€ ์ „์ฒด ์•ฑ์˜ ์†๋„๋ฅผ ๋Šฆ์ถ”๋Š” ๊ฒƒ์„ ์˜๋ฏธ ํ•ฉ๋‹ˆ๋‹ค ! ์Šค๋กœํ‹€ ์—†์ด ํšก๋‹จ๋ณด๋„ 21/ํฌ๋กฌ 51์„ ์‚ฌ์šฉํ•˜์—ฌ ์‹ค์ œ ์žฅ์น˜์—์„œ ํ…Œ์ŠคํŠธ:

์ผ๋ฐ˜ ๋ฒ„ํŠผ:
image

ํ“จ์–ด๋ฒ„ํŠผ:
image

์ด๊ฒƒ์€ ์—ฌ์ „ํžˆ โ€‹โ€‹8๋ฐฐ ๊ฐœ์„ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค! ๊ทธ๊ฒƒ์€ ๊ฑฐ๋Œ€ํ•˜๋‹ค! ๋ชจ๋ฐ”์ผ ์žฅ์น˜์—์„œ ์ด๊ฒƒ์ด ์–ผ๋งˆ๋‚˜ ์ค‘์š”ํ•œ์ง€ ์ƒ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

ํ•œ ํŽ˜์ด์ง€์— 100๊ฐœ์˜ ๋ฒ„ํŠผ ๋Œ€์‹  ์ตœ๋Œ€ 10๊ฐœ์˜ ๋ฒ„ํŠผ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜๋„ 10๊ฐœ์˜ ๊ทธ๋ฆฌ๋“œ, 10๊ฐœ์˜ X ๋“ฑ์„ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Button์€ ๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ์ปดํฌ๋„ŒํŠธ ์ค‘ ํ•˜๋‚˜์ด๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค! ์„ฑ๋Šฅ ๊ด€์ ์—์„œ material-ui ๊ฐ€ ๊นจ์ ธ ์žˆ์Œ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ์ด์ œ AppBar, Toolbar, List, Drawer์™€ ๊ฐ™์€ ์ปจํ…Œ์ด๋„ˆ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์ƒ์ƒํ•ด๋ณด์‹ญ์‹œ์˜ค! ์ด๊ฒƒ์€ ๋” ๋‚˜์˜๋‹ค! ๋ชจ๋“  ํŽ˜์ด์ง€์— 20๊ฐœ์˜ ๊ตฌ์„ฑ ์š”์†Œ/์ปจํ…Œ์ด๋„ˆ๋ฅผ ๋งค์šฐ ๋น ๋ฅด๊ฒŒ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ฐ•๋ ฅํ•œ ๋ฐ์Šคํฌํƒ‘/๋งฅ์—์„œ ์–ด๋– ํ•œ ์†๋„ ์ €ํ•˜๋„ ๋งŒ๋ฃŒ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— material-ui๊ฐ€ ๋ฏฟ์„ ์ˆ˜ ์—†์„ ์ •๋„๋กœ ๋Š๋ฆฌ์ง€ ์•Š๋‹ค๋Š” ์˜๋ฏธ๋Š” ์•„๋‹™๋‹ˆ๋‹ค.

react-intl์—์„œ ์ด์ „ props์™€ ์ƒˆ props ๊ฐ„์˜ ๊ฒ€์‚ฌ๋Š” ํ•ญ์ƒ false์ž…๋‹ˆ๋‹ค. CPU ์ฃผ๊ธฐ๋ฅผ ๋‚ญ๋น„ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ x13 -> x0.8

์ฝ”๋“œ์ƒŒ๋“œ๋ฐ•์Šค์— ๋Œ€ํ•œ ์˜ˆ๋ฅผ ๋ณด์—ฌ์ฃผ์„ธ์š”. ์™œ ์ด๋Ÿฐ ์ผ์ด ์ผ์–ด๋‚˜์•ผ ํ•˜๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋ฐ˜์‘ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์ž˜๋ชป ์‚ฌ์šฉํ•  ๋•Œ๋งŒ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ณต์‹์ ์ธ ์˜ˆ ๋Š” react-intl ์ด ์ ์šฉ๋˜์ง€ ์•Š์€ context subscribers ์ฒ˜๋Ÿผ ๋ณด์ด๊ธฐ ๋•Œ๋ฌธ์— ์ž˜๋ชป๋œ ์‚ฌ์šฉ๋ฒ•์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค . ๊ทธ๋Ÿฌ๋‚˜ ์„ฑ๋Šฅ์„ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ๋ฐ˜์‘ ์ง€์นจ ๋ฐ ๋ชจ๋ฒ” ์‚ฌ๋ก€์™€ ์ผ์น˜ํ•˜๋Š” ๋‹ค๋ฅธ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ๋งŽ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

BTW: WithStyles๋Š” ๋ชจ๋ฐ”์ผ ์žฅ์น˜์˜ ๋ฒ„ํŠผ์— ๋Œ€ํ•ด ์ตœ๋Œ€ 2,27ms๋ฅผ ์†Œ๋น„ํ•ฉ๋‹ˆ๋‹ค. 8๊ฐœ์˜ ๊ตฌ์„ฑ ์š”์†Œ์™€ 60fps ๋ฏธ๋งŒ์ž…๋‹ˆ๋‹ค.

์‚ฌ์‹ค์ด ์•„๋‹Œ ์ฃผ์žฅ์œผ๋กœ ๊ฐœ์ธ์ ์ธ ๊ฐ€์ •์„ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

๊ฐœ์ธ์ ์ธ ์ถ”์ธก์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ๋น„ํŒ์  ์‚ฌ๊ณ ๋ฅผ ํ•˜๋ ค๊ณ  ๋…ธ๋ ฅํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ฐœ๋…์ ์œผ๋กœ ๋งํ•˜์ž๋ฉด, ์ถ”๊ฐ€ prop ์ˆœํšŒ๋Š” ์ˆœ์ˆ˜ ๋ฒ„์ „์ด ์•„๋‹Œ ๋ฒ„์ „์— ๋น„ํ•ด ์†๋„๋ฅผ ๋Šฆ์ถ”๋ฉฐ ๊ฐ€์น˜ ์žˆ๋Š” ๊ฒƒ์„ ๊ฐ€์ง€์น˜๊ธฐํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. #5628 ๋˜๋Š” https://github.com/react-bootstrap/react-bootstrap/issues/633#issuecomment -234749417 ๋˜๋Š” https://github.com/reactstrap/reactstrap/pull/771#issuecomment -375765577๊ณผ ๊ฐ™์€ ์ถ”๋ก 

์ˆœ์ˆ˜ํ•จ:
capture d ecran 2018-03-27 a 11 43 41

์ˆœ์ˆ˜ํ•œ ์—†์ด:
capture d ecran 2018-03-27 a 11 44 15

์žฌ์ƒ์‚ฐ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • https://codesandbox.io/s/715p7661k1 ์—ด๊ธฐ
  • Chrome์—์„œ ํ”„๋กœํŒŒ์ผ๋Ÿฌ๋ฅผ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.
  • ๋ Œ๋”๋ง ๋ฒ„ํŠผ์„ 5๋ฒˆ ํด๋ฆญ

@oliviertassinari codesandbox๊ฐ€ ๋ชจ๋“  ๊ฒƒ์„ ํ…Œ์ŠคํŠธ์— ์ ํ•ฉํ•˜๊ฒŒ ๋งŒ๋“ ๋‹ค๊ณ  ํ™•์‹ ํ•ฉ๋‹ˆ๊นŒ? ๋‚ด ๊ฒฐ๊ณผ๊ฐ€ ๋งค์šฐ ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์—:

์ˆœ์ˆ˜ํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ(์Šค๋กœํ‹€์ด ์—†์–ด๋„ ๋Š๋ฆผ):
image

์ˆœ์ˆ˜(true๋กœ ๋ณ€๊ฒฝํ•˜๊ณ  ์ €์žฅํ•œ ํ›„ ์ฝ”๋“œ์ƒŒ๋“œ๋ฐ•์Šค์— ๋Œ€ํ•œ ์ƒˆ URL์„ ์–ป์Œ):
image

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

๋‚˜๋Š” ์š”์ ์„ ๋ณธ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด๊ฒƒ์€ ๋งค์šฐ ํฅ๋ฏธ๋กœ์šด ์ ˆ์ถฉ์•ˆ์ž…๋‹ˆ๋‹ค. ํ•œ ์ชฝ์—์„œ๋Š” material-ui์กฐ์ฐจ๋„ "๊ฐ€๋Šฅํ•œ ํ•œ ์œ ์—ฐ ํ•ด์•ผ "ํ•˜์ง€๋งŒ ๋‹ค๋ฅธ ํ•œํŽธ์œผ๋กœ๋Š” ํ˜„์žฌ ์„ฑ๋Šฅ์œผ๋กœ ์ธํ•ด ์ „ํ˜€ _์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค_.

์ˆœ์ˆ˜ ๋ฐ ๋น„์ˆœ์ˆ˜ ๋ฒ„์ „์˜ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ์ƒ๊ฐํ•ด์•ผ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚ด ์•ฑ์ด ๋ฐ์Šคํฌํ†ฑ์—์„œ๋„ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์„ฑ๋Šฅ์„ ์–ป๊ธฐ ์œ„ํ•ด ์ง€๊ธˆ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

@Bessonov ์ฝ”๋“œ ์ƒŒ๋“œ ๋ฐ•์Šค๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ €์žฅ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ diff๊ฐ€ ๋ˆ„๋ฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋งํฌ๋ฅผ ์—…๋ฐ์ดํŠธํ–ˆ์Šต๋‹ˆ๋‹ค.

<Button>
+ <i>
    Button
+ </i>
</Button>

์™œ ๋‹ค๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ์‚ฐ์ถœํ•ด์•ผ ํ•˜๋Š”์ง€ ์ดํ•ด๊ฐ€ ๋˜์ง€ ์•Š์Šต๋‹ˆ๊นŒ? ๋” ๋‚˜์€ ์ฐจํŠธ๋ฅผ ์–ป์—ˆ์ง€๋งŒ ์ˆœ์ˆ˜ํ•˜์ง€ ์•Š์€ ๋ฒ„์ „์€ ํ›จ์”ฌ ๋Š๋ฆฝ๋‹ˆ๋‹ค.

ํŽธ์ง‘: ์•Œ๊ฒ ์Šต๋‹ˆ๋‹ค. ๋ฌด์Šจ ์ผ์ด ์ผ์–ด๋‚˜๊ณ  ์žˆ๋Š”์ง€ ์•Œ์•„ ๋‚ด๋ ค๊ณ  ๋…ธ๋ ฅํ•˜์‹ญ์‹œ์˜ค ...

์•Œ์•˜์–ด ์ด์ œ ์ดํ•ด ํ–ˆ์–ด. "๋ชจ๋“  ๋ Œ๋”์˜ ์ƒˆ ๊ฐœ์ฒด"์™€ ๋™์ผํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ์ „์— ๋ˆˆ์น˜์ฑ„์ง€ ๋ชปํ–ˆ๋‹ค. ์–ด๋–ค ๊ฒฝ์šฐ์—๋Š” babel ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ํ†ตํ•ด ์ž๋™์œผ๋กœ ์ƒ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ธ€์Ž„, ๋‹น์‹ ์€ ์ด๋ฏธ ๊ทธ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค! :D ์ž์ฒด์ ์œผ๋กœ๋Š” ๋งŽ์€ ์ด์ ์ด ์—†์ง€๋งŒ(~7%๋ฅผ ํ‘œ์‹œํ–ˆ์Šต๋‹ˆ๋‹ค) ์œ„์—์„œ ์–ธ๊ธ‰ํ•œ ๋ช‡ ๊ฐ€์ง€ ๊ฒฐํ•จ์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด ์ˆœ์ˆ˜ํ•œ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฒฐ๋ก ์ ์œผ๋กœ ์—ฌ์ „ํžˆ ์ˆ˜์ต์„ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ง€๊ธˆ Pure Wrapper + babel ํ”Œ๋Ÿฌ๊ทธ์ธ + ํ”„๋กœ๋•์…˜ ๋นŒ๋“œ๋กœ ํ…Œ์ŠคํŠธํ–ˆ๋Š”๋ฐ ๋™์ผํ•œ ๋ชจ๋ฐ”์ผ ์žฅ์น˜์—์„œ ๋น ๋ฅด๊ฒŒ ์ธ์ƒ์ ์ž…๋‹ˆ๋‹ค!

๋‚ด๊ฐ€ ๋งํ–ˆ๋“ฏ์ด, ์œ ์—ฐ์„ฑ์„ ์œ„ํ•œ ์ˆœ์ˆ˜ํ•˜์ง€ ์•Š์€ ๊ตฌ์„ฑ ์š”์†Œ์™€ ์„ฑ๋Šฅ์„ ์œ„ํ•œ ์ˆœ์ˆ˜ ๊ตฌ์„ฑ ์š”์†Œ(๋ž˜ํผ๋Š” ๋‹จ์ˆœํ•˜๊ณ  ์œ ์ง€ ๋ณด์ˆ˜๊ฐ€ ์šฉ์ดํ•˜๋„๋ก ์œ ์ง€ํ•˜๊ธฐ์— ์ถฉ๋ถ„ํ•จ)๋ฅผ ๋ชจ๋‘ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์ข‹์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ €์—๊ฒŒ๋Š” ์ „์ฒด ์„ฑ๋Šฅ ํ–ฅ์ƒ์ด ์„ฑ๋Šฅ ๋‹จ์ ๋ณด๋‹ค ํ›จ์”ฌ ํฌ๊ธฐ ๋•Œ๋ฌธ์— ์ˆœ์ˆ˜ํ•œ ๊ตฌ์„ฑ ์š”์†Œ๋งŒ์œผ๋กœ ์‚ด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜๋Š” ๋” ๋‚˜์€: ์ˆœ์ˆ˜ ๊ตฌ์„ฑ ์š”์†Œ ์—†์ด material-ui๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์ข‹์•„, ์ง€๊ธˆ์€ ์ด ์ฃผ์ œ์— ๋Œ€ํ•œ ์ถ”๊ฐ€ ์ž…๋ ฅ์„ ๊ธฐ๋‹ค๋ฆฌ๊ณ  ์žˆ์œผ๋ฉฐ ๋‚ด ์•ฑ์—์„œ ์ž์ฒด ๋ž˜ํผ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

ํ†ต์ฐฐ๋ ฅ ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!

๋‚˜๋Š” transform-react-constant-elements๊ฐ€ ์‹ค์ œ๋กœ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ๊ณ  ์ •๋ง๋กœ ์œ ์šฉํ•˜๋‹ค๋Š” ๊ฒƒ์„ ๋“ค์–ด๋ณธ ์ ์ด ์—†์Šต๋‹ˆ๋‹ค. ๋ฌด์ž‘์œ„ ๋ฏธ์„ธ ์ตœ์ ํ™”๋งŒํผ์€ ๊ดœ์ฐฎ์ง€๋งŒ ์‹ค์ œ๋กœ๋Š” ๋งŽ์€ ๊ฒƒ์„ ์–ป์„ ์ˆ˜ ์žˆ์„ ๋งŒํผ ๊ฐ„๋‹จํ•œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ๋“œ๋ญ…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ <Add /> ์™€ ๊ฐ™์€ ๋ชจ๋“  SVG ์Šคํƒ€์ผ ์•„์ด์ฝ˜ ๊ตฌ์„ฑ ์š”์†Œ์— ๋Œ€ํ•œ ์ตœ์ ํ™”๊ฐ€ ๋‚˜์˜์ง€ ์•Š์„ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์ด ์˜ˆ์ œ๋ฅผ ์‚ดํŽด๋ณด๋ฉด(์ธก๋ฉด์—์„œ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ํด๋ฆญํ•˜๊ณ  "react-constant"๋ฅผ ๊ฒ€์ƒ‰ํ•œ ๋‹ค์Œ "transform-react-constant-elements" ํ™•์ธ๋ž€์„ ํด๋ฆญ) ์ตœ์ ํ™”๋œ ๊ฒƒ์ด ๊ฑฐ์˜ ์—†์Œ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๊ฐ„๋‹จํ•œ ์ •์  InputAdornment ๊ฐ€ ๋งจ ์œ„๋กœ ์ด๋™๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
  • ๊ทธ๋Ÿฌ๋‚˜ ์‚ฌ์†Œํ•˜๊ฒŒ ๊ฐ„๋‹จํ•œ ์ œ์ถœ ๋ฒ„ํŠผ์€ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ๋„ฃ๋Š” ์ˆœ๊ฐ„ ๋” ์ด์ƒ ์ตœ์ ํ™”๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.
  • ๊ทธ๋ฆฌ๊ณ  InputAdornment ์ž์ฒด๊ฐ€ ์ด์ œ ํ˜ธ์ด์ŠคํŠธ๋˜๋Š” ๋™์•ˆ InputProps={{startAdornment: ...}} ๋Š” ์—ฌ์ „ํžˆ ์ธ๋ผ์ธ ์ƒํƒœ์ด๋ฉฐ PureComponent๋ฅผ ๋ถˆ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๋ Œ๋”๋งํ•  ๋•Œ๋งˆ๋‹ค ์ƒˆ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  • ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ classes={{label: classes.runButtonLabel}} ๋Š” PureComponent๊ฐ€ ์‹คํ–‰ ๋ฒ„ํŠผ์„ ์ตœ์ ํ™”ํ•˜๋Š” ๊ฒƒ์„ ๋ถˆ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

์ €๋Š” ๊ฐœ์ธ์ ์œผ๋กœ PureComponent๋ฅผ ์ข‹์•„ํ•˜๊ณ  ์ ˆ๋Œ€์ ์œผ๋กœ ๋ชจ๋“  ๊ณณ์—์„œ ์‚ฌ์šฉํ•˜๊ณ  ์ตœ๋Œ€ํ•œ ์ตœ์ ํ™”ํ•˜์—ฌ ์ž‘๋™ํ•˜๋„๋ก ๋…ธ๋ ฅํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ MUI๊ฐ€ PureComponent๊ฐ€ ์ž‘๋™ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๋งŒ๋“ค์–ด์ง„ ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค.

  • InputProps ์™€ ๊ฐ™์€ *Props ์†Œํ’ˆ์€ MUI ์ž‘๋™ ๋ฐฉ์‹์˜ ๊ธฐ๋ณธ ํŒจํ„ด์ž…๋‹ˆ๋‹ค. ํ•„์š”ํ•  ๋•Œ MUI ๋‚ด๋ถ€๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ๊ณ ๊ธ‰ ๋ฐฉ๋ฒ•์ผ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๊ฐ„๋‹จํ•œ ์‚ฌ์šฉ ์‚ฌ๋ก€์—์„œ ์ •๊ธฐ์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด ํŒจํ„ด์€ ์ผ๋ฐ˜์ ์œผ๋กœ ์ˆœ์ˆ˜ ๋ชจ๋“œ์—์„œ ์ตœ์ ํ™”๋  ์ˆ˜ ์žˆ๋Š” ๋ชจ๋“  ๋ฆฌํ”„ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์ตœ์ ํ™”ํ•  ์ˆ˜ ์—†๋„๋ก ๋งŒ๋“ญ๋‹ˆ๋‹ค.
  • ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ classes={{...}} ํŒจํ„ด์€ PureComponent์—์„œ๋„ ์ž‘๋™ํ•˜์ง€ ์•Š์œผ๋ฉฐ MUI์—์„œ ์Šคํƒ€์ผ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. (๊ทธ๋ฆฌ๊ณ  classes={classes} ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ๋งํ•˜๋Š” ๊ฒƒ์€ ์‹ค์ œ ์†Œ๋น„์ž๊ฐ€ ๊ตฌ์„ฑ ์š”์†Œ์˜ ๋‚ด๋ถ€ ํด๋ž˜์Šค์™€ ๋‹ค๋ฅธ ํด๋ž˜์Šค ์ด๋ฆ„์„ ๊ฐ€์งˆ ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๊ณ  classes ๊ฐ€ ๋‹ค๋ฅธ ์š”์†Œ์˜ ์Šคํƒ€์ผ์„ ์ง€์ •ํ•˜๋Š” ํด๋ž˜์Šค๋„ ํฌํ•จํ•  ๊ฐ€๋Šฅ์„ฑ์ด ๋†’๊ธฐ ๋•Œ๋ฌธ์— ์‹ค์šฉ์ ์ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋™์ผํ•œ ์†Œ๋น„ ๊ตฌ์„ฑ ์š”์†Œ์—์„œ)
  • ์ž์‹์ด ๋งŽ์ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ํ•˜๋‚˜์˜ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๊ฐ–๋Š” ๋Œ€์‹  ์ผ๋ฐ˜์ ์ธ ํŒจํ„ด์€ ์ข…์ข… 2-3์„ ์‚ฌ์šฉํ•˜๊ณ  ๊ทธ ์ค‘ ํ•˜๋‚˜๋งŒ ์ˆœ์ˆ˜ํ•˜๊ฒŒ ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฌด์—‡์ด๋“  ์ตœ์ ํ™”ํ•˜๋ ค๋ฉด ์ด๋Ÿฌํ•œ ๊ทผ๋ณธ์ ์ธ ๋ฌธ์ œ๋ฅผ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๋‹จ์ˆœํžˆ ์‚ฌ๋žŒ๋“ค์ด ์ˆœ์ˆ˜ ๋ชจ๋“œ MUI๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ํ—ˆ์šฉํ•˜๋Š” ๊ฒƒ๋งŒ์œผ๋กœ๋Š” ์‹ค์ œ๋กœ ๋งŽ์ด ์ตœ์ ํ™”๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋‘ ๊ฐ€์ง€ ๊ฐ€๋Šฅ์„ฑ์„ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๋‹ค.

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

  1. ๋‚ด๊ฐ€ ์ƒ๊ฐํ•  ์ˆ˜์žˆ๋Š” ํ•œ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์€ shallowMemoize ๋กœ์ปฌ this ๋ฐ key ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” shallowMemoize ์งง์€ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์–•์€ ๊ฐ™์Œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฉ”๋ชจํ™”ํ•ฉ๋‹ˆ๋‹ค.
  2. ๋‚ด๊ฐ€ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๋Š” ๋˜ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์€ reselect์™€ ๊ฐ™์€ ๊ฒƒ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฉ”๋ชจํ•  ์„ ํƒ๊ธฐ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
  3. 1.์—์„œ shallowMemoize ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ๋˜ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์€ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ render() ์— ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ Œ๋”๋งํ•  ๋•Œ๋งˆ๋‹ค ์ƒˆ ํ•ญ๋ชฉ์„ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๊ณ  key ๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š๊ณ  ๋งˆ์ง€๋ง‰ ๋ Œ๋”๋ง์—์„œ ๋ฉ”๋ชจ์ด์ œ๋œ ๊ฐœ์ฒด๋ฅผ ๋‹ค์‹œ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š”์ง€ ํ™•์ธํ•œ ๋‹ค์Œ ๋ชจ๋“  ์ด์ „ ๊ฐ’์„ ๋ฒ„๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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

import {createSelector} from 'reselect';

class FormPage extends PureComponent {
  state = { example: '' };

  change = e => this.setState({example: e.target.value});
  submit = () => {
    console.log('Submit: ', this.state.example);
  };

  runButtonClasses = createSelector(
    props => props.classes.runButtonLabel,
    runButtonLabel => ({runButtonLabel}));

  render() {
    const {title} = this.props;
    const {example} = this.state;

    return (
      <form>
        {title}
        <TextField
          InputProps={this.shallowMemoize('a', {
            // This example assumes use of transform-react-constant-elements to make this object always the same
            startAdornment: <InputAdornment position="start">Kg</InputAdornment>,
          }}}
          onChange={example}
          value={example} />
        <Button classes={this.runButtonClasses(classes)}>Run</Button>
        <Button onClick={this.submit}>Submit</Button>
      </form>
    );
  }
}
// ...
  <strong i="6">@withShallowMemoize</strong>
  render(memo) {
    const {title} = this.props;
    const {example} = this.state;

    return (
      <form>
        {title}
        <TextField
          InputProps={memo({
            startAdornment: <InputAdornment position="start">Kg</InputAdornment>,
          }}}
          onChange={example}
          value={example} />
        <Button classes={memo(classes)}>Run</Button>
        <Button onClick={this.submit}>Submit</Button>
      </form>
    );
  }

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

์ด๊ฒƒ์ด MUI๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ ๊ถŒ์žฅ๋˜๋Š” ๋ฐฉ๋ฒ•์ด๋ผ๋ฉด ์ˆœ์ˆ˜ ๋ชจ๋“œ๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ณด์‹œ๋‹ค์‹œํ”ผ ์ผ๋ฐ˜์ ์ธ ์‚ฌ์šฉ ์‚ฌ๋ก€์— ๋Œ€ํ•œ ์ž‘์€ ๋„์šฐ๋ฏธ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋งŒ๋“ค๊ธฐ ์‹œ์ž‘ํ•˜์ž๋งˆ์ž ํ•ด๋‹น ๊ตฌ์„ฑ ์š”์†Œ ์ž์ฒด๋Š” ์‰ฝ๊ฒŒ ์ˆœ์ˆ˜ํ•œ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. WeightTextField ์˜ˆ์ œ์—์„œ value ๊ฐ€ ์—ฌ์ „ํžˆ ๋™์ผํ•˜๊ณ , withStyles, InputProps์— ํ•„์š”ํ•œ ๋ฉ”๋ชจ ์ž‘์—… ๋˜๋Š” InputAdornment ์„ค์ •์„ ์™„์ „ํžˆ ๊ฑด๋„ˆ๋›ฐ๋Š” ํ•œ ์ด์ œ WeightTextField ๋Š” ๋‹ค์‹œ ๋ Œ๋”๋ง๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  value ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด ์–ด์จŒ๋“  TextField๋ฅผ ๋‹ค์‹œ ๋ Œ๋”๋งํ•ด์•ผ ํ•˜๋ฏ€๋กœ ์ˆœ์ˆ˜ํ•˜์ง€ ์•Š์€ InputProps={{...}} ๋Š” ์ค‘์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ด ๊ธธ์ด ์ข‹๋‹ค. ๋‚˜๋Š” ์ด๋ก ์ƒ ๋งˆ์ดํฌ๋กœ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์ข‹์•„ํ•ฉ๋‹ˆ๋‹ค. ๋น„๋ก ๋‚ด๊ฐ€ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๋Š” ๊ทธ๊ฒƒ๋“ค์„ ์ž‘์„ฑํ•˜๊ธฐ ์œ„ํ•ด ํ˜„์žฌ ์œ ํšจํ•œ ๋ชจ๋“  ๊ตฌ๋ฌธ/ํŒจํ„ด์„ ์‹ซ์–ดํ•˜์ง€๋งŒ. ๋‚˜๋Š” MyComponent = enhance(MyComponent) ๋ฅผ ์›ํ•˜์ง€ ์•Š๊ณ  ์žฅ์‹ํ•˜๊ณ  ์‹ถ์ง€๋งŒ ์ž‘์€ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ์งง์€ ๋ฐฉ๋ฒ• ์ค‘ ์–ด๋Š ๊ฒƒ๋„ ์žฅ์‹ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋˜ํ•œ import {TextField} from 'material-ui'; ๋ฅผ import WeightTextField from '../../../ui/WeightTextField ;`๋กœ ๋ฐ”๊พธ๋Š” ๊ฒƒ์„ ์‹ซ์–ดํ•ฉ๋‹ˆ๋‹ค.

```js
let WeightTextField = ({unit, InputProps, ...props}) => (
{...์†Œํ’ˆ}
InputProps={{
์‹œ์ž‘์žฅ์‹:{๋‹จ์œ„} ,
...InputProps
}}
onChange={์˜ˆ์ œ}
๊ฐ’={์˜ˆ์ œ} />
);
WeightTextField = ์ˆœ์ˆ˜(WeightTextField);

RunButton = ์ž‘์„ฑ(
withStyles(ํ…Œ๋งˆ => ({
๋ ˆ์ด๋ธ”: {
fontWeight: '800',
},
})),
์ˆœ์ˆ˜ํ•œ
)(๋‹จ์ถ”);

const SubmitButton = ์ˆœ์ˆ˜(๋ฒ„ํŠผ);

ํด๋ž˜์Šค FormPage ํ™•์žฅ ๊ตฌ์„ฑ ์š”์†Œ {
์ƒํƒœ = { ์˜ˆ: '' };

๋ณ€๊ฒฝ = e => this.setState({์˜ˆ: e.target.value});
์ œ์ถœ = () => {
console.log('์ œ์ถœ: ', this.state.example);
};

๋ Œ๋”๋ง() {
const {์ œ๋ชฉ} = this.props;
const {์˜ˆ์ œ} = this.state;

return (
  <form>
    {title}
    <WeightTextField
      unit='Kg'
      onChange={example}
      value={example} />
    <RunButton>Run</RunButton>
    <SubmitButton onClick={this.submit}>Submit</SubmitButton>
  </form>
);

}
}
````

ํฐ ๋ชฉ๋ก์˜ ํŽ˜์ด์ง€์— 500-2000๊ฐœ์˜ ํ™•์ธ๋ž€์„ ํ‘œ์‹œํ•ด์•ผ ํ•˜๋Š” ์‚ฌ์šฉ ์‚ฌ๋ก€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ ๋ธŒ๋ผ์šฐ์ € ํ™•์ธ๋ž€์„ ์‚ฌ์šฉํ•˜๋ฉด ์„ฑ๋Šฅ์€ ๊ดœ์ฐฎ์ง€๋งŒ <Checkbox> ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์„ฑ๋Šฅ์ด ๋งค์šฐ ๋–จ์–ด์ง€๊ณ  ํŽ˜์ด์ง€์˜ ํ™•์ธ๋ž€ ์ˆ˜์— ๋”ฐ๋ผ ์„ ํ˜•์œผ๋กœ ํ™•์žฅ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ: https://codesandbox.io/s/5x596w5lwn

๋‚˜๋Š” mui@next๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค โ€” ์ด๊ฒƒ์„ ์‹คํ–‰ ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด _์ง€๊ธˆ_ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ช‡ ๊ฐ€์ง€ ์ „๋žต์ด ์žˆ์Šต๋‹ˆ๊นŒ?

@์œŒ์Šจ์žญ์Šจ
์ฒซ์งธ, ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ Œ๋”๋งํ•  ๋•Œ๋งˆ๋‹ค ํ™•์ธ๋ž€๋งˆ๋‹ค ์ƒˆ ์ฒ˜๋ฆฌ๊ธฐ๊ฐ€ ์ƒ์„ฑ๋˜์–ด ์ˆ˜ํ–‰ํ•˜๋ ค๋Š” PureComponent ์ตœ์ ํ™”๊ฐ€ ์ตœ์ ํ™”๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

  handleChange = index => event => {
    this.setState({

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

https://codesandbox.io/s/r7l64j6v5n

๋ฌด์—‡์ด๋“  ์ตœ์ ํ™”ํ•˜๋ ค๋ฉด ์ด๋Ÿฌํ•œ ๊ทผ๋ณธ์ ์ธ ๋ฌธ์ œ๋ฅผ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๋‹จ์ˆœํžˆ ์‚ฌ๋žŒ๋“ค์ด ์ˆœ์ˆ˜ ๋ชจ๋“œ MUI๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ํ—ˆ์šฉํ•˜๋Š” ๊ฒƒ๋งŒ์œผ๋กœ๋Š” ์‹ค์ œ๋กœ ๋งŽ์ด ์ตœ์ ํ™”๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋‘ ๊ฐ€์ง€ ๊ฐ€๋Šฅ์„ฑ์„ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๋‹ค.

@dantman ์ด API ์„ ํƒ์€ DX๋ฅผ ์ตœ๋Œ€ํ•œ ๋น ๋ฅด๊ฒŒ ํ•˜๋ฉด์„œ ์ตœ๋Œ€ํ•œ DX๋ฅผ ๊ฐœ์„ ํ•˜๊ธฐ ์œ„ํ•ด ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค.

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

์‘ ์šฐ๋ฆฌ๋Š” ๊ทธ๋ž˜. ๋ž˜ํ•‘ ํŒจํ„ด์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉ์ž ์ •์˜ํ•˜๋Š” ๋ฐ ํ™•์‹คํžˆ ๊ถŒ์žฅ๋˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ์„ฑ๋Šฅ ์ตœ์ ํ™”๋ฅผ ์ ์šฉํ•˜๋„๋ก ํ™•์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ตฌ์„ฑ ์š”์†Œ ์‚ฌ์šฉ์˜ ๊ฐ€๋ณ€์„ฑ์ด ํ›จ์”ฌ ๋‚ฎ์€ ์‚ฌ์šฉ์ž ์˜์—ญ์—์„œ ๋” ์‰ฝ์Šต๋‹ˆ๋‹ค. ๋ฌธ์„œ์—์„œ ์ด ์š”์ ์— ๋Œ€ํ•œ FAQ ์งˆ๋ฌธ์ด๋‚˜ ๊ฐ€์ด๋“œ ์„น์…˜์„ ์ถ”๊ฐ€ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์‘ ์šฐ๋ฆฌ๋Š” ๊ทธ๋ž˜. ๋ž˜ํ•‘ ํŒจํ„ด์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉ์ž ์ •์˜ํ•˜๋Š” ๋ฐ ํ™•์‹คํžˆ ๊ถŒ์žฅ๋˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ์„ฑ๋Šฅ ์ตœ์ ํ™”๋ฅผ ์ ์šฉํ•˜๋„๋ก ํ™•์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ตฌ์„ฑ ์š”์†Œ ์‚ฌ์šฉ์˜ ๊ฐ€๋ณ€์„ฑ์ด ํ›จ์”ฌ ๋‚ฎ์€ ์‚ฌ์šฉ์ž ์˜์—ญ์—์„œ ๋” ์‰ฝ์Šต๋‹ˆ๋‹ค. ๋ฌธ์„œ์—์„œ ์ด ์š”์ ์— ๋Œ€ํ•œ FAQ ์งˆ๋ฌธ์ด๋‚˜ ๊ฐ€์ด๋“œ ์„น์…˜์„ ์ถ”๊ฐ€ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ™•์ธ. ์ด ๊ฒฝ์šฐ:

  • ์ž‘์€ ์ƒํƒœ ๋น„์ €์žฅ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์‰ฝ๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋Š” recompose์™€ ๊ฐ™์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. ์  ์žฅ, ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ recompose์™€ ์œ ์‚ฌํ•˜์ง€๋งŒ recompose์˜ ํŒจํ„ด๊ณผ ๊ฐ™์€ ์ˆœ์ˆ˜ํ•œ ์ƒํƒœ ๋น„์ €์žฅ ๊ธฐ๋Šฅ์„ ๊ตฌ์ถ•ํ•˜์ง€๋งŒ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋งŒํผ ์ข‹์€ ๋‹ค๋ฅธ ํŒจํ„ด์ด๋‚˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์žˆ๋‹ค๊ณ  ๋งํ•ด ์ค€๋‹ค๋ฉด ํ™˜์˜ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.
  • MUI๊ฐ€ ์žˆ๋Š” js ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๋‹ค์–‘ํ•œ ์ž๋™ ์™„์„ฑ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ฐ CSS๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์ œ์•ˆ์„ ๋‚˜์—ดํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ, ๋‹ค์–‘ํ•œ ๊ธฐ์กด ํด๋” ๊ตฌ์„ฑ ํŒจํ„ด ๋ฐ ๊ฒฝ๋กœ ํ•ดํ‚น ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ( ../../../../ui/Foo ๊ฐ€์ ธ์˜ค๊ธฐ๋ฅผ something-local/Foo ์™€ ๊ฐ™์€ ๊ฒƒ์œผ๋กœ ๋ณ€ํ™˜) MUI๋ฅผ ๋ž˜ํ•‘ํ•˜๋Š” ๋งˆ์ดํฌ๋กœ ๊ตฌ์„ฑ ์š”์†Œ์˜ ๋กœ์ปฌ ์‹œ๋ฆฌ์ฆˆ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ import {TextField} from 'material-ui'; ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋งŒํผ ํ›Œ๋ฅญํ•˜๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์œผ๋ฉฐ ๊ฐœ๋ฐœ์ž๊ฐ€ ์‰ฝ๊ฒŒ ํ‡ด๋ณดํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋Š๊ปด์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค. .

@dantman ํ™˜์ƒ์ ์ž…๋‹ˆ๋‹ค. ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

withStyles(๋˜๋Š” ์˜คํžˆ๋ ค JSS)๊ฐ€ ๋งค์šฐ ๋Š๋ฆฌ๊ธฐ ๋•Œ๋ฌธ์— sCU๋ฅผ ์ ์šฉํ•˜๋Š” ๋ฐ ์—ฌ๋Ÿฌ ๋ฒˆ ํ•„์š”ํ–ˆ์Šต๋‹ˆ๋‹ค. JSS์˜ ์ฝ”๋“œ๋Š” ๋ชจ๋ฅด์ง€๋งŒ ๊ฝค ๋งŽ์ด ์ตœ์ ํ™” ๋  ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ styled-components ๋˜๋Š” glamorous๋ฅผ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ ๊ฒฐ๊ตญ JSS์™€ ์•ฑ์—์„œ ๋‹ค๋ฅธ ํ•˜๋‚˜๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ๋‘˜ ๋‹ค JSS๋ณด๋‹ค ์„ฑ๋Šฅ์ด ๋›ฐ์–ด๋‚ฉ๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ๋Š” ์•ฝ๊ฐ„ ์„ฑ๊ฐ€์‹ค ์ˆ˜ ์žˆ์ง€๋งŒ ์•ฑ ์ˆ˜์ค€ sCU ๋˜๋Š” ๋” ์Šค๋งˆํŠธํ•œ ์ƒํƒœ ์—…๋ฐ์ดํŠธ๋กœ ์‰ฝ๊ฒŒ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ์•„์ง ๋ฌธ์ œ๊ฐ€ ๋  ๋งŒํผ ๋Š๋ฆฐ ๋‹จ์ผ MUI ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋ณด์ง€ ๋ชปํ–ˆ๊ณ  ์ƒ๋‹นํ•œ ์‹œ๊ฐ„์ด ์†Œ์š”๋  MUI ๋‚ด๋ถ€์—์„œ ์‹ค์ œ๋กœ ์ฝ”๋”ฉํ•˜์ง€๋„ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

๋” ๋น ๋ฅผ ์ˆ˜ ์—†๊ณ  ๊ฐ๋…์ด ๋œ ํ•„์š”ํ•˜๋‹ค๋ฉด ๋” ์ข‹์„ ๊ฒƒ์ด๋ผ๊ณ  ๋งํ•  ์ˆ˜๋Š” ์—†์ง€๋งŒ ์ ์–ด๋„ ๋‚ด๊ฐ€ ๋ณด๊ธฐ์—๋Š” ์ด ๊ฒฝ์šฐ MUI๋ณด๋‹ค JSS๋ฅผ ์ง์ ‘ ์ตœ์ ํ™”ํ•˜๋Š” ๋ฐ ์‹œ๊ฐ„์„ ๋ณด๋‚ด๋Š” ๊ฒƒ์ด ๋” ๋‚˜์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@Pajn ํ”ผ๋“œ๋ฐฑ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. withStyles ์„ฑ๋Šฅ์— ๋ฌธ์ œ๊ฐ€ ์žˆ๊ฑฐ๋‚˜ styled-components๋ณด๋‹ค ์„ฑ๋Šฅ์ด ๋›ฐ์–ด๋‚œ ์ƒํ™ฉ์„ ๋ณด๋Š” ๊ฒƒ์€ ์ •๋ง ์ข‹์Šต๋‹ˆ๋‹ค.

์•„๋ฌด๋„์ด repo https://github.com/reactopt/reactopt๋ฅผ ํ™•์ธ ํ–ˆ์Šต๋‹ˆ๊นŒ?

$ click - button (text: ู…ู‚ุงู„ุงุช ) => CssBaseline,TransitionGroup,TouchRipple,TransitionGroup,TouchRipple,ScrollbarSize,TransitionGroup,TouchRipple,Ripple,TransitionGroup,TouchRipple,TransitionGroup,TouchRipple,TransitionGroup,TouchRipple,TransitionGroup,TouchRipple,TransitionGroup,TouchRipple,TransitionGroup,TouchRipple,Main,ScrollbarSize,TransitionGroup,TouchRipple,Ripple,TransitionGroup,TouchRipple,TransitionGroup,TouchRipple,TransitionGroup,TouchRipple,TransitionGroup,TouchRipple,TransitionGroup,TouchRipple,TransitionGroup,TouchRipple,TransitionGroup,TouchRipple

์ด๋Ÿฌํ•œ ๊ตฌ์„ฑ ์š”์†Œ๋Š” ๋‹จ์ˆœํ•œ ํด๋ฆญ๋งŒ์œผ๋กœ ๋ถˆํ•„์š”ํ•œ ์žฌ๋ Œ๋”๋ง์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์™œ ๊ตฌ์„ฑ ์š”์†Œ ์—…๋ฐ์ดํŠธ ์ˆ˜๋ช… ์ฃผ๊ธฐ๋ฅผ ์‹œ๋„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๊นŒ?

@nimaa77

์•„๋ฌด๋„์ด repo https://github.com/reactopt/reactopt๋ฅผ ํ™•์ธ ํ–ˆ์Šต๋‹ˆ๊นŒ?
์•„๋‹ˆ์š”, ์—…๋ฐ์ดํŠธ๋ฅผ ์™œ ํ–ˆ์Šต๋‹ˆ๊นŒ? ๋ฐ chrome/react ๊ฐœ๋ฐœ ๋„๊ตฌ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ๊ตฌ์„ฑ ์š”์†Œ๋Š” ๋‹จ์ˆœํ•œ ํด๋ฆญ๋งŒ์œผ๋กœ ๋ถˆํ•„์š”ํ•œ ์žฌ๋ Œ๋”๋ง์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์™œ ๊ตฌ์„ฑ ์š”์†Œ ์—…๋ฐ์ดํŠธ ์ˆ˜๋ช… ์ฃผ๊ธฐ๋ฅผ ์‹œ๋„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๊นŒ?

์œ„์˜ ๋…ผ์˜๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค. ์ด๊ฒƒ์€ ๋ชจ๋“  ์‚ฌ์šฉ ์‚ฌ๋ก€์— ์ ํ•ฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‚˜์—๊ฒŒ material-ui๋Š” ์ˆœ์ˆ˜ ๋ฒ„์ „๊ณผ ์ˆœ์ˆ˜ํ•˜์ง€ ์•Š์€ ๋ฒ„์ „์˜ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋ชจ๋‘ ์ œ๊ณตํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ˆœ์ˆ˜ํ•œ ๊ตฌ์„ฑ ์š”์†Œ๋กœ ์„ฑ๋Šฅ์ด ํฌ๊ฒŒ ํ–ฅ์ƒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

@dantman

์ด ์˜ˆ์ œ๋ฅผ ๋ณด๋ฉด(์ธก๋ฉด์—์„œ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ํด๋ฆญํ•˜๊ณ  "react-constant"๋ฅผ ๊ฒ€์ƒ‰ํ•œ ๋‹ค์Œ "transform-react-constant-elements" ํ™•์ธ๋ž€์„ ํด๋ฆญ) ์ตœ์ ํ™”๋œ ๊ฒƒ์ด ๊ฑฐ์˜ ์—†์Œ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ํ•œ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ผ ๋ฟ์ž…๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์˜ต์…˜, ํ”Œ๋Ÿฌ๊ทธ์ธ ๋ฐ ๊ธฐํƒ€ ์†์œผ๋กœ ๋งŒ๋“  ์ตœ์ ํ™”๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜คํ•ดํ•˜์ง€ ๋งˆ์„ธ์š”. ํ•˜์ง€๋งŒ ์ตœ์ ํ™”๊ฐ€ ์ข‹์€์ง€ ๋‚˜์œ์ง€ ์ด๋ก ์ ์ธ ๋…ผ์˜์—๋Š” ๊ด€์‹ฌ์ด ์—†์Šต๋‹ˆ๋‹ค. WORKS์ธ ์ตœ์ ํ™” ์ž‘์—…์— ๊ด€์‹ฌ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ ์–ด๋„ ๋‚ด ์„ค์ •์—์„œ๋Š”. ๋‚ด๊ฐ€ ์œ„์— ์“ด ๋ชจ๋“  ๊ฒƒ์€ ๋‚˜๋ฅผ ์œ„ํ•ด ์ผํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ์ ์–ด๋„ ์ค‘์ €๊ฐ€ ๋ชจ๋ฐ”์ผ ์žฅ์น˜์—์„œ ๋‚ด ์•ฑ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ๊ตฌ์„ฑ ์š”์†Œ ํŠธ๋ฆฌ ์žฌ์ •๋ ฌ๊ณผ ๊ฐ™์€ ๋” ๋งŽ์€ ์ตœ์ ํ™”๋ฅผ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•˜์ง€๋งŒ ์ˆœ์ˆ˜ํ•œ ๊ตฌ์„ฑ ์š”์†Œ ๋ฐ ๊ธฐํƒ€ ์ž๋™ ์ตœ์ ํ™” ์—†์ด๋Š” ์„ฑ๋Šฅ์„ ๋‹ฌ์„ฑํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์˜ˆ, ์ €๋Š” ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ํ”„๋กœํŒŒ์ผ๋ง๊ณผ ์ตœ์ ํ™”๋ฅผ ๋งค์šฐ ๋งŽ์ด ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

@Bessonov ์•„๋งˆ๋„ ์šฐ๋ฆฌ๋Š” prop์„ ์‚ฌ์šฉํ•˜์—ฌ shouldComponentUpdate ๋ฉ”์†Œ๋“œ๋ฅผ ์–•์€ ๋น„๊ต(https://reactjs.org/docs/shallow-compare.html)๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ฑฐ๋‚˜ ํ•ญ์ƒ false๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ด๊ฒƒ์€ ๋‘ ๊ฐ€์ง€ ๋ฒ„์ „์˜ ๊ตฌ์„ฑ ์š”์†Œ(์ˆœ์ˆ˜ ๋ฐ ์ผ๋ฐ˜)๋กœ ๋ฒˆ๋“ค ํฌ๊ธฐ๋ฅผ ์ฆ๊ฐ€์‹œํ‚ค์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

@lucasljj ์œ„์—์„œ ์–ธ๊ธ‰ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ์ƒํƒœ ์ €์žฅ ๊ตฌ์„ฑ ์š”์†Œ์— ๋Œ€ํ•œ ๋ž˜ํผ๋กœ ์ˆ˜ํ–‰๋˜๋Š” ๊ฒฝ์šฐ ๋ฒˆ๋“ค ํฌ๊ธฐ๊ฐ€ ํฌ๊ฒŒ ์ฆ๊ฐ€ํ•˜์ง€ ์•Š์„ ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋ฉ๋‹ˆ๋‹ค. ์œ„์˜ ํ”„๋กœํ•„๋„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค. ์ˆœ์ˆ˜ํ•œ ๊ตฌ์„ฑ ์š”์†Œ๋งŒ sCU์—์„œ return false; ๋ณด๋‹ค ๋น ๋ฆ…๋‹ˆ๋‹ค.

์ˆœ์ˆ˜ ๊ตฌ์„ฑ ์š”์†Œ ๋˜๋Š” sCU๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๊ตฌ์„ฑ ์š”์†Œ์˜ ๋ฌธ์ œ๋Š” ๋‚ด๋ถ€์— ์ˆœ์ˆ˜ํ•˜์ง€ ์•Š์€ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ children ์ž…๋‹ˆ๋‹ค. ์œ„์˜ ์ง„์ˆ ์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค. ํ•ด๊ฒฐํ•ด์•ผ ํ•  ๋˜ ๋‹ค๋ฅธ ๋ฌธ์ œ๋Š” ํ…Œ๋งˆ ์ „ํ™˜์ž…๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ๋˜์ง€๋Š” ์•Š์•˜์ง€๋งŒ ์ ์–ด๋„ Context API๋กœ ๊ทน๋ณตํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

@bossonov Pure Components๋Š” ํŒŒํ‹ฐ์— ๋Šฆ๊ฒŒ ์™”๊ธฐ ๋•Œ๋ฌธ์—๊ฐ€ ์•„๋‹Œ ๋ฐ˜์‘์˜ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ๊ฐ„์ฃผ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‚˜๋Š” ๋Œ€๋ถ€๋ถ„์˜ ์‚ฌ๋žŒ๋“ค์ด ํ•˜์œ„ ํŠธ๋ฆฌ์—์„œ ๋ถ€์กฑ์„ ์™„ํ™”ํ•˜๋Š” redux ์–‘์‹ ์Šคํƒ€์ผ ๋ž˜ํผ๋ฅผ ๋งŒ๋“ค ๊ฒƒ์ด๋ผ๋Š” ๋ฐ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค.

์ˆœ์ˆ˜ ๊ตฌ์„ฑ ์š”์†Œ์™€ ์ž์‹์— ๊ด€ํ•ด ์–ธ๊ธ‰ํ•œ ๋ฌธ์ œ๋Š” ์ตœ์ƒ์œ„ props๊ฐ€ ์ž์‹์—๊ฒŒ ์ „ํŒŒ๋˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ์—๋งŒ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  prop ๋˜๋Š” state ๋ณ€๊ฒฝ์€ prop์ด ์ „ํŒŒ๋˜์ง€ ์•Š๋Š” ์ˆ˜์ค€๊นŒ์ง€ ์ž์‹ ํŠธ๋ฆฌ๋ฅผ ํ†ตํ•ด ๋‹ค์‹œ ๋ Œ๋”๋ง์„ ํŠธ๋ฆฌ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.
์ˆœ์ˆ˜ํ•œ ๊ตฌ์„ฑ ์š”์†Œ์˜ ์•„์ด๋””์–ด๋Š” ๋ชจ๋“  ์†Œํ’ˆ ๋˜๋Š” ์ƒํƒœ ๋ณ€๊ฒฝ์— ๋Œ€ํ•ด ๋‹ค์‹œ ๋ Œ๋”๋ง๋œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋‚ด๋ถ€๋ฅผ ์ž˜ ๋ชจ๋ฅด์ง€๋งŒ ๋ชจ๋“  ์ž์‹์—๊ฒŒ ์ „๋‹ฌํ•˜๋Š” ๊ตฌ์„ฑ ์š”์†Œ ๋ณ€๊ฒฝ ์†์„ฑ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์ด ๊ถ๊ธˆํ–ˆ์Šต๋‹ˆ๋‹ค. ์ „์ฒด ํŠธ๋ฆฌ๋ฅผ ํ†ตํ•ด ์†Œํ’ˆ์„ ์ „๋‹ฌํ•  ํ•„์š”๊ฐ€ ์—†๋„๋ก ์ด ๋ชฉ์ ์œผ๋กœ ์ƒˆ ์ปจํ…์ŠคํŠธ API๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

@oliviertassinari

์„ฑ๋Šฅ์€ v1 ๋ฆด๋ฆฌ์Šค ์ดํ›„์— ์ค‘์ ์„ ๋‘˜ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ข‹์Šต๋‹ˆ๋‹ค. v1์ด ์ถœ์‹œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. :) ์„ฑ๋Šฅ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ด์•ผ ํ•˜๋Š” ์‹œ์ ์— ๋Œ€ํ•œ ์•„์ด๋””์–ด๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? ์ด ๋ฌธ์ œ๋Š” v1 ์ดํ›„ ์ด์ •ํ‘œ์˜ ์ผ๋ถ€๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค.

@Bessonov ์‹œ๊ฐ„์„ ๋‚ด์–ด ROADMAP์„ ์—…๋ฐ์ดํŠธํ•˜๋Š” ๊ฒƒ์ด ์ข‹์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์„ฑ๋Šฅ์— ๊ด€ํ•ด์„œ. ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ ๋‘ ๊ฐ€์ง€๋ฅผ ์—ผ๋‘์— ๋‘๊ณ  ์žˆ์ง€๋งŒ ๋” ๋งŽ์€ ๊ฒƒ์„ ๋ฐœ๊ฒฌํ•˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.

  1. ์šฐ๋ฆฌ๋Š” ๋ณด์ด์ง€ ์•Š๋Š” ๊ฒƒ์„ ๊ฐœ์„ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋ฒค์น˜๋งˆํฌ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ง€๊ธˆ๊นŒ์ง€ ๋‘ ๊ฐœ์˜ ํฅ๋ฏธ๋กœ์šด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋ณด์•˜์Šต๋‹ˆ๋‹ค.
  2. CSS ์„œ๋ฒ„ ์ธก์„ ๋ Œ๋”๋งํ•˜๋ ค๋ฉด React๊ฐ€ ๋ Œ๋”๋งํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ๊ฒƒ์˜ ~30%๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” style = f(props) ์ง€์›ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค(์Œ, ์•„์ง ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค: #7633). ์šฐ๋ฆฌ๋Š” ๋งค์šฐ ํšจ์œจ์ ์ธ ์บ์‹ฑ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์–ด ๋ฐ˜๋ณต ์š”์ฒญ์— ๋Œ€ํ•œ ๋น„์šฉ์„ 0%์— ๊ฐ€๊น๊ฒŒ ์ค„์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. SSR ์„ฑ๋Šฅ์ด ๋น„์ฆˆ๋‹ˆ์Šค ๋ฉ”ํŠธ๋ฆญ์— ํ•ด๋ฅผ ๋ผ์น˜๋ฉด ์‚ฌ๋ฌด์‹ค์—์„œ ์ž‘์—…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    ๊ทธ๋Ÿฌ๋‚˜ ์ด๊ฒƒ์ด ์œ ์ผํ•œ ์˜ต์…˜์€ ์•„๋‹™๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” (๋ฒˆ๋“ค ํฌ๊ธฐ ์˜ํ–ฅ๊ณผ ๊ท ํ˜•์„ ๋งž์ถ”๊ธฐ ์œ„ํ•ด) ๋Ÿฐํƒ€์ž„ ๋Œ€์‹  ์ปดํŒŒ์ผ ์‹œ๊ฐ„์— ๋น„์šฉ์ด ๋งŽ์ด ๋“œ๋Š” JSS ์‚ฌ์ „ ์„ค์ •์„ ์ ์šฉํ•˜๋Š” Babel ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์ƒ๊ฐํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. cc @kof.

URL์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

์œ„์˜ 1 ๋ฐ ๋งํฌ๋œ #4305์— ์™„์ „ํžˆ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค.

  1. SSR์€ ์ฒซ ํŽ˜์ด์ง€ ๋กœ๋“œ์— ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์ง€๋งŒ ๋Š๋ฆฐ ๋ Œ๋”๋ง์ด๋‚˜ ์ฝ”๋ฅด๋„๋ฐ”์—๋Š” ๋„์›€์ด ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ฐœ์ธ์ ์œผ๋กœ ๋ฐ์Šคํฌํƒ‘์ด๋‚˜ ๋ชจ๋ฐ”์ผ์—์„œ ์ฒ˜์Œ ๋กœ๋“œํ•  ๋•Œ๋Š” ๋ฌด์‹œํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๋Š๋ฆฐ ๋ Œ๋”๋ง์€ ์ฒ˜์Œ ๋กœ๋“œํ•œ ํ›„์—๋„ ๋ชจ๋ฐ”์ผ ์žฅ์น˜์— ์—ฌ์ „ํžˆ ์˜ํ–ฅ์„ ์ค๋‹ˆ๋‹ค.

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

๋˜ ๋‹ค๋ฅธ ๊ฒƒ์€ mui(๋ฐ babel ๋“ฑ)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋” ๋‚˜์€ ์„ฑ๋Šฅ์„ ์–ป๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์ผ์ข…์˜ ๋ฌธ์„œ ๋˜๋Š” ์˜ˆ์ œ ํ”„๋กœ์ ํŠธ์ž…๋‹ˆ๋‹ค.

jss-cache๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

ISTF + ์ „์ฒ˜๋ฆฌ ํŒŒ์ดํ”„๋ผ์ธ์€ ๋ช‡ ms๋ฅผ ๋‹จ์ถ•ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

2018๋…„ 5์›” 19์ผ ํ† ์š”์ผ 19:06 Anton Bessonov [email protected]์ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ผ์Šต๋‹ˆ๋‹ค.

URL์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

1๊ณผ ๋งํฌ๋œ #4305์— ์ „์ ์œผ๋กœ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค.
https://github.com/mui-org/material-ui/issues/4305 ์œ„.

  1. SSR์€ ์ฒซ ํŽ˜์ด์ง€ ๋กœ๋“œ์— ๋„์›€์ด ๋˜์ง€๋งŒ ๋Š๋ฆฐ ๋กœ๋“œ์—๋Š” ๋„์›€์ด ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
    ๋ Œ๋”๋ง ๋˜๋Š” ์ฝ”๋ฅด๋„๋ฐ”. ๊ฐœ์ธ์ ์œผ๋กœ ์ฒ˜์Œ ๋กœ๋“œํ•  ๋•Œ๋Š” ๋ฌด์‹œํ•  ์ˆ˜ ์žˆ์ง€๋งŒ
    ๋ฐ์Šคํฌํƒ‘ ๋˜๋Š” ๋ชจ๋ฐ”์ผ์—์„œ๋„ ๋Š๋ฆฐ ๋ Œ๋”๋ง์€ ์—ฌ์ „ํžˆ โ€‹โ€‹๋ชจ๋ฐ”์ผ ์žฅ์น˜์— ์˜ํ–ฅ์„ ๋ฏธ์นฉ๋‹ˆ๋‹ค.
    ์ฒซ ๋กœ๋”ฉ.

์ปดํŒŒ์ผ ์‹œ๊ฐ„ ์ตœ์ ํ™”๋Š” ํ›Œ๋ฅญํ•  ๊ฒƒ์ด๋ฉฐ ๋‚ด ๊ด€์ ์—์„œ๋Š”
์ฒ˜์Œ ๋กœ๋“œํ•˜๊ณ  ๋‹ค์‹œ ๋ Œ๋”๋งํ•  ๋•Œ ํ–ฅ์ƒ๋  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์„ ํ˜ธ๋ฉ๋‹ˆ๋‹ค.

๋˜ ๋‹ค๋ฅธ ๊ฒƒ์€ mui๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์ผ์ข…์˜ ๋ฌธ์„œ ๋˜๋Š” ์˜ˆ์ œ ํ”„๋กœ์ ํŠธ์ž…๋‹ˆ๋‹ค.
(๋ฐ babel ๋“ฑ) ๋” ๋‚˜์€ ์„ฑ๋Šฅ์„ ์–ป์œผ๋ ค๋ฉด.

jss-cache http://cssinjs.org/jss-cache?v=v3.0.0 ์ด ๋  ์ˆ˜ ์žˆ๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.
์‚ฌ์šฉ ๋œ.

โ€”
๋‹น์‹ ์ด ์–ธ๊ธ‰๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์„ ๋ฐ›๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์ด ์ด๋ฉ”์ผ์— ์ง์ ‘ ๋‹ต์žฅํ•˜๊ณ  GitHub์—์„œ ํ™•์ธํ•˜์„ธ์š”.
https://github.com/mui-org/material-ui/issues/10778#issuecomment-390418709 ,
๋˜๋Š” ์Šค๋ ˆ๋“œ ์Œ์†Œ๊ฑฐ
https://github.com/notifications/unsubscribe-auth/AADOWGrCxNGqrT4MijiX8r9Ad32z6RsJks5t0FEtgaJpZM4S4woq
.

๋ฒค์น˜๋งˆํฌ ์„ค์ •์— ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
https://github.com/A-gambit/CSS-IN-JS-Benchmarks/blob/master/RESULT.md

์˜ค react-jss(material-ui์—์„œ ์‚ฌ์šฉ)๊ฐ€ ๊ฝค ๋Š๋ฆฐ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

@janhoeck ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉฐ, ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์ฆ๋ช…ํ•  ์ˆ˜ ์—†์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ €๋Š” ํ™•์‹ ํ•ฉ๋‹ˆ๋‹ค.

@kof ๋‚˜๋Š” ๋งˆ์ดํฌ๋กœ ๋ฒค์น˜๋งˆํฌ๊ฐ€ ๋งŽ์€ ๊ฒƒ์„ ๋งํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์„ ๊ฝค ์ดํ•ดํ•˜์ง€๋งŒ ์•„ํ”„๋กœ๋””ํ…Œ์— ๋น„ํ•ด 4x-6x๋Š” ์ •๋ง ๋Š๋ฆฝ๋‹ˆ๋‹ค. ์‚ฌ์‹ค material-ui์˜ ์ „์ฒด์ ์ธ ์„ฑ๋Šฅ์€ ๊ทธ๋‹ค์ง€ ๋น›๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

4x-6x๋Š” ์•„ํ”„๋กœ๋””ํ…Œ์— ๋น„ํ•ด ์ •๋ง ๋Š๋ฆฝ๋‹ˆ๋‹ค.

@Bessonov ๋ฒค์น˜๋งˆํฌ ๋ฐฉ๋ฒ•๋ก ์ด ํ•ต์‹ฌ ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‹œ๋„ํ•ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
https://twitter.com/necolas/status/954024318308007937?lang=fr

๋‚ด ๋ธŒ๋ผ์šฐ์ €์˜ ๊ฒฐ๊ณผ:
โš ๏ธ ์ž์‹ ๊ฐ ์—†์ด

capture d ecran 2018-06-12 a 17 58 54

material-ui์˜ ์ „๋ฐ˜์ ์ธ ์„ฑ๋Šฅ์ด ๋น›๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” React ์ž์ฒด์™€ ๊ตฌ์„ฑ ์š”์†Œ ๋น„์šฉ์œผ๋กœ ์ธํ•ด ๋งค์šฐ ์ œํ•œ์ ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@Bessonov ์„ฑ๋Šฅ์„ ํ™•์ธํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•œ ๊ฒƒ์ด ๋ฌด์—‡์ด๋“ , ์•„ํ”„๋กœ๋””ํ…Œ์— ๊ด€ํ•ด์„œ๋Š” ์ตœ๋Œ€ํ•œ ๋นจ๋ฆฌ ์‚ฌ์šฉํ•˜๊ณ  ๋ Œ๋”๋ง์„ ์ง€์—ฐํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์‹ค์ด ์•„๋‹™๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋Œ€๋ถ€๋ถ„์˜ ๋ฒค์น˜๋งˆํฌ๋Š” CPU ์‹œ๊ฐ„์„ ์ธก์ •ํ•˜์ง€๋งŒ ์ตœ์ข… ๋ Œ๋”๋ง ์„ฑ๋Šฅ์€ ์ธก์ •ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. @oliviertassinari๊ฐ€ ๊ฒŒ์‹œํ•œ ๋ฒค์น˜๊ฐ€ ๊ฐ€์žฅ ํ˜„์‹ค์ ์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

MUI ์„ฑ๋Šฅ๊ณผ ๊ด€๋ จํ•˜์—ฌ ์ถ”์ƒํ™”๋ฅผ ์ „ํ˜€ ์‚ฌ์šฉํ•˜์ง€ ์•Š์„ ๋•Œ ๋” ๋นจ๋ผ์งˆ ์ˆ˜ ์žˆ์ง€๋งŒ ์š”์ ์€ ์•„๋‹™๋‹ˆ๋‹ค. MUI ๋‹ค์Œ์€ ๊ฝค ๋น ๋ฆ…๋‹ˆ๋‹ค. ๋งค์šฐ ๋น ๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ์™„์ „ํžˆ ์ž˜๋ชป๋œ ์ž‘์—…์„ ํ•˜๊ฑฐ๋‚˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์˜ค์šฉํ•˜์ง€ ์•Š๋Š” ํ•œ ์„ฑ๋Šฅ์— ๋Œ€ํ•ด ๊ฑฑ์ •ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

@kof ์•„๋‹ˆ์š”, MUI๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋น ๋ฅด์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ˆ˜์šฉ ๊ฐ€๋Šฅํ•œ ์„ฑ๋Šฅ์„ ์–ป์œผ๋ ค๋ฉด ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์„ ๊ตฌํ˜„ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ™•์‹คํžˆ: ๊ณ ๊ธ‰ Mac์šฉ์ด ์•„๋‹ˆ๋ผ ๋ชจ๋ฐ”์ผ ์žฅ์น˜์šฉ์ด๋ผ๋Š” ๊ฒƒ์„ ๋ณด์ง€ ๋ชปํ•˜์…จ์Šต๋‹ˆ๊นŒ?

๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์™„์ „ํžˆ ์ž˜๋ชป ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ์˜ค์šฉํ•˜์ง€ ์•Š๋Š” ํ•œ ์„ฑ๋Šฅ์— ๋Œ€ํ•ด ๊ฑฑ์ •ํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค.

์Œ, ์œ„์˜ ๋ช‡ ๊ฐ€์ง€ codesanbox ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค. ์ปจํ…Œ์ด๋„ˆ์˜ MUI ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ๊ตฌ์„ฑ ์š”์†Œ ๋ฐ๋ชจ์—์„œ์™€ ๊ฐ™์ด ์ž…๋ ฅ ๊ฐ’์„ ์ปจํ…Œ์ด๋„ˆ ์ƒํƒœ์— ์ €์žฅํ•˜๋ฉด ๋งค์šฐ ๋น ๋ฅด๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. PureComponent๋กœ ๊ฐ์‹ธ๊ณ , ์ œ์–ด๋˜์ง€ ์•Š๋Š” ๊ตฌ์„ฑ ์š”์†Œ, ํŠธ๋ฆฌ ์žฌ์ •๋ ฌ, ์ƒ์ˆ˜ ์š”์†Œ, ๋ฉ”๋ชจ ์ž‘์„ฑ ๋“ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ํ—ˆ์šฉ ๊ฐ€๋Šฅํ•œ ์„ฑ๋Šฅ์„ ์œ ์ง€ํ•˜๋„๋ก ๋•์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด (atm ์šฐ๋ฆฌ๋Š” ๋” ์ด์ƒ ์„œ๋ž์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Œ)์—์„œ ๋” ๋‚˜์€ ๊ฒฐ๊ณผ๋ฅผ ์–ป๊ธฐ ์œ„ํ•ด MUI๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
https://codesandbox.io/s/r1ov818nwm

@oliviertassinari ๋งํฌ ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ์€ nexus 4์˜ Chrome 66์— ๋Œ€ํ•œ ๊ฒฐ๊ณผ์ž…๋‹ˆ๋‹ค. ๋ณด์‹œ๋‹ค์‹œํ”ผ ๊ฒฐ๊ณผ๋Š” 10๋ฐฐ ๋” ๋‚˜์ฉ๋‹ˆ๋‹ค. ํšก๋‹จ ๋ณด๋„ 21/ํฌ๋กฌ 51์—์„œ๋Š” ์กฐ๊ธˆ ๋Š๋ฆด ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

screenshot_2018-06-12-18-20-19

์šฐ๋ฆฌ๋Š” React ์ž์ฒด์™€ ๊ตฌ์„ฑ ์š”์†Œ ๋น„์šฉ์œผ๋กœ ์ธํ•ด ๋งค์šฐ ์ œํ•œ์ ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค๋„ ์–ธ๊ธ‰ํ–ˆ๋“ฏ์ด IMHO๋Š” ๋ฐ˜๋“œ์‹œ ๊ทธ๋Ÿฐ ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ๋ชจ๋“  ์žฌ๋ Œ๋”๋ฅผ ํ”ผํ•˜๋ฉด ์„ฑ๋Šฅ๊ณผ ๋ฐฐํ„ฐ๋ฆฌ ์ธก๋ฉด์—์„œ ํฐ ์ด์ ์„ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์žŠ์ง€ ๋งˆ์„ธ์š”. ์„ฑ๋Šฅ์€ ๋กœ๋“œ๋งต์˜ ์„ธ ๋ฒˆ์งธ ์š”์ ์ž…๋‹ˆ๋‹ค.+1:

๊ทธ๋ ‡๊ฒŒ ๋ด: cssinjs๋กœ ํ•˜๋Š” ์ผ์ด ๋ชจ๋ฐ”์ผ ์žฅ์น˜์—์„œ ๋„ˆ๋ฌด ๋Š๋ฆฌ๋‹ค๋ฉด ์ด ๋ฐ˜์‘๊ณผ ๋Œ€๋ถ€๋ถ„์˜ ๋‹ค๋ฅธ ๊ฒƒ๋“ค์—๋„ ์‚ฌ์šฉํ•ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค. cssinjs๊ฐ€ ์†๋„๋ฅผ ๋Šฆ์ถ”๋ฉด ๋ฐ˜์‘ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ์†๋„๋ฅผ ํ›จ์”ฌ ๋” ๋Šฆ์ถฅ๋‹ˆ๋‹ค. ๋ ˆ๋ฒจ ob ์ถ”์ƒํ™”๋ฅผ ์žฌ๊ณ ํ•˜๊ฑฐ๋‚˜ ์ตœ์ ํ™”๋ฅผ ์ ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

@oliviertassinari ๋Š” ๊ทธ evtl์ž…๋‹ˆ๋‹ค. ์—…๋ฐ์ดํŠธ ์‹œ mui ๋ž˜ํผ๊ฐ€ jss ์Šคํƒ€์ผ์„ ๋‹ค์‹œ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ์ž ์žฌ์ ์œผ๋กœ ๋ถˆํ•„์š”ํ•œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์ผ๋ถ€ ๋ˆ„์ถœ์ด ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@kof

๊ทธ๋ ‡๊ฒŒ ๋ด [...]

๋„ˆ์˜ ์˜๋„๋ฅผ ์•Œ ๊ฒ ์–ด. ๊ทธ๋Ÿฌ๋‚˜ ๋ฐ˜์‘ํ•˜๊ณ  ๋ฐ˜์‘ํ•˜๋Š” (์ˆœ์ˆ˜) ๊ตฌ์„ฑ ์š”์†Œ๋Š” ๊ทธ ์ž์ฒด๋กœ ๋ณ‘๋ชฉ ํ˜„์ƒ์ด ์•„๋‹ˆ๋ฉฐ ๋งค์šฐ ์ž˜ ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, MUI๋Š” PureComponent๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์ง€๋งŒ(์œ„์—์„œ ์„ค๋ช…ํ•œ ์žฅ๋‹จ์ ์ด ์žˆ์Œ) ์šฐ๋ฆฌ์˜ ์‚ถ์„ ๋” ์•ˆ์ „ํ•˜๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. @oliviertassinari ๋Š” ์บ์‹œ ๋˜๋Š” ์‚ฌ์ „ ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋” ๋‚˜์€ ์„ฑ๋Šฅ์„ ์–ป์„ ์ˆ˜ ์žˆ๋Š” ๊ธฐํšŒ๊ฐ€ ์–ธ๊ธ‰ ํ–ˆ์Šต๋‹ˆ๋‹ค.

์˜คํ•ดํ•˜์ง€ ๋งˆ์„ธ์š”. ์—ฌ๋Ÿฌ๋ถ„์€ ๋ฉ‹์ง„ ์‚ฌ๋žŒ๋“ค์ด๋ฉฐ ๋ชจ๋“  MUI ๋ฆด๋ฆฌ์Šค์— ๋Œ€ํ•ด ์ •๋ง ๋งŒ์กฑํ•ฉ๋‹ˆ๋‹ค. ๋ฐ•์ˆ˜: ํ•˜์ง€๋งŒ ๋ชจ๋“  ์‚ฌ์šฉ์ž๊ฐ€ ๊ณ ์„ฑ๋Šฅ ๋ฐ์Šคํฌํ†ฑ์„ ํ†ตํ•ด ์›น์‚ฌ์ดํŠธ๋ฅผ ๋ฐฉ๋ฌธํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ์„ฑ๋Šฅ๋„ ๊ณ ๋ คํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋ฐ˜์‘์ด ์„ฑ๋Šฅ ๋ณ‘๋ชฉ ํ˜„์ƒ์ด ์•„๋‹ˆ๊ณ  ๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ํ™•์‹ ํ•œ๋‹ค๋ฉด JSS๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค. ๋ถˆํ•„์š”ํ•œ ์ž‘์—…์ด ์ง„ํ–‰ ์ค‘์ด๊ณ  ์—…๋ฐ์ดํŠธ ์‹œ CSS๊ฐ€ ์žฌ์ƒ์„ฑ๋˜๋Š” ๊ฒฝ์šฐ ์œ ํšจ์„ฑ์„ ๊ฒ€์‚ฌํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ์„ ์ƒ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์œ ์ผํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ˆœ์ˆ˜ ๊ตฌ์„ฑ ์š”์†Œ๋Š” ์ตœ์ ํ™”๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ ์ˆ˜์ค€ ์ฝ”๋“œ์—์„œ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. MUI๋Š” ์ด๋ฅผ ์ˆ˜ํ–‰ํ•  ํ•„์š”๊ฐ€ ์—†์œผ๋ฉฐ ์ผ๋ฐ˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋ฏ€๋กœ ์–ด๋– ํ•œ ๊ฐ€์ •๋„ ํ•ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค. PureComponent๊ฐ€ ํ•ญ์ƒ ์ข‹์€ ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค.

JSS๋Š” ์ฒซ๋‚ ๋ถ€ํ„ฐ ์„ฑ๋Šฅ์„ ๊ณ ๋ คํ–ˆ์œผ๋ฉฐ ๋งˆ์ดํฌ๋กœ ์ตœ์ ํ™”์— ๋์—†๋Š” ์‹œ๊ฐ„์„ ๋ณด๋ƒˆ์Šต๋‹ˆ๋‹ค.

์ด๊ฑด ๋ง๋„ ์•ˆ๋ผ. ๋ชจ๋“  ๋‹จ์ผ ์ƒํ˜ธ ์ž‘์šฉ์—์„œ ์žฌ๋ฃŒ UI ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ๋‹ค์‹œ ๋ Œ๋”๋ง๋˜๋Š” ๊ฒƒ์„ ๋ง‰์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ํ•˜๋Š” ์ผ์€ ์ค‘์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

class RowText extends Component {
  shouldComponentUpdate = (nextProps, nextState) => {
    return false;
  };

  render() {
    const { title, artist } = this.props;
    return <ListItemText primary={title} secondary={artist} />;
  }
}

ํŠธ๋ฆฌ๊ฑฐ๋Š” ๊ธฐ๋ณธ Typography ์š”์†Œ๋ฅผ ๋‹ค์‹œ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. ์–ด๋–ป๊ฒŒ ์ด๊ฒƒ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๊นŒ?

์ด๋ด, ์ด๊ฒƒ์€ ๋ชฉ๋ก๊ณผ ๋ชฉ๋ก ํ•ญ๋ชฉ์—์„œ๋งŒ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์™œ์š” ? ๋‚ด๊ฐ€ ํ•  ์ˆ˜ ์žˆ๋Š” ์ผ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

@ danielo515 ์ „์ฒด ์˜ˆ๊ฐ€ ์—†์œผ๋ฉด ๋งํ•˜๊ธฐ ์–ด๋ ต์Šต๋‹ˆ๋‹ค. List ๊ตฌ์„ฑ ์š”์†Œ๋„ ์ปจํ…์ŠคํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ ํ•ด๋‹น ๊ฐ’๋„ ๋ณ€๊ฒฝํ•˜๋ฉด ๋‹ค์‹œ ๋ Œ๋”๋ง์ด ํŠธ๋ฆฌ๊ฑฐ๋ฉ๋‹ˆ๋‹ค.

@eps1lon์€ ์ดํ•ดํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ปจํ…์ŠคํŠธ์˜ ๋ณ€ํ™”๊ฐ€ ์–ด๋–ป๊ฒŒ ์ผ์–ด๋‚  ์ˆ˜ ์žˆ๋Š”์ง€ ์„ค๋ช…ํ•ด ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ๋‚˜๋Š” ๋ชฉ๋ก ๊ตฌ์„ฑ ์š”์†Œ์— ์•„๋ฌด ๊ฒƒ๋„ ์ „๋‹ฌํ•˜์ง€ ์•Š๊ณ  ๊ทธ ์•ˆ์— ์žƒ์–ด๋ฒ„๋ฆฐ ์ž์‹์„ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค.

@danielo515 ๊ธฐ๋ณธ์ ์œผ๋กœ List ๋ Œ๋”๋ง๋  ๋•Œ๋งˆ๋‹ค. ์ƒˆ๋กœ์šด ์ปจํ…์ŠคํŠธ API๋Š” ์ปจํ…์ŠคํŠธ ๊ฐ’์„ ๋ฉ”๋ชจํ•˜์—ฌ ํƒ์ƒ‰ํ•  ์ˆ˜ ์žˆ๋Š” ๋ช‡ ๊ฐ€์ง€ ์ตœ์ ํ™” ์ „๋žต์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ–ˆ์Šต๋‹ˆ๋‹ค.

ํ˜„์žฌ ๋ฐ˜์‘ํ•˜๋Š” ์ปจํ…์ŠคํŠธ API๋Š” ๊ฐ’์ด WRT๋ฅผ ์—„๊ฒฉํ•œ ํ‰๋“ฑ์œผ๋กœ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒฝ์šฐ ๋ชจ๋“  ์†Œ๋น„์ž์— ๋Œ€ํ•ด ๋‹ค์‹œ ๋ Œ๋”๋ง์„ ํŠธ๋ฆฌ๊ฑฐํ•ฉ๋‹ˆ๋‹ค. List ์— ๋Œ€ํ•œ ๋ชจ๋“  ๋ Œ๋”๋ง ํ˜ธ์ถœ์—์„œ ์ƒˆ ๊ฐœ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ชจ๋“  ์†Œ๋น„์ž๋„ ๋‹ค์‹œ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ์ง€๊ธˆ์€ ์‰ฝ๊ฒŒ ์„ฑ๋Šฅ ํ–ฅ์ƒ์„ ์œ„ํ•ด List ๋ฅผ ๋ž˜ํ•‘ํ•˜์—ฌ ์ž์ฃผ ๋‹ค์‹œ ๋ Œ๋”๋งํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ฒค์น˜๋งˆํฌ๋ฅผ ๋จผ์ € ์ˆ˜ํ–‰ํ•˜๊ฑฐ๋‚˜ ๋” ์ผ์ฐ ๋ Œ๋”๋ง์„ ์ค‘๋‹จํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ๋ฐ˜๋ณต์ ์ธ ๋ Œ๋”๋ง ํ˜ธ์ถœ Typography ์€ ๊ทธ๋ ‡๊ฒŒ ๋‚˜์˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

React.memo ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋ž˜ํ•‘ํ•˜๋ฉด ์ž์‹์ด ์—†๋Š” ๋ชจ๋“  ๊ฒฝ์šฐ์— ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. 3๊ฐœ์˜ ExpansionPanel๊ณผ 14๊ฐœ์˜ FormControl์ด ์žˆ๋Š” ์–‘์‹์ด ์žˆ๋Š”๋ฐ ๋ฐ์Šคํฌํƒ‘์—์„œ ์ง€์—ฐ๋ฉ๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ์„ฑ๋Šฅ ๋ฌธ์ œ์— ๋Œ€ํ•œ ์†”๋ฃจ์…˜์ด ์—†์œผ๋ฉด material-ui๋ฅผ ๊ณ„์† ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

@prevostc ์˜ˆ๊ฐ€ ์—†์œผ๋ฉด ๋ฌด์—‡์ด ์ž˜๋ชป๋˜์—ˆ๋Š”์ง€ ๋งํ•˜๊ธฐ ์–ด๋ ต์Šต๋‹ˆ๋‹ค.

@prevostc codeandbox ์žฌ์ƒ์‚ฐ์„ ๋ณด์ง€ ์•Š๊ณ  ์ด๊ฒƒ์ด์ด ๋ฌธ์ œ์™€ ๊ด€๋ จ์ด ์žˆ๋Š”์ง€ ์šฐ๋ฆฌ๋„ ๋‹น์‹ ๋„ ์•Œ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

@prevostc ์ž์‹์„ ํ•„์š”๋กœ ํ•˜์ง€ ์•Š๋Š” ์ž์‹ ๋งŒ์˜ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋ฉ”๋ชจ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ฆ‰, ๋ฐ์ดํ„ฐ/์ด๋ฒคํŠธ ์†Œํ’ˆ์„ ์‚ฌ์šฉํ•˜์ง€๋งŒ ์ž์‹์€ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ๋‹จ์ผ ํ™•์žฅ ํŒจ๋„์„ ๋ Œ๋”๋งํ•˜๋Š” ์—ญํ• ์„ ํ•˜๋Š” ๊ณ ์œ ํ•œ ์ˆœ์ˆ˜/memoed MyExpansionPanel ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ํ•ด๋‹น <MyExpansionPanel ... /> ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ ํ™•์žฅ ํŒจ๋„์„ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ๋‹ค์‹œ ๋ Œ๋”๋ง์€ ๋‹จ์ผ ํ™•์žฅ ํŒจ๋„๋กœ ์ œํ•œ๋ฉ๋‹ˆ๋‹ค(๋˜๋Š” ๋‘ ํŒจ๋„ ๊ฐ„์— ์ „ํ™˜ํ•  ๋•Œ ๋‘ ํŒจ๋„).

@oliviertassinari @kof @dantman
๋‹ค์Œ์€ ๋‚ด ์„ฑ๋Šฅ ๋ฌธ์ œ์˜ ์ฝ”๋“œ์ƒŒ๋“œ๋ฐ•์Šค ์žฌ์ƒ์‚ฐ์ž…๋‹ˆ๋‹ค. https://codesandbox.io/s/yvv2y2zxxx

์‚ฌ์šฉ์ž ์ž…๋ ฅ์— ์•ฝ๊ฐ„์˜ ์ง€์—ฐ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ~20๊ฐœ์˜ ํ•„๋“œ(์ผ๋ฐ˜์ ์ด์ง€๋Š” ์•Š์Œ)๊ฐ€ ์žˆ๋Š” ์–‘์‹์ž…๋‹ˆ๋‹ค. ๋Š๋ฆฐ ์žฅ์น˜์—์„œ๋Š” ์ด ์–‘์‹์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์„ฑ๋Šฅ ๋ฌธ์ œ๋Š” ์‚ฌ์šฉ์ž ์ž…๋ ฅ์— ๋Œ€ํ•œ ๋Œ€๊ทœ๋ชจ ๋‹ค์‹œ ๋ Œ๋”๋ง์—์„œ ๋ฐœ์ƒํ•˜์ง€๋งŒ ์ˆœ์ˆ˜ํ•œ ๊ตฌ์„ฑ ์š”์†Œ(React.memo)์— MUI ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋ž˜ํ•‘ํ•˜๋ฉด ์—ฌ๊ธฐ์— ์žˆ๋Š” ๋ชจ๋“  ํ•ญ๋ชฉ์— ์ž์‹๊ณผ ์ž์‹์ด ์žˆ์œผ๋ฏ€๋กœ ์•„๋ฌด ์ž‘์—…๋„ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋Š” AFAIK๋ฅผ ๋‹ค์‹œ ๋ Œ๋”๋งํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(์ถœ์ฒ˜: https:// reactjs.org/docs/react-api.html#reactpurecomponent)

์•„๋ž˜๋Š” ๋‚ด ์ˆ˜๋™ ๋ฒค์น˜๋งˆํฌ์˜ ์ผ๋ถ€ ์Šคํฌ๋ฆฐ์ƒท์ž…๋‹ˆ๋‹ค. ํ•˜๋‚˜๋Š” ์ตœ์ ํ™”๋˜์ง€ ์•Š์€ ๊ฒƒ, ํ•˜๋‚˜๋Š” ๋ชจ๋“  ๊ฒƒ์„ ๋ฉ”๋ชจํ•œ ๊ฒƒ, ๋‹ค๋ฅธ ํ•˜๋‚˜๋Š” ์ „์ฒด ์–‘์‹์—์„œ ์ƒํƒœ๋ฅผ ๋„ˆ๋ฌด ์ž์ฃผ ์„ค์ •ํ•˜์ง€ ์•Š๋„๋ก ๋กœ์ปฌ ์ƒํƒœ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ์ž ์ง€์ • ์ž…๋ ฅ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
๊ฐ ๊ตฌ์„ฑ์—์„œ ์‚ฌ์šฉ์ž ์ž…๋ ฅ ์กฐ์ •์€ ์•ฝ 60ms๊ฐ€ ๊ฑธ๋ฆฝ๋‹ˆ๋‹ค(60fps์—์„œ ๋ Œ๋”๋งํ•ด์•ผ ํ•˜๋Š” 16ms๋ณด๋‹ค ํ›จ์”ฌ ๋†’์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” MUI๋ฅผ ์‚ฌ๋ž‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋‚ด๊ฐ€ ๋ญ”๊ฐ€ ์ž˜๋ชปํ–ˆ๋‹ค๋Š” ๊ฒƒ์„ ๊ธฐ๊บผ์ด ์•Œ๊ฒŒ ๋  ๊ฒƒ์ด๊ณ  ์‰ฌ์šด ์ˆ˜์ •์ด ์—†๋‹ค๋ฉด ์Šฌํ”Œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. <3

@dantman React.ReactNode ๋ฅผ ์ž…๋ ฅ(์ž์‹ ๋˜๋Š” ์†Œํ’ˆ)์œผ๋กœ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ExpansionPanel ๋ฅผ ์–ด๋–ป๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ๋‚ด ์•ฑ์˜ ๋ชจ๋“  ํŒจ๋„์— ๋Œ€ํ•ด ํŠน์ • ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์ž‘์„ฑํ•ด์•ผ ํ•œ๋‹ค๋Š” ์˜๋ฏธ์ธ ๊ฒฝ์šฐ ๋ถˆํ–‰ํžˆ๋„ ์ด๋Ÿฌํ•œ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ๋„ˆ๋ฌด ๋งŽ์Šต๋‹ˆ๋‹ค.

screenshot 2018-12-20 at 22 04 08

screenshot 2018-12-20 at 21 56 57

screenshot 2018-12-20 at 22 05 00

@dantman React.ReactNode ๋ฅผ ์ž…๋ ฅ(์ž์‹ ๋˜๋Š” ์†Œํ’ˆ)์œผ๋กœ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ExpansionPanel ๋ฅผ ์–ด๋–ป๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ๋‚ด ์•ฑ์˜ ๋ชจ๋“  ํŒจ๋„์— ๋Œ€ํ•ด ํŠน์ • ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์ž‘์„ฑํ•ด์•ผ ํ•œ๋‹ค๋Š” ์˜๋ฏธ์ธ ๊ฒฝ์šฐ ๋ถˆํ–‰ํžˆ๋„ ์ด๋Ÿฌํ•œ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ๋„ˆ๋ฌด ๋งŽ์Šต๋‹ˆ๋‹ค.

์˜ˆ, ๊นŠ์ด ์ค‘์ฒฉ๋œ ํŒจ๋„ ํŠธ๋ฆฌ๋กœ ํ•˜๋‚˜์˜ ๊ฑฐ๋Œ€ํ•œ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋งŒ๋“œ๋Š” ๋Œ€์‹  ํ™•์žฅ ํŒจ๋„ ์กฐ๊ฐ์„ ๊ตฌ์„ฑ ์š”์†Œ๋กœ ๋ถ„๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๊ฑฐ๋Œ€ํ•œ ๋‚˜๋ฌด๋ฅผ ์ตœ์ ํ™”ํ•˜๋Š” ๊ฒƒ์€ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

๋ถˆ๊ฐ€๋Šฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. React ์ปดํฌ๋„ŒํŠธ๋Š” ๋งค์šฐ ๊ฐ€๋ณ์Šต๋‹ˆ๋‹ค. ๋ฐฉ๋Œ€ํ•œ ๊ตฌ์„ฑ ์š”์†Œ์˜ ์ฝ”๋“œ ๋ธ”๋ก์„ ๋ณต์‚ฌํ•˜์—ฌ ํ•จ์ˆ˜์— ๋ถ™์—ฌ๋„ฃ์œผ๋ฉด ๊ฑฐ์˜ ์™„๋ฃŒ๋ฉ๋‹ˆ๋‹ค. ๊ทธ ๋‹ค์Œ์—๋Š” ์†Œํ’ˆ์„ ์—ฐ๊ฒฐํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ทธ ๊ธฐ๋Šฅ์„ ํ•˜๊ณ  props์˜ ์ˆœ์ˆ˜ํ•œ ์ตœ์ ํ™”๋ฅผ ๊นจ๋œจ๋ฆฌ๋Š” ๊ฒƒ๋“ค์„ ์ „๋‹ฌํ•˜์ง€ ์•Š๋Š” ํ•œ React.memo๋Š” ๋งค์šฐ ์‰ฝ๊ฒŒ ์ตœ์ ํ™”๋ฉ๋‹ˆ๋‹ค.

ํฐ ๊ตฌ์„ฑ ์š”์†Œ์—์„œ ์ฒญํฌ๋ฅผ ๋ถ„๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์ž‘์€ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒฝ์šฐ ๊ธฐ์–ตํ•˜์‹ญ์‹œ์˜ค. ์ž์ฒด ํŒŒ์ผ ๋ฐ ์ž์ฒด prop ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ํ†ตํ•ด ๋ณต์žกํ•  ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค. propTypes ์—†์ด ์‚ฌ์šฉ๋˜๋Š” ๊ตฌ์„ฑ ์š”์†Œ์™€ ๋™์ผํ•œ ํŒŒ์ผ์— ์žˆ๋Š” ๋‹จ์ˆœ ๊ธฐ๋Šฅ ๊ตฌ์„ฑ ์š”์†Œ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰, ๋™์ผํ•œ ํŒŒ์ผ์˜ ๊ตฌ์„ฑ ์š”์†Œ์—์„œ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ž‘์€ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ, Material UI๋Š” ๋‚ฎ์€ ์ˆ˜์ค€์˜ dom ์š”์†Œ๋ณด๋‹ค ์•ฝ๊ฐ„ ๋Š๋ฆฝ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ MUI Input ๊ฐ€ raw input ๋ณด๋‹ค 10๋ฐฐ ๋Š๋ฆฌ๊ณ  100 ์ดํ›„ ๋„ˆ๋ฌด ๋Š๋ ค์กŒ๋‹ค๊ณ  ํ•ด๋„ MUI๊ฐ€ ์—†์–ด๋„ ์—ฌ์ „ํžˆ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ๊ทธ๊ฒƒ์ด 10๋ฐฐ ๋” ๋น ๋ฅด๋”๋ผ๋„ raw input ๋Š” 1000๊ฐœ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ์‚ฌ์ดํŠธ๋ฅผ ๋˜‘๊ฐ™์ด ๋Š๋ฆฌ๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค. MUI๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ์—๋„ React์—์„œ ๋‹จ์ผ ๋ชจ๋†€๋ฆฌ์‹ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. React๊ฐ€ ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ๊ณ„๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋„๋ก ์•ฑ์„ ์ ๋‹นํ•œ ํฌ๊ธฐ์˜ ์ฒญํฌ๋กœ ๋ถ„ํ• ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

@prevostc ํ™•์žฅ ํŒจ๋„์„ ๋™์ผํ•œ ํŒŒ์ผ ๊ตฌ์„ฑ ์š”์†Œ๋กœ ๋ถ„ํ• ํ•˜์—ฌ ์ตœ์ ํ™”ํ•œ ๋ฐ๋ชจ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋ณด์‹œ๋‹ค์‹œํ”ผ ์ž…๋ ฅ์ด ์—…๋ฐ์ดํŠธ๋˜๋ฉด ํ•˜๋‚˜์˜ ํ™•์žฅ ํŒจ๋„๋งŒ ๋‹ค์‹œ ๋ Œ๋”๋ง๋ฉ๋‹ˆ๋‹ค. ๊ด€๋ จ ์—†๋Š” ํ™•์žฅ ํŒจ๋„์„ ๋‹ค์‹œ ๋ Œ๋”๋งํ•˜๋Š” ๋ฐ ์‹œ๊ฐ„์ด ๋‚ญ๋น„๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์›ํ•˜๋Š” ๊ฒฝ์šฐ ์œ ์‚ฌํ•œ ํŒจํ„ด์„ ๊ณต์œ ํ•˜๋Š” ์ž…๋ ฅ๊ณผ ์œ ์‚ฌํ•œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜๋„ ์žˆ์œผ๋ฏ€๋กœ ๊ด€๋ จ ์—†๋Š” ์ž…๋ ฅ๋„ ๋‹ค์‹œ ๋ Œ๋”๋ง๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ๋‹จ์ง€ ์ข‹์€ ์ตœ์ ํ™” ํŒจํ„ด์ด ์•„๋‹ˆ๋ผ ์ข‹์€ ์ฝ”๋”ฉ ํŒจํ„ด์ด๋ผ๋Š” ์ ์— ์ฃผ๋ชฉํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์‹ค์ œ ์ฝ”๋“œ์—์„œ ์ž…๋ ฅ ๋ฐฐ์—ด์„ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์ •์˜๋œ ์ด๋ฆ„, ๋ ˆ์ด๋ธ” ๋ฐ ๋ชฉ์ ์œผ๋กœ ์ž…๋ ฅ์„ ๋ช…์‹œ์ ์œผ๋กœ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค. ๊ฒฝ๊ณ„์™€ ๋ฐ˜๋ณต ํŒจํ„ด์„ ์ฐพ๋Š” ๊ฒƒ์€ ์‚ฌ๋ฌผ์„ ์ตœ์ ํ™”ํ•  ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ƒ์šฉ๊ตฌ๋ฅผ ์ค„์—ฌ ์ฝ”๋“œ๋ฅผ ๋” ๊ฑด์กฐํ•˜๊ณ  ์ฝ๊ธฐ ์‰ฝ๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์ฆ‰, InputWrapper ๋Œ€์‹  FormControl+InputLabel+FormHelperText+Input ์ฝค๋ณด๋ฅผ ์ž‘์€ ๋กœ์ปฌ SimpleTextInput ๊ตฌ์„ฑ ์š”์†Œ๋กœ ๋ถ„๋ฆฌํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋Š” ์ตœ์ ํ™”(๊ด€๋ จ ์—†๋Š” ์ž…๋ ฅ์ด ๋‹ค์‹œ ๋ Œ๋”๋ง๋˜์ง€ ์•Š์Œ)ํ•  ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ฝ”๋“œ๊ฐ€ ์ถ”๊ฐ€ ์ƒ์šฉ๊ตฌ๋ฅผ ๋ฐ˜๋ณตํ•  ํ•„์š”๊ฐ€ ์—†์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

https://codesandbox.io/s/0o7vw76wzp

screen shot 2018-12-20 at 2 51 31 pm

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

๋ฌธ์•ˆ ์ธ์‚ฌ

์ž ์—ฌ๊ธฐ ์—…๋ฐ์ดํŠธ๋œ ์ŠคํŠธ๋ ˆ์Šค ํ…Œ์ŠคํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. https://codesandbox.io/s/wz7yy1kvqk

์ด ์ผ๋ฐ˜์ ์ธ ์ ์—์„œ @dantman ์— ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. https://github.com/mui-org/material-ui/issues/10778#issuecomment -449153635 ํ•˜์ง€๋งŒ ์ด ์ ์€ ์–‘์˜ ๊ตฌ์„ฑ ์š”์†Œ์—์„œ ์ด๋Ÿฌํ•œ ์„ฑ๋Šฅ ๋ฌธ์ œ๋ฅผ ์˜ˆ์ƒํ•˜์ง€๋Š” ์•Š์•˜์ง€๋งŒ ์„ฑ๋Šฅ ๋ฌธ์ œ์˜ ์›์ธ์„ ์ฐพ์•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

JSS๊ฐ€ ๋Š๋ฆฐ๊ฐ€์š”? (์Šคํฌ์ผ๋Ÿฌ ์ฃผ์˜: ์—†์Œ)

์ด ์Šค๋ ˆ๋“œ์˜ ์ด์ „ ์ฃผ์„ ์ค‘ ์ผ๋ถ€๋ฅผ ์ฐธ์กฐํ•˜์—ฌ withStyles ๋ชจ๋“  ํ˜ธ์ถœ์„ ์ œ๊ฑฐํ•˜๊ธฐ ์œ„ํ•ด ์ŠคํŠธ๋ ˆ์Šค ํ…Œ์ŠคํŠธ์— ํ™•์ธ๋ž€์„ ์ถ”๊ฐ€ํ–ˆ์œผ๋ฉฐ JSS๊ฐ€ ๋น ๋ฅด๋ฉฐ ์„ฑ๋Šฅ ๋ฌธ์ œ์˜ ์›์ธ์ด ์•„๋‹ˆ๋ผ๋Š” ๊ฒฐ๋ก ์— ๋„๋‹ฌํ–ˆ์Šต๋‹ˆ๋‹ค. ( @kof ๊ฐ€ https://github.com/mui-org/material-ui/issues/10778#issuecomment-396609276์—์„œ ์ง€์ ํ–ˆ๋“ฏ์ด).

screenshot 2018-12-22 at 15 17 26

์ˆ˜์ •

๋‚ด ํŠน์ • ์‚ฌ์šฉ ์‚ฌ๋ก€์˜ ๊ฒฝ์šฐ ์‹ค์ œ๋กœ ํ•˜๋‚˜์˜ ์ž…๋ ฅ๋งŒ ๋ณ€๊ฒฝ๋˜์—ˆ์Œ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ์–‘์‹ ์—…๋ฐ์ดํŠธ ์‹œ ๊ฐ ์–‘์‹ ์ž…๋ ฅ์ด ๋‹ค์‹œ ๋ Œ๋”๋ง๋œ๋‹ค๋Š” ๋ฌธ์ œ๋ฅผ ์ •ํ™•ํžˆ ์ง€์ ํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.
์•„๋ž˜ ์Šคํฌ๋ฆฐ์ƒท์—์„œ FormControl๊ณผ Input์„ ๋ฉ”๋ชจํ™”๋œ ๊ตฌ์„ฑ ์š”์†Œ๋กœ ๋ž˜ํ•‘ํ•˜์—ฌ ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ๋ Œ๋”๋ง์„ ๋ฐฉ์ง€ํ–ˆ์Šต๋‹ˆ๋‹ค. @dantman์€ ์‹ค์ œ๋กœ ๊ฐ ExpansionPanel ์— ๋Œ€ํ•ด ํŠน์ • ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋งŒ๋“ค ๊ฒƒ์„ ์ œ์•ˆํ–ˆ์ง€๋งŒ ์ด๊ฒƒ์€ ๋œ ์ผ๋ฐ˜์ ์ธ ์†”๋ฃจ์…˜์ž…๋‹ˆ๋‹ค. ์ฐธ๊ณ ๋กœ ๊ฐ ํŒจ๋„์€ ์—ฌ์ „ํžˆ โ€‹โ€‹๋‹ค์‹œ ๋ Œ๋”๋ง๋˜๊ณ  ์„ฑ๋Šฅ์€ ์ตœ์ ๊ณผ๋Š” ๊ฑฐ๋ฆฌ๊ฐ€ ๋ฉ€์ง€๋งŒ ์ง€๊ธˆ์€ ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค.

screenshot 2018-12-22 at 15 18 22

๊ทธ๋ž˜์„œ? ๋ฌด์—‡ ํ–ฅํ›„ ๊ณ„ํš?

React.ReactNode ๊ตฌ์„ฑ์— ํฌ๊ฒŒ ์˜์กดํ•˜๋Š” ํ˜„์žฌ API์— ๋Œ€ํ•œ ๋Œ€๋Œ€์ ์ธ ๋ณ€๊ฒฝ ์—†์ด material-ui ์ฝ”๋“œ ๋ณ€๊ฒฝ์œผ๋กœ ์ด๋Ÿฌํ•œ ์ข…๋ฅ˜์˜ ๋ฌธ์ œ๋ฅผ ํ”ผํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์€ ์—†๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.
๊ทธ๋Ÿฌ๋‚˜ https://github.com/mui-org/material-ui/issues/10778#issuecomment -449153635์—์„œ @dantman์ด ์–ธ๊ธ‰ํ–ˆ๋“ฏ์ด MUI๋Š” ์˜ˆ์ƒ๋ณด๋‹ค ์•ฝ๊ฐ„ ๋Š๋ฆฝ๋‹ˆ๋‹ค. ์ด๊ฒƒ์„ ์ „ํ˜€ ๋‹ค๋ฃจ์ง€ ์•Š๋Š” ๊ฒƒ์€ IMHO์˜ ์‹ค์ˆ˜์ž…๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๋ฅผ ์ธ์‹ํ•˜๊ณ  ์„ฑ๋Šฅ ๋ฌธ์ œ ๋ฐ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•๊ณผ ๊ด€๋ จ๋œ ๋ฌธ์„œ ํŽ˜์ด์ง€๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ์˜ ํŽ˜์ด์ง€๊ฐ€ ์ฃผ๋กœ ๊ณต์‹ ๋ฌธ์„œ(https://reactjs.org/docs/optimizing-performance.html)๋กœ ๋ฆฌ๋””๋ ‰์…˜๋˜๊ณ  ์„ฑ๋Šฅ ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ฌ ์ˆ˜ ์žˆ๋Š” ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋‚˜์—ดํ•˜๋”๋ผ๋„ ์‹œ์ž‘์ž…๋‹ˆ๋‹ค.
์ด๋Ÿฌํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์‚ฌ์šฉ์ž์—๊ฒŒ console.warn์„ ํ‘œ์‹œํ•˜๋Š” ๊ฒƒ์ด ๋” ๋‚ซ์ง€๋งŒ material-ui ์ˆ˜์ค€์—์„œ ๋ฌธ์ œ๋ฅผ ๊ฐ์ง€ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

@prevostc ์ด ๋ฉ”์‹œ์ง€๋Š” ๋‚ด ํ•˜๋ฃจ๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋‚ด๊ฐ€ ์‚ฌ๋ž‘ํ•˜๋Š” ์ปค๋ฎค๋‹ˆํ‹ฐ์˜ ์ข…๋ฅ˜์ž…๋‹ˆ๋‹ค. ์„ฑ๋Šฅ์„ ๊ฐœ์„ ํ•˜๊ณ  ์‚ฌ์šฉ์ž ์˜์—ญ ์ตœ์ ํ™”์˜ ํ•„์š”์„ฑ์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด mui๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋Š” ์•„์ด๋””์–ด๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? API ๋ณ€๊ฒฝ์ด ๊ฐ€๋Šฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค : s

๋‚˜๋Š” ํ˜„์žฌ ์›์‹œ ์„ฑ๋Šฅ(API ๋ณ€๊ฒฝ ์—†์ด)์„ ๊ฐœ์„ ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ ๋งŒํผ MUI์˜ ๋‚ด๋ถ€๋ฅผ ์•Œ์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋ช‡ ๊ฐ€์ง€ ์•„์ด๋””์–ด๋ฅผ ์—ฐ๊ตฌํ•˜๊ณ  ์žˆ์ง€๋งŒ ์˜ค๋Š˜ ๊ฒฐ์ •์ ์ธ ๊ฒƒ์€ ์—†์Šต๋‹ˆ๋‹ค. ๋ผ๋””์˜ค ๊ทธ๋ฃน์ด ์ง์ ‘ ๋ถ€๋ชจ๊ฐ€ ์•„๋‹ ๋•Œ ๋‹ค์‹œ ๋ Œ๋”๋ง๋˜๋Š” ์•ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์•„์ง ๋กœ์ปฌ์—์„œ ์žฌ์ƒ์„ฑํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๋ชจ๋“  API ๋ณ€๊ฒฝ์€ API์—์„œ React.ReactNode ์†Œํ’ˆ(์•„์ด ๋ฐ ์•„์ด์ฝ˜๊ณผ ๊ฐ™์€ ๊ธฐํƒ€ ์†Œํ’ˆ) ์ œ๊ฑฐ๋ฅผ ๊ณ ๋ คํ•˜๋Š” ๊ฒƒ์ด์ง€๋งŒ ๋™์ผํ•œ ๊ตฌ์„ฑ ๊ฐ€๋Šฅ์„ฑ์„ ์œ ์ง€ํ•˜๋Š” ์ข‹์€ ๋ฐฉ๋ฒ•์„ ์ฐพ์„ ์ˆ˜ ์—†์—ˆ์Šต๋‹ˆ๋‹ค.
๋‚ด๊ฐ€ ์‹œ๋„ํ•œ ๊ฒƒ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. https://codesandbox.io/s/jpw36jw65 (๊ฒฝ๊ณ : ์™„๋ฃŒ๋˜์ง€ ์•Š์Œ).

๋˜ํ•œ ๊ฐœ๋ฐœ ๋ชจ๋“œ์—์„œ ๋ฐ˜์‘์ด ํŠนํžˆ ๋Š๋ฆฌ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐœ๋ฐœ ๋ชจ๋“œ์—์„œ MUI๊ฐ€ ํŠนํžˆ ๋Š๋ฆฝ๋‹ˆ๋‹ค. ์ด๋ฅผ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

Material-UI๊ฐ€ ํ˜„์žฌ ์ง๋ฉดํ•˜๊ณ  ์žˆ๋Š” ์„ฑ๋Šฅ ๋ฌธ์ œ๋ฅผ ์ตœ์ ํ™”ํ•˜๊ธฐ ์œ„ํ•ด ( @Bessonov๊ฐ€ ์ œ์•ˆํ•œ ๊ฒƒ๊ณผ ๊ฐ™์€) ๊ธฐ๋Šฅ ์ถ”๊ฐ€์— ์ง„์ „์ด ์žˆ์Šต๋‹ˆ๊นŒ?
์ด ํ›Œ๋ฅญํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ”„๋กœ์ ํŠธ์— ์‚ฌ์šฉํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ์„ ๋•Œ ํ”„๋กœ์ ํŠธ๊ฐ€ ์ ์  ๋” ์ปค์งˆ ๋•Œ ์ด๋Ÿฌํ•œ ์„ฑ๋Šฅ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ๋ชฐ๋ž์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ Material-UI ๋ฌธ์„œ์—์„œ Material-UI๊ฐ€ ๋Š๋ ค์ง€๊ณ  UX์— ํ•ด๋ฅผ ๋ผ์น  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ์— ๋Œ€ํ•ด ์•Œ๋ ค์ฃผ๋Š” ์„น์…˜์„ ๋ณด์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค.
Material-UI์™€ ์ง๊ฐ„์ ‘์ ์œผ๋กœ ๊ด€๋ จ๋œ ๋งŽ์€ ์„ฑ๋Šฅ ๋ฌธ์ œ๊ฐ€ ์ด ๋ฌธ์ œ์—์„œ ๋ณด๊ณ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ์‚ฌ๋žŒ์ด ์ง„ํ–‰ ์ƒํ™ฉ์„ ์ถ”์ ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋‹ค๋ฅธ ๋ฌธ์ œ์— ๋‚˜์—ดํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ๊ดœ์ฐฎ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์‹œ๋ฉด ์ƒˆ ๋ฌธ์ œ๋ฅผ ์—ด โ€‹โ€‹์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@mkermani144 Material-UI๊ฐ€ ์ž˜๋ชปํ•˜๊ณ  ์žˆ๋Š” ๊ฒƒ๊ณผ ์ง์ ‘์ ์ธ ์ƒ๊ด€๊ด€๊ณ„๊ฐ€ ์žˆ๋Š” ์„ฑ๋Šฅ ๋ณด๊ณ ์„œ๋ฅผ ์•„์ง ๋ณด์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. ์ง€๊ธˆ๊นŒ์ง€ ์ด ๋ฌธ์ œ๋Š” ์–ด๋ ค์›€์„ ๊ฒช๊ณ  ์žˆ๋Š” ์‚ฌ๋žŒ๋“ค์„ ์œ„ํ•œ ๋„์›€๋ง ํฌ๋Ÿผ์œผ๋กœ ์‚ฌ์šฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋ณด๊ณ ๋œ ์กฐ์น˜ ์‚ฌํ•ญ์ด ์—†์Œ์„ ํ™•์ธํ•ฉ๋‹ˆ๊นŒ? React ์ถ”์ƒํ™”์—๋Š” ๋น„์šฉ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ˜ธ์ŠคํŠธ๋ฅผ ๋ž˜ํ•‘ํ•˜๋Š” ๊ฐ ๊ตฌ์„ฑ ์š”์†Œ๋Š” ๋ Œ๋” ํŠธ๋ฆฌ์— ๊ฐ€์ค‘์น˜๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ์†๋„๋ฅผ ๋Šฆ์ถฅ๋‹ˆ๋‹ค. ๋„ค์ดํ‹ฐ๋ธŒ ํ˜ธ์ŠคํŠธ๋กœ 100๊ฐœ ์ด์ƒ์˜ ๋ชฉ๋ก ํ•ญ๋ชฉ์„ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ํด๋ž˜์Šค ๊ตฌ์„ฑ ์š”์†Œ๋กœ ๋ž˜ํ•‘ํ•˜๋ฉด ๋ฌธ์ œ๊ฐ€ ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค. Material-UI์—๋งŒ ๊ตญํ•œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

ํ…Œ์ด๋ธ”

๊ฐœ๋ฐœ ๋ชจ๋“œ

ํ…Œ์ด๋ธ”์˜ ์˜ˆ๋ฅผ ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์‚ฌ๋žŒ๋“ค์ด ๋Š๋ฆฌ๊ฒŒ ์ฐพ๋Š” ๊ตฌ์„ฑ ์š”์†Œ์ž…๋‹ˆ๋‹ค. ๊ฐ€์ƒํ™”๋ฅผ ๋ฌธ์„œํ™”ํ–ˆ์œผ๋ฉฐ ๋งŽ์€ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ ํ…Œ์ŠคํŠธ ์‚ฌ๋ก€์—์„œ๋Š” ๊ฐœ๋ฐœ ๋ชจ๋“œ์—์„œ 100๊ฐœ์˜ ํ•ญ๋ชฉ์„ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฝ์šฐ๋ฅผ ๊ณ ๋ คํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  1. ์›์‹œ ํ…Œ์ด๋ธ”: https://codesandbox.io/s/v066y5q7z3 : ๋ Œ๋” ์—์„œ
  2. ํ…Œ์ด๋ธ” Material-UI ๋งˆ์Šคํ„ฐ: https://codesandbox.io/s/m4kwmvj9ly : ๋ Œ๋”์—์„œ 250ms
  3. Table Material-UI Next: https://codesandbox.io/s/2o35yny1jn : ๋ Œ๋” ์—์„œ

๋”ฐ๋ผ์„œ ํ˜ธ์ŠคํŠธ ์š”์†Œ์— ๋Œ€ํ•ด ๊ฐœ๋ฐœ ๋ชจ๋“œ์—์„œ Material-UI๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์˜ค๋ฒ„ํ—ค๋“œ๋Š” ์•ฝ x4์ž…๋‹ˆ๋‹ค(์ƒ์‚ฐ์—์„œ๋Š” ์ฐจ์ด๊ฐ€ ๋” ์ž‘์Šต๋‹ˆ๋‹ค!). ๋‹จ์ˆœํžˆ ์ค‘๊ฐ„ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ~100๊ฐœ์˜ ํ…Œ์ด๋ธ” ํ•ญ๋ชฉ ๋ชฉ๋ก์„ ๋ Œ๋”๋งํ•œ ํ›„ ๊ฐ€์ƒํ™”๊ฐ€ ์ค‘์š”ํ•˜๊ธฐ ์‹œ์ž‘ํ•˜๋Š” ์ด์œ ์ž…๋‹ˆ๋‹ค. ์ด์ œ ์šฐ๋ฆฌ๋Š” ์™œ ๊ทธ๋ฆฌ๊ณ  ๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ๋ฌด์—‡์„ ํ•  ์ˆ˜ ์žˆ๋Š”์ง€์— ๋Œ€ํ•ด ์กฐ๊ธˆ ๋” ๊นŠ์ด ํŒŒ๊ณ ๋“ค

  1. ํ…Œ์ด๋ธ” ์›์‹œ + ๊ธฐ๋Šฅ ๊ตฌ์„ฑ ์š”์†Œ. ์™œ ๊ธฐ๋Šฅ์„ฑ ์ปดํฌ๋„ŒํŠธ์ธ๊ฐ€? ์‚ฌ์šฉ๋œ ํด๋ž˜์Šค ์ด๋ฆ„์„ ์ถ”์ƒํ™”ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๊ตฌ์„ฑ ์š”์†Œ ์‚ฌ์šฉ์ž๊ฐ€ ๋ฐ˜๋ณตํ•˜๋Š” ๊ฒƒ์„ ์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
    https://codesandbox.io/s/1zl75mwlpj : ๋ Œ๋” ์—์„œ
  2. ํ…Œ์ด๋ธ” ์›์‹œ + ๊ธฐ๋Šฅ ๊ตฌ์„ฑ ์š”์†Œ + forwardRef. ์™œ forwardRef์ธ๊ฐ€? ์šฐ๋ฆฌ๋Š” ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ "ํˆฌ๋ช…"ํ•˜๊ณ  ref๋กœ ํ˜ธ์ŠคํŠธ ์š”์†Œ์— ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ์›ํ•ฉ๋‹ˆ๋‹ค.
    https://codesandbox.io/s/32o2y0o9op : ๋ Œ๋”์—์„œ 120ms
  3. ํ…Œ์ด๋ธ” Raw + ํ•จ์ˆ˜ ๊ตฌ์„ฑ ์š”์†Œ + forwardRef + withStyles. ์™œ withStyles? ๊ตฌ์„ฑ ์š”์†Œ์˜ ์Šคํƒ€์ผ์„ ์ง€์ •ํ•˜๊ธฐ๋ฅผ ์›ํ•˜๊ธฐ ๋•Œ๋ฌธ์—:
    https://codesandbox.io/s/j2n6pv768y : ๋ Œ๋”์—์„œ 200ms
  4. ํ…Œ์ด๋ธ” Raw + ํ•จ์ˆ˜ ๊ตฌ์„ฑ ์š”์†Œ + forwardRef + makeStyles. makeStyles๋Š” withStyles๋ณด๋‹ค ๋น ๋ฅผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‹œ๋„ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.
    https://codesandbox.io/s/yw52n07l3z : ๋ Œ๋”๋ง์—์„œ 130ms .

๋”ฐ๋ผ์„œ ํ•œ ๊ฐ€์ง€ ํ™œ์šฉ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ withStyles์—์„œ makeStyles๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ ๋ชจ๋“œ์—์„œ ์•ฝ +30%์˜ ์„ฑ๋Šฅ(262 / (262 - 70))์„ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ƒ์‚ฐ ๋ชจ๋“œ

ํ”„๋กœ๋•์…˜ ๋ชจ๋“œ์—์„œ ๋™์ผํ•œ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋ฅผ ์‹คํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค.

  • ์ˆ˜ํ™”๋ฌผ์—์„œ nยฐ1 30ms
  • ์ˆ˜ํ™”๋ฌผ์—์„œ nยฐ3 106ms
  • nยฐ4 ์ˆ˜ํ™”๋ฌผ์—์„œ 40ms
  • ์ˆ˜ํ™”๋ฌผ์—์„œ nยฐ5 41ms
  • ์ˆ˜ํ™”๋ฌผ์—์„œ nยฐ6 80ms
  • ์ˆ˜ํ™”๋ฌผ์—์„œ nยฐ7 57ms

๋”ฐ๋ผ์„œ withStyles ์—์„œ makeStyles ๋กœ์˜ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์€ ํ”„๋กœ๋•์…˜ ๋ชจ๋“œ์—์„œ ์ด๋ก ์ƒ ์—ฌ์ „ํžˆ +30% ์†๋„ ํ–ฅ์ƒ์ž…๋‹ˆ๋‹ค.

๊ดœ์ฐฎ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์‹œ๋ฉด ์ƒˆ ๋ฌธ์ œ๋ฅผ ์—ด โ€‹โ€‹์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@ mkermani144 Material-UI๊ฐ€ ์ž˜๋ชปํ•˜๊ณ ์žˆ๋Š” ํŠน์ • ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค๋ฉด ํ™•์‹คํ•ฉ๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ ์•„๋ž˜์— ์žˆ๋Š” ๋ชจ๋“  ๋Œ“๊ธ€์— ๋Œ€ํ•ด ์ฝ์—ˆ์Šต๋‹ˆ๋‹ค. ๋‚ด ๋ฌธ์ œ๋Š” ์•ž์—์„œ ์–ธ๊ธ‰ํ•œ ๋‹ค๋ฅธ ๋ฌธ์ œ์— ๋งž์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

List ๊ตฌ์„ฑ ์š”์†Œ์— ListItem ์ค‘ ํ•˜๋‚˜๊ฐ€ ์„ ํƒ๋˜์–ด ๊ฐ•์กฐ ํ‘œ์‹œ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ListItem ๋ฅผ ํด๋ฆญํ•˜์—ฌ ์„ ํƒํ•˜๊ณ  ๊ฐ•์กฐ ํ‘œ์‹œํ•˜๋ฉด ์ „์ฒด ๋ชฉ๋ก(์ž์‹ ํฌํ•จ)์ด ๋‹ค์‹œ ๋ Œ๋”๋ง๋ฉ๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๊ฐ€ ์ด์ „ ์˜๊ฒฌ ๊ณผ ์ •ํ™•ํžˆ ๋™์ผํ•˜๊ฒŒ ๋ณด์ผ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์ง€๋งŒ ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ ์–ด๋„ ๋‚˜๋Š” ๊ทธ๋ ‡๊ฒŒ ์ƒ๊ฐํ•œ๋‹ค.

React ํ”„๋กœํŒŒ์ผ๋Ÿฌ์˜ ๊ฒฐ๊ณผ๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

image
๋ณด์‹œ๋‹ค์‹œํ”ผ ์ด๋ฏธ์ง€์˜ ์ตœ์ƒ์œ„ ์ˆ˜์ค€์— MyList ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ตฌ์„ฑ ์š”์†Œ๋Š” MUI List ๋Œ€ํ•œ ๋ž˜ํผ์ผ ๋ฟ์ด๋ฉฐ ์ˆœ์ˆ˜ํ•˜๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

class MyList extends React.PureComponent {
  render() {
    return (
      <List>
        {this.props.children}
      </List>
    );
  }
}

๊ทธ์˜ ์˜๊ฒฌ ์ค‘ ํ•˜๋‚˜ ์—์„œ @eps1lon ์ด List ๋ฅผ ๋‹ค์‹œ ๋ Œ๋”๋งํ•˜๋ฉด ์ปจํ…์ŠคํŠธ๊ฐ€ ์—…๋ฐ์ดํŠธ๋˜๊ณ  ์ด ์ปจํ…์ŠคํŠธ ์—…๋ฐ์ดํŠธ๊ฐ€ ๋ชจ๋“  ์†Œ๋น„์ž( ListItem ํฌํ•จ)๋„ ๋‹ค์‹œ ๋ Œ๋”๋งํ•œ๋‹ค๊ณ  ์–ธ๊ธ‰ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด ๋ž˜ํผ๋ฅผ ์ถ”๊ฐ€ ํ–ˆ์Šต๋‹ˆ๋‹ค. .

๋˜ํ•œ ๋ชจ๋“  ListItem ์ˆœ์ˆ˜ํ•˜๊ฒŒ ๋งŒ๋“ค๊ณ  ์•ฑ์„ ๋‹ค์‹œ ํ”„๋กœํŒŒ์ผ๋งํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‚ด ์‚ฌ์šฉ์ž ์ง€์ • ๊ตฌ์„ฑ ์š”์†Œ(์˜ˆ: MyListItem )๊ฐ€ _itself_๋ฅผ ๋‹ค์‹œ ๋ Œ๋”๋งํ•˜์ง€ ์•Š์•˜์ง€๋งŒ ๊ทธ ์•„๋ž˜์˜ ๋ชจ๋“  ์ž์‹์ด __did__ํ•œ ๊ฒƒ์„ ์ œ์™ธํ•˜๊ณ  ๊ฒฐ๊ณผ๋Š” ๋™์ผํ–ˆ์Šต๋‹ˆ๋‹ค.

MUI๊ฐ€ ์Šคํƒ€์ผ์„ ์ง€์ •ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•˜๋Š” ์ปจํ…์ŠคํŠธ๊ฐ€ _somehow_๋ฅผ ๋‹ค์‹œ ๋ Œ๋”๋งํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์™œ ์ด๋Ÿฌํ•œ ์žฌ๋ Œ๋”๋ง์ด ๋ฐœ์ƒํ•˜๊ณ  ์–ด๋–ป๊ฒŒ ํ”ผํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

์•„๋‹ˆ๋ฉด ๋‚ด๊ฐ€ ๋ญ”๊ฐ€ ์ž˜๋ชปํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?

์ฐธ๊ณ : ์ €๋Š” MUI ์ƒˆ๋กœ์šด(์•ŒํŒŒ) ์Šคํƒ€์ผ๋ง ์†”๋ฃจ์…˜, ์ฆ‰ @material-ui/styles ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒŒ ์ค‘์š”ํ•œ์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

@mkermani144 ๊ธฐ๋ณธ ์š”์†Œ๊ฐ€ ์žˆ๋Š” Material-UI๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  ๋‹ค์‹œ ๋ Œ๋”๋ง์ด ์—ฌ์ „ํžˆ ์กด์žฌํ•˜๋Š”์ง€ ๊ด€์ฐฐํ•˜์‹ญ์‹œ์˜ค. ์ˆœ์ˆ˜ํ•œ ๋…ผ๋ฆฌ๋Š” ์ด๋Ÿฐ ์‹์œผ๋กœ ๋„์›€์ด ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. React.createElement๋Š” ๊ฐ ๋ Œ๋”๋ง์—์„œ ์ƒˆ ์ฐธ์กฐ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  PureComponent๋ฅผ ๋ฌดํšจํ™”ํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ, ์š”์†Œ๊ฐ€ ๊ฐœ์ฒด์ด๊ณ  ๊ฐœ์ฒด๊ฐ€ Javascript์—์„œ ์—„๊ฒฉํ•˜๊ฒŒ ๋™์ผํ•˜์ง€ ์•Š๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์œผ๋ฏ€๋กœ sCU ๊ฐ€ ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ React.createElement ๊ฐ€ ๋‹ค์‹œ ํ˜ธ์ถœ๋œ๋‹ค๋Š” ๊ฒƒ์€ ๋ฌด์Šจ ๋ง์ธ์ง€ ์ดํ•ด๊ฐ€ ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. createElement ํ˜ธ์ถœ List ๋‚ด๋ถ€์˜ ํ˜ธ์ถœ์„ ์˜๋ฏธํ•˜๋Š” ๊ฒฝ์šฐ ๋‹ค์‹œ ๋ Œ๋”๋ง๋˜๋Š” ๊ฒฝ์šฐ์—๋งŒ ์ž์‹( ListItem )์— ๋Œ€ํ•ด createElement ๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์‹œ ๋ Œ๋”๋ง๋˜์ง€ ์•Š์œผ๋ฉด createElement ๊ฐ€ ํ˜ธ์ถœ๋˜์ง€ ์•Š๊ณ  ๋‹ค์‹œ ๋ Œ๋”๋ง๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ฌธ์ œ๋Š” List ์ž์ฒด๊ฐ€ ๋‹ค์‹œ ๋ Œ๋”๋ง๋œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@mkermani144 ์ตœ์†Œํ•œ์˜ ์žฌํ˜„ ์˜ˆ์ œ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค๋ฉด ์šฐ๋ฆฌ๊ฐ€ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

MyList (๋”ฐ๋ผ์„œ List )๋Š” MyList ( MyComponent ๋ผ๊ณ  ๋ถ€๋ฅผ ์ˆ˜ ์žˆ์Œ)๋ฅผ ๋ Œ๋”๋งํ•˜๋Š” ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ๋‹ค์‹œ ๋ Œ๋”๋ง๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค์‹œ ๋ Œ๋”๋ง๋ฉ๋‹ˆ๋‹ค. MyList PureComponent๋Š” MyComponent ๊ฐ€ ๋‹ค์‹œ ๋ Œ๋”๋ง๋˜๊ณ  MyList ๋Œ€ํ•œ ์ƒˆ ์ž์‹์ด ์ƒ์„ฑ๋˜์–ด MyList ๊ฒ€์‚ฌ๊ฐ€ ์‹คํŒจํ•˜๋ฏ€๋กœ ๋„์›€์ด ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

MyComponent ์•„๋งˆ๋„ ์„ ํƒ๋œ ํ•ญ๋ชฉ์˜ ์ƒํƒœ๋ฅผ ์ €์žฅํ•˜๋Š” ๊ณณ์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค์‹œ ๋ Œ๋”๋ง๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

List์˜ MUI ๊ตฌํ˜„์€ ๊ฐ ๋ Œ๋”๋ง๋งˆ๋‹ค List ์ปจํ…์ŠคํŠธ ๊ฐ’์„ ๋‹ค์‹œ ์ƒ์„ฑํ•˜์ง€ ์•Š๋„๋ก ๋ณ€๊ฒฝ๋˜์–ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.
์—ฌ๊ธฐ: https://github.com/mui-org/material-ui/blob/fb4889f42613b05220c49f8fc361451066989328/packages/material-ui/src/List/List.js#L57

๋Œ€์‹  List๊ฐ€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ณด์ด๋„๋ก ํ•˜์‹ญ์‹œ์˜ค.

const List = React.forwardRef(function List(props, ref) {
  const {
    children,
    classes,
    className,
    component: Component,
    dense,
    disablePadding,
    subheader,
    ...other
  } = props;
  const context = React.useMemo(() => ({ dense }), [dense]);

  return (
    <Component
      className={clsx(
        classes.root,
        {
          [classes.dense]: dense && !disablePadding,
          [classes.padding]: !disablePadding,
          [classes.subheader]: subheader,
        },
        className,
      )}
      ref={ref}
      {...other}
    >
      <ListContext.Provider value={context}>
        {subheader}
        {children}
      </ListContext.Provider>
    </Component>
  );
});

๊ทธ๋Ÿฌ๋ฉด ListItems์˜ sCU ๋ฒ„์ „์„ ๊ฐ„๋‹จํ•˜๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

MyList๋ฅผ ๋ Œ๋”๋งํ•˜๋Š” ๊ตฌ์„ฑ ์š”์†Œ(MyComponent๋ผ๊ณ  ๋ถ€๋ฅผ ์ˆ˜ ์žˆ์Œ)๊ฐ€ ๋‹ค์‹œ ๋ Œ๋”๋ง๋˜๊ธฐ ๋•Œ๋ฌธ์— MyList(๋ฐ ๋”ฐ๋ผ์„œ List)๊ฐ€ ๋‹ค์‹œ ๋ Œ๋”๋ง๋ฉ๋‹ˆ๋‹ค. MyList์˜ PureComponent๋Š” MyComponent๊ฐ€ ๋‹ค์‹œ ๋ Œ๋”๋ง๋˜๊ณ  MyList์— ๋Œ€ํ•œ ์ƒˆ ์ž์‹์ด ์ƒ์„ฑ๋˜์–ด MyLists ๊ฒ€์‚ฌ๊ฐ€ ์‹คํŒจํ•˜๋ฏ€๋กœ ๋„์›€์ด ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

@Pajn ์•„๋‹ˆ์š”, ๋‚ด React ํ”„๋กœํŒŒ์ผ๋Ÿฌ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์„ธ์š”. MyList ๋Š” ๋‹ค์‹œ ๋ Œ๋”๋งํ•˜์ง€ ์•Š์•˜์ง€๋งŒ(ํšŒ์ƒ‰) List ๋Š” ๋‹ค์‹œ ๋ Œ๋”๋งํ–ˆ์Šต๋‹ˆ๋‹ค(ํŒŒ๋ž€์ƒ‰). ๋‚˜๋Š” PureComponent ๋Œ€ํ•ด MyList PureComponent ๋ฅผ ์ง€์†ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์‹ฌ์ง€์–ด ๊ตฌํ˜„ ๋‚ด๊ฐ€ ๋น„๋ก sCU ์œ„ํ•ด MyList ๊ทธ๋ž˜์„œ ๋ Œ๋”๋ง์„ ๋‹ค์‹œํ•˜์ง€ ์•Š๋Š”, List __does ๋‹ค์‹œ render__์„.

@oliviertassinari
๋‚˜๋Š” ์ตœ์†Œํ•œ์˜ ์žฌ์ƒ์‚ฐ ์˜ˆ์ œ๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.

import React, { Component } from 'react';

import StylesProvider from '@material-ui/styles/StylesProvider';
import ThemeProvider from '@material-ui/styles/ThemeProvider';

import { createMuiTheme } from '@material-ui/core';

import List from '@material-ui/core/List';
import ListItem from '@material-ui/core/ListItem';

const theme = createMuiTheme({});

const MyListItem = React.memo(ListItem, (prev, next) => prev.selected === next.selected);

class App extends Component {
  state = {
    selected: null,
  }
  render() {
    return (
      <StylesProvider>
        <ThemeProvider theme={theme}>
          <List>
            {[0, 1, 2, 3, 4].map(el => (
              <MyListItem
                button
                selected={el === this.state.selected}
                onClick={() => this.setState({ selected: el })}
              >
                {el}
              </MyListItem>
            ))}
          </List>
        </ThemeProvider>
      </StylesProvider>
    );
  }
}

export default App;

๋ฐ˜์‘ ํ”„๋กœํŒŒ์ผ๋Ÿฌ ๊ฒฐ๊ณผ(4๋ฒˆ์งธ ๋ชฉ๋ก ํ•ญ๋ชฉ ํด๋ฆญ ํ›„):

image

๋ณด์‹œ๋‹ค์‹œํ”ผ ์˜ˆ์ƒ๋Œ€๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ์ถ”๊ฐ€ ์žฌ๋ Œ๋”๋ง์ด ์—†์Šต๋‹ˆ๋‹ค( ListItem ๋‚ด๋ถ€์˜ ButtonBase ๊ตฌ์„ฑ ์š”์†Œ ์ œ์™ธ). ๋ฌธ์ œ๋Š” ์ด ์žฌ์ƒ์‚ฐ์ด _๋„ˆ๋ฌด ๋ฏธ๋ฏธํ•˜๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ๊ฒƒ์— ๊ฑด๋„ˆ ๋›ฐ๋Š” ๋งŽ์€ ๊ฒƒ๋“ค์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์ถ”๊ฐ€ ์žฌ๋ Œ๋”๋ง์„ ์œ ๋ฐœํ•˜๋Š” ๋‚ด ์ฝ”๋“œ์— ๋ฌด์—‡์ด ๋ฌธ์ œ์ธ์ง€ ๋งํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ํ•œ ๊ฐ€์ง€ ์งˆ๋ฌธ์„ ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค. MUI ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋ž˜ํ•‘ํ•˜๋Š” WithStylesInner ๊ตฌ์„ฑ ์š”์†Œ์—์„œ ๋‹ค์‹œ ๋ Œ๋”๋ง๋˜๋Š” ์›์ธ์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

@mkermani144 ์ด ์ˆ˜์ • ์‚ฌํ•ญ์— ๋Œ€ํ•ด ์–ด๋–ป๊ฒŒ ์ƒ๊ฐํ•˜์‹œ๋‚˜์š”?

--- a/packages/material-ui/src/List/List.js
+++ b/packages/material-ui/src/List/List.js
@@ -40,6 +40,13 @@ const List = React.forwardRef(function List(props, ref) {
     ...other
   } = props;

+  const context = React.useMemo(
+    () => ({
+      dense,
+    }),
+    [dense],
+  );
+
   return (
     <Component
       className={clsx(
@@ -54,7 +61,7 @@ const List = React.forwardRef(function List(props, ref) {
       ref={ref}
       {...other}
     >
-      <ListContext.Provider value={{ dense }}>
+      <ListContext.Provider value={context}>
         {subheader}
         {children}
       </ListContext.Provider>

ํ’€ ๋ฆฌํ€˜์ŠคํŠธ๋ฅผ ์ œ์ถœํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? :) ์šฐ๋ฆฌ๋Š” Table ๊ตฌ์„ฑ ์š”์†Œ์™€ ๋™์ผํ•œ ์ „๋žต์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๋ฌธ์ œ๋ฅผ ์‹ ๊ณ ํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!

@oliviertassinari ๋ฌผ๋ก ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์ •ํ™•ํžˆ @Pajn ์ด ์ด์ „์— ์ œ์•ˆํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. PR์„ ์ œ์ถœํ–ˆ์Šต๋‹ˆ๋‹ค.

14934๊ฐ€ ๋ณ‘ํ•ฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ List ๊ตฌ์„ฑ ์š”์†Œ๋Š” ์•„๋ฌด๋ฆฌ ์ตœ์ ํ™”ํ•˜๋”๋ผ๋„ ์ถฉ๋ถ„ํžˆ ํฌ๋ฉด ์„ฑ๋Šฅ ๋ณ‘๋ชฉ ํ˜„์ƒ์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Table ๋ฌธ์„œ์— ์žˆ๋Š” ๊ฒƒ๊ณผ ๊ฐ™์ด List ๊ตฌ์„ฑ์š”์†Œ์™€ ํ•จ๊ป˜ react-window ๋˜๋Š” react-virtualized ์‚ฌ์šฉ์„ ๋ณด์—ฌ์ฃผ๋Š” ์˜ˆ๋ฅผ ์ œ๊ณตํ•ด์•ผ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๊นŒ?

์šฐ๋ฆฌ๊ฐ€ Table ๋ฌธ์„œ์— ์žˆ๋Š” ๊ฒƒ๊ณผ ๊ฐ™์ด List ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ react-window ๋˜๋Š” react-virtualized์˜ ์‚ฌ์šฉ๋ฒ•์„ ๋ณด์—ฌ์ฃผ๋Š” ์˜ˆ์ œ๋ฅผ ์ œ๊ณตํ•ด์•ผ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๊นŒ?

๋Œ€๋‹จํ•˜๋„ค์š” :+1:

Fwiw ์ฑ„ํŒ… ์•ฑ์„ ๋งŒ๋“ค์—ˆ๊ณ  ์•ฑ์—์„œ ๋งŽ์€ ์—ฐ๋ฝ์ฒ˜ ๋ชฉ๋ก์„ ๋ Œ๋”๋งํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ฐ™์€ ๋ฌธ์ œ์— ๋ถ€๋”ช์ณค๋‹ค.
@mkermani144 ๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

https://stackoverflow.com/questions/55969987/why-do-the-children-nodes-rerender-when-the-parent-node-is-not-even-being-update/55971559

@henrylearn2rock ๊ฐ€์ƒํ™” ์‚ฌ์šฉ์„ ๊ณ ๋ คํ•ด ๋ณด์…จ์Šต๋‹ˆ๊นŒ? ๋ชฉ๋ก์— ๋Œ€ํ•œ ๋ฐ๋ชจ๋ฅผ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค: https://next.material-ui.com/demos/lists/#virtualized -list.

์ด๊ฒƒ์€ ๋˜ํ•œ ๋‚˜๋ฅผ ์ •๋ง๋กœ ๋„˜์–ด๋œจ๋ ธ๋‹ค. ๋‚˜๋Š” ๋Œ€๋ถ€๋ถ„์˜ ์‚ฌ๋žŒ๋“ค(์ €๋ฅผ ํฌํ•จํ•˜์—ฌ)์ด ์ˆœ์ˆ˜ ๊ตฌ์„ฑ์š”์†Œ ์•„๋ž˜์˜ ๋ชจ๋“  ๊ฒƒ์ด ์žฌ๋ Œ๋”๋ง์œผ๋กœ๋ถ€ํ„ฐ ์•ˆ์ „ํ•˜๋‹ค๊ณ  ๊ฐ€์ •ํ–ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋ถ„๋ช…ํžˆ ์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๊ฒฝ์šฐ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. ๊ฐ€์žฅ ์ตœ๊ทผ์— ์ œ์•ˆํ•œ ๋Œ€๋กœ ๊ฐ€์ƒํ™”๋ฅผ ์‹œ๋„ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ฐ์‚ฌ ํ•ด์š”!

๋‚˜๋Š” ๋Œ€๋ถ€๋ถ„์˜ ์‚ฌ๋žŒ๋“ค(์ €๋ฅผ ํฌํ•จํ•˜์—ฌ)์ด ์ˆœ์ˆ˜ ๊ตฌ์„ฑ์š”์†Œ ์•„๋ž˜์˜ ๋ชจ๋“  ๊ฒƒ์ด ์žฌ๋ Œ๋”๋ง์œผ๋กœ๋ถ€ํ„ฐ ์•ˆ์ „ํ•˜๋‹ค๊ณ  ๊ฐ€์ •ํ–ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋ถ„๋ช…ํžˆ ์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๊ฒฝ์šฐ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ React.PureComponent ๋˜๋Š” React.memo๊ฐ€ ์ž‘๋™ํ•˜๋Š” ๋ฐฉ์‹์ด ์•„๋‹™๋‹ˆ๋‹ค. ๊ตฌ์„ฑ ์š”์†Œ ์ž์ฒด์—๋งŒ ์˜ํ–ฅ์„ ์ค๋‹ˆ๋‹ค. ์ปจํ…์ŠคํŠธ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด ์–ด๋ฆฐ์ด๋Š” ์—ฌ์ „ํžˆ ๋‹ค์‹œ ๋ Œ๋”๋งํ•ด์•ผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@pytyl PureComponent ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ํ•˜์œ„ ํŠธ๋ฆฌ์—์„œ ๋‹ค์‹œ ๋ Œ๋”๋ง๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•œ ์ฝ”๋“œ๋ฅผ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

@eps1lon ๋‹ค์Œ ๋ฌธ์„œ๋Š”
https://reactjs.org/docs/optimizing-performance.html#shouldcomponentupdate-in-action

shouldComponentUpdate๊ฐ€ C2๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋Š” ํ•˜์œ„ ํŠธ๋ฆฌ์— ๋Œ€ํ•ด false๋ฅผ ๋ฐ˜ํ™˜ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— React๋Š” C2๋ฅผ ๋ Œ๋”๋งํ•˜๋ ค๊ณ  ์‹œ๋„ํ•˜์ง€ ์•Š์•˜์œผ๋ฏ€๋กœ C4 ๋ฐ C5์—์„œ shouldComponentUpdate๋ฅผ ํ˜ธ์ถœํ•  ํ•„์š”์กฐ์ฐจ ์—†์—ˆ์Šต๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ์ด๊ฒƒ์„ ์ž˜๋ชป ์•Œ๊ณ  ์žˆ๋Š” ๊ฒƒ์€ ์•„๋‹๊นŒ? ๋‹ค์Œ์€ ๋‚ด ํ”„๋กœํŒŒ์ผ๋Ÿฌ์˜ ์Šค๋ƒ…์ƒท์ž…๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•ด ๋ฉ”๋‰ด ๊ตฌ์„ฑ ์š”์†Œ์˜ shouldComponentUpdate์— ๋Œ€ํ•ด ๋ช…์‹œ์ ์œผ๋กœ false๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

Screen Shot 2019-05-08 at 7 46 32 PM

์ด๋กœ ์ธํ•ด ๋ชจ๋“  ์ž์‹ ๊ตฌ์„ฑ ์š”์†Œ(Categories, Category, CategoryItems, CategoryItem)๊ฐ€ ๋‹ค์‹œ ๋ Œ๋”๋ง๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๋งŽ์€ MUI ๊ด€๋ จ ์‚ฌํ•ญ์ด ํ•˜๋‹จ์—์„œ ๋‹ค์‹œ ๋ Œ๋”๋ง๋˜์–ด ๋งŽ์€ ์ง€์—ฐ์„ ์ผ์œผํ‚ค๋Š” ๊ฒƒ์œผ๋กœ ๋ณด์ž…๋‹ˆ๋‹ค. withStyles, Typography, ButtonBase์™€ ๊ฐ™์€ ๊ฒƒ๋“ค. React๋Š” ์•„์ง ์กฐ๊ธˆ ์ƒ์†Œํ•˜๋ฏ€๋กœ ์ €์˜ ๋ฌด์ง€๋ฅผ ์šฉ์„œํ•ด ์ฃผ์‹ญ์‹œ์˜ค. ๋‹ค์Œ์€ ๋ฉ”๋‰ด ๊ตฌ์„ฑ ์š”์†Œ์— ๋Œ€ํ•œ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค(์—ฌ๊ธฐ์„œ shouldComponentUpdate์— ๋Œ€ํ•ด false๋ฅผ ๋ฐ˜ํ™˜ํ•จ).

import React, { Component } from "react";
import Categories from "./Categories";
import { withStyles, Paper } from "@material-ui/core";

const styles = theme => ({
  root: {
    paddingTop: 0,
    marginLeft: theme.spacing.unit * 2,
    marginRight: theme.spacing.unit * 2,
    marginTop: theme.spacing.unit * 1
  }
});

class Menu extends Component {
  shouldComponentUpdate(nextProps, nextState) {
    if (nextProps.categories.length == this.props.categories.length) {
      return false;
    }
    return true;
  }

  render() {
    const { classes, categories } = this.props;

    return (
      <Paper className={classes.root}>
        <Categories categories={categories} />
      </Paper>
    );
  }
}

export default withStyles(styles)(Menu);

๋ฌธ์ œ๋ฅผ ์ดํ•ดํ•˜๋ ค๋ฉด ์ „์ฒด ์ฝ”๋“œ ์ƒŒ๋“œ๋ฐ•์Šค๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

@eps1lon ๋‚ด์ผ ์ œ์ž‘ํ•ด

@eps1lon ์€ ์ฝ”๋“œํŽœ์ž…๋‹ˆ๋‹ค.
https://codesandbox.io/s/348kwwymj5

๊ฐ„๋‹จํ•œ ์„ค๋ช…
์‹๋‹น์„ ์œ„ํ•œ ๊ธฐ๋ณธ ๋ฉ”๋‰ด ์•ฑ์ž…๋‹ˆ๋‹ค(์ข…์ข… 100๊ฐœ ์ด์ƒ์˜ ๋ฉ”๋‰ด ํ•ญ๋ชฉ์ด ์žˆ์Œ). ์‚ฌ์šฉ์ž๊ฐ€ ๋ฉ”๋‰ด ํ•ญ๋ชฉ์„ ํด๋ฆญํ•˜๋ฉด "์ฃผ๋ฌธ์— ์ถ”๊ฐ€" ๋Œ€ํ™” ์ƒ์ž๊ฐ€ ์—ด๋ฆฝ๋‹ˆ๋‹ค. ํ”„๋กœํŒŒ์ผ๋Ÿฌ๊ฐ€ ์„ฑ๋Šฅ์ด ์ข‹์ง€ ์•Š์€ ๋ช‡ ๊ฐ€์ง€ ์ƒํ™ฉ์„ ์ฒจ๋ถ€ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค(์ด ํ†ต๊ณ„๋Š” ํ”„๋กœ๋•์…˜ ๋นŒ๋“œ์— ์—†์Œ).

์ฒด๊ณ„
MacBook Pro(Retina, 13ํ˜•, 2015๋…„ ์ดˆ)
3.1GHz ์ธํ…” ์ฝ”์–ด i7
ํŒŒ์ด์–ดํญ์Šค 66.0.3

์‚ฌ๋ก€ 1(์‚ฌ์šฉ์ž๊ฐ€ ๋ฉ”๋‰ด ํ•ญ๋ชฉ์„ ํด๋ฆญํ•จ)
๋ Œ๋”๋ง ์‹œ๊ฐ„: 218ms

Screen Shot 2019-05-10 at 4 45 26 AM

Screen Shot 2019-05-10 at 4 45 48 AM

์‚ฌ๋ก€ 2(์‚ฌ์šฉ์ž๊ฐ€ ๋Œ€ํ™” ์ƒ์ž์—์„œ ์ฃผ๋ฌธ์— ์ถ”๊ฐ€ ๋ฒ„ํŠผ ํด๋ฆญ)
๋ Œ๋”๋ง ์‹œ๊ฐ„: 356ms

Screen Shot 2019-05-10 at 4 46 24 AM

Screen Shot 2019-05-10 at 4 47 10 AM

๋‚˜๋Š” ์—ฌ๊ธฐ์—์„œ ์ดˆ๋ณด์ž ์‹ค์ˆ˜๋ฅผํ•˜๊ณ  ์žˆ๋‹ค๊ณ  ํ™•์‹ ํ•˜๋ฏ€๋กœ ์–ด๋–ค ์ง€์นจ์ด๋ผ๋„ ํฌ๊ฒŒ ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

WithStyles(ButtonBase)๊ฐ€ ๋‹ค์‹œ ๋ Œ๋”๋ง๋จ์— ๋”ฐ๋ผ WithStyles๋Š” ํ•„์š”ํ•˜์ง€ ์•Š๋”๋ผ๋„ ๋‹ค์‹œ ์ƒ์„ฑ๋˜๋Š” ์ปจํ…์ŠคํŠธ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ด๊ฒƒ์„ ์ฐพ์„ ์ˆ˜ ์žˆ์—ˆ๋‹ค https://github.com/mui-org/material-ui/blob/048c9ced0258f38aa38d95d9f1cfa4c7b993a6a5/packages/material-ui-styles/src/StylesProvider/StylesProvider.js#L38 ๊ทธ๋Ÿฌ๋‚˜ ์žฅ์†Œ๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค StylesProvider๋Š” ์‹ค์ œ ์ฝ”๋“œ์—์„œ ์‚ฌ์šฉ๋˜์ง€๋งŒ(GitHubs ๊ฒ€์ƒ‰์€ ๊ทธ๋‹ค์ง€ ์ข‹์ง€ ์•Š์Œ) ์ด์œ ๊ฐ€ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@eps1lon ์€ ์ด๊ฒƒ์ด ์›์ธ์ผ ์ˆ˜ ์žˆ๋Š”์ง€ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ? ๊ทธ๋ ‡๋‹ค๋ฉด ์ปจํ…์ŠคํŠธ ๊ฐ์ฒด์˜ useMemo๊ฐ€ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. localOptions๊ฐ€ ์•ˆ์ •์ ์ธ์ง€ ๋˜๋Š” useMemo๋ฅผ ๋” ์ „ํŒŒํ•ด์•ผ ํ•˜๋Š”์ง€ ์—ฌ๋ถ€๋Š” ์•Œ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

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

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

@pytyl ๊ท€ํ•˜์˜ ์ฝ”๋“œ ์ƒŒ๋“œ๋ฐ•์Šค๋ฅผ ์‚ดํŽด๋ณด์•˜๋Š”๋ฐ ๋ Œ๋”๋ง ์•„ํ‚คํ…์ฒ˜์— ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฉ”๋‰ด ํ•ญ๋ชฉ์„ ํด๋ฆญํ•˜๋ฉด ๋ชจ๋“  ๊ฒƒ์„ ๋‹ค์‹œ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. GlobalContext๋Š” ์ˆœ์ˆ˜ ๋…ผ๋ฆฌ๋ฅผ ์ ํ”„ํ•ฉ๋‹ˆ๋‹ค.

@eps1lon ์ด ๋ฌธ์ œ๋ฅผ ๋‹ซ์•„์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ตฌ์ฒด์ ์œผ๋กœ ํ™•์ธ๋œ ๋ฌธ์ œ์— ์ดˆ์ ์„ ๋งž์ถ”๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

TL;DR: ์ปจํ…์ŠคํŠธ ์Šฌ๋ผ์ด์Šค ์ƒ์„ฑ, ์ปจํ…์ŠคํŠธ ๊ฐ’ ๋ฉ”๋ชจ, ํŠนํžˆ material-ui์— ๋ฌธ์ œ ์—†์Œ: https://codesandbox.io/s/8lx6vk2978

๋ช‡ ๊ฐ€์ง€ ํŒŒ๊ณ  ๋“ค์—ˆ๊ณ  ๋ฌธ์ œ๋Š” ๋ Œ๋”๋ง ์ค‘์— ๋‹ค์‹œ ์ƒ์„ฑ๋˜๋Š”์ด ํฐ ๊ธ€๋กœ๋ฒŒ ์ปจํ…์ŠคํŠธ๊ฐ€ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ „์—ญ ์ปจํ…์ŠคํŠธ๊ฐ€ ๋‹ค์‹œ ์ƒ์„ฑ๋˜๋Š” ์ง€์ ์„ ํด๋ฆญํ•˜๋ฉด ์•ฑ์„ ๋‹ค์‹œ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. ๊ท€ํ•˜์˜ CategoryItem์€ ๊ท€ํ•˜์˜ ์•ฑ์— 100๋ฒˆ ๋‚˜ํƒ€๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ๋“ฃ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. 100๊ฐœ์˜ material-ui MenuItem์ด ์žˆ์œผ๋ฏ€๋กœ ์ˆ˜์ฒœ ์ปท์œผ๋กœ ๊ณ ์ „์ ์ธ ์ฃฝ์Œ์„ ๋งž์ดํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ์•„์ด๋Ÿฌ๋‹ˆํ•˜๊ฒŒ๋„ ์†”๋ฃจ์…˜์˜ ์ผ๋ถ€๋Š” ์ปจํ…์ŠคํŠธ ๊ฐ’์„ ๋ฉ”๋ชจํ•˜๋Š” ๊ฒƒ์ด์ง€๋งŒ ์ค‘์š”ํ•œ ๋ถ€๋ถ„์€ ๋ณ„๋„์˜ ์ปจํ…์ŠคํŠธ ์Šฌ๋ผ์ด์Šค๋ฅผ ์‹๋ณ„ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ƒํƒœ ๋ฐ ๋””์ŠคํŒจ์น˜ ์ปจํ…์ŠคํŠธ๊ฐ€ ์ ์ ˆํ•œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ useReducer์™€ ํ•จ๊ป˜ useContext๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ๊ถŒ์žฅ๋˜๋ฉฐ ์—ฌ๊ธฐ์— ๋งž๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ๊ฝค ํฐ ๋‚˜๋ฌด๋ฅผ ๋งŒ๋“ค๊ณ  ๋” ๋งŽ์€ ์ปจํ…์ŠคํŠธ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์†Œํ’ˆ์„ ์ง€์˜ฅ์œผ๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. useContext ์‚ดํŽด๋ณด์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ฌธ์ œ์— ์ง๋ฉดํ•˜๊ธฐ ์‹œ์ž‘ํ•˜๋ฉด ๋งŽ์€ ๋„์›€์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@oliviertassinari ์†”๋ฃจ์…˜์— ๋Œ€ํ•œ ์ผ๋ฐ˜์ ์ธ ํ•จ์ •์„ ์ˆ˜์ง‘ํ•˜๋Š” ๊ฒƒ์€ ์ข‹์€ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๊ทธ๊ฒƒ๊ณผ ๋ณ„๊ฐœ์˜ ๋ฌธ์ œ๋ฅผ ๋งŒ๋“ค ๊ฒƒ์ธ์ง€ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@oliviertassinari @eps1lon ์ˆ˜์ •

๋ Œ๋”๋ง ์„ฑ๋Šฅ์ด ๋Š๋ฆฐ ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. <Box> ๊ตฌ์„ฑ ์š”์†Œ์˜ ๋ชจ๋“  ์ธ์Šคํ„ด์Šค๋ฅผ <div> ๋กœ ๊ต์ฒดํ•˜์—ฌ ์™„์ „ํžˆ ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค. react devtools ํ™”์—ผ ๊ทธ๋ž˜ํ”„๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋””๋ฒ„๊น…ํ–ˆ๊ณ  ์•ฝ 420ms์—์„œ 20ms๋กœ ์ด๋™ํ–ˆ์Šต๋‹ˆ๋‹ค.

<Box> es;
Screen Shot 2019-08-16 at 12 47 25 AM

<Box> ์—†์ด:
Screen Shot 2019-08-16 at 12 42 38 AM

@mankittens ์Šคํƒ€์ผ ์—”์ง„์œผ๋กœ styled-components๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Box ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์„ฑ๋Šฅ์€ ํ›จ์”ฌ ๋” ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ฐ€๊นŒ์šด ์žฅ๋ž˜์— JSS๋กœ ๋” ์ข‹์•„์งˆ ๊ฒƒ์ž…๋‹ˆ๋‹ค https://github.com/mui-org/material-ui/pull/16858.

์ด ๋ฌธ์ œ๋ฅผ ๋‹ซ์Šต๋‹ˆ๋‹ค. ํฌ๊ด„์ ์ธ ์Šค๋ ˆ๋“œ๊ฐ€ ์•„๋‹Œ ๊ฐœ์„ ์˜ ๊ฐ ์ž ์žฌ์  ์˜์—ญ์— ๋Œ€ํ•œ ์ „์šฉ ์„ฑ๋Šฅ ๋ณด๊ณ ์„œ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰