ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 성능잡기 (lazy loading, React devtools, 재렌더링을 막는 memo)
    React 2022. 3. 25. 14:28

     1. 함수나 오브젝트는 선언해서 쓰는게 낫다.

    예를 들면,

    return (
    	<button onClick={ () => {} }>버튼</button>
    )
    //-----------
    function 버튼끄기() { }
    return (
    	<button onClick={ 버튼끄기 }>버튼</button>
    )

    위보단 아래처럼 함수를 선언해서 함수이름을 가져다 쓰는게 낫다.

    오브젝트도

    <div style={ { color : 'white' }> </div>
    //--------------
    var style = { color : 'white'}
    return (
    	<div style={style}></div>
    )

    이런 식으로, 위보단 아래처럼 오브젝트 변수를 만들어놓고 사용하는게 낫다.

    이유는 메모리할당 때문인데  이름없는 함수를 사용하면 메모리가 할당이 되기 때문이다.

     

    2. 애니메이션을 줄 때 transform을 쓰는게 낫다

    margin, width, padding 등 레이아웃 잡는 속성들을 변경하면 렌더링시간이 오래걸리기 때문에 transform을 써주는게 낫다.

     

    3. 컴포넌트 import할 때, App.js에서 Detail.js, Cart.js등등을 다 import 했을 때 미리 로드하기 떄문에 부담이 될 수 있다.

    이럴때 lazy loading을 쓸 수 있다. Detail컴포넌트가 필요해진 시점에 Detail 컴포넌트를 로드하는 기능이다.

    import React, {useState, lazy, Suspense} from 'react';

    먼저, React, {useState}import 하는 곳에 {lazy}랑 {Suspense}를 import해준다. 그 다음에,

    //import Detail from './Detail.js' 이거 대신
    let Detail = lazy(()=>{ return import('./Detail') }) //return import(파일경로)

    이런 식으로 import를 해준다. 이러면 Detail 컴포넌트가 필요해질 때 로드한다. 그리고 function App안의 Detail태그를

    <Suspense fallback={<div>로딩중이에요</div>}>
    	<Detail shoes={shoes} 재고={재고} 재고변경={재고변경} />
    </Suspense>

    <Suspense></Suspense>로 감싸준다. 그리고 Suspense태그에 fallback 프롭스를 하나 넣고, 로딩중이에요 같은 div를 넣으면, 페이지가 천천히 로딩된다고 했으니 로딩중일때 흰 페이지가 아니라 로딩중이에요 라는 문구를 띄우는 역할을 한다.

     

    4. 쓸데없이 재렌더링을 막는 memo

    function Cart(){
      return (
        <Parent 이름="존박" 나이="20"/>
      )
    }
    
    function Parent(props){
      return (
        <div>
          <Child1 이름={props.존박} />
          <Child2 나이={props.나이} />
        </div>
      )
    }
    
    function Child1(){
      useEffect( ()=>{ console.log('렌더링됨1') } );
      return <div>1111</div>
    }
    function Child2(){
      useEffect( ()=>{ console.log('렌더링됨2') } );
      return <div>2222</div>
    }

    이때 Cart 컴포넌트에서 <Parent 이름="존박1" 나이="20"/>으로 바꾸면 재렌더링이 된다. 컴포넌트에 있는 props 나 state가 변경되면 그걸 쓰는 HTML이 전부 재렌더링 된다.

    이게 어찌보면 존박만 존박1로 변경했는데 Child1과 Child2 둘 다 재렌더링이 되는 불필요함이다. 그래서 memo()를 사용하면 불필요한 재렌더링을 막을 수 있다.

    즉, props가 변경이 안된 컴포넌트는 재렌더링하지 말아주세요 라는 기능이다.

    먼저,

    import React, {useEffect, memo} from 'react';

    memo를 import해온다. 그다음에,

    let Child2 = memo(function(){
      useEffect( ()=>{ console.log('렌더링됨2') } );
      return <div>2222</div>
    })

    이렇게 함수를 memo로 감싸주고, 변수에 담아주면 이 함수는 관련된 props가 변경이 될 때만 재렌더링된다.

    memo의 단점은 기존 props과 바뀐 props를 비교연산 후 컴포넌트 업데이트할지말지 결정해서 props의 양이 많아지면 사이트가 느려진다.

    'React' 카테고리의 다른 글

    localStorage  (0) 2022.03.25
    PWA  (0) 2022.03.25
    state 변경함수 사용시 주의점 : async  (0) 2022.03.24
    리액트에서 자주쓰는 if문 작성패턴 5개  (0) 2022.03.24
    Redux useSelector과 useDispatch  (0) 2022.03.23

    댓글

Designed by Tistory.