기능 구현 다음에 가장 중요한 것은 바로 성능향상과 유지관리이다!
리액트도 컴포넌트의 로딩속도 등 향상시킬 수 있는 방법이 존재한다
1. 함수나 오브젝트는 변수에 담아 쓰는게 좋다!
부제 : 익명함수/익명object 안쓰기
=메모리공간을 아낄 수 있는 JS 코딩 관습
function Cart(){
return (
<div style={ {color : 'red'} } ></div>
)
}
콜백함수나 오브젝트를 써넣지 말고
var 스타일 = {color : 'red'};
function Cart(){
return (
<div style={ 스타일 } ></div>
)
}
컴포넌트 바깥에 있는 변수에 저장해서 사용하자!
강의에선 function Cart 안에 넣는데 그거 아니고 바깥에 넣자!
왜냐면 컴포넌트가 재렌더링될 때 변수에 저장되지 않은 이름없는 object, function 류의 자료형들은 매번 새로운 메모리 영역을 할당해줘야하기 때문에 컴퓨터가 바빠질 수 있다.
그걸 방지하기 위해 컴포넌트 바깥에 저렇게 마련해두시면 된다.
2. 애니메이션은 CSS transform 속성 주로 사용!
부제 : 레이아웃에 애니메이션 주지말기 (레이아웃은 width, margin, padding, left right top bottom 이런 것들을 뜻)
=전반적인 CSS 코딩 팁
자바스크립트나 transition을 이용해 레이아웃을 변경시키는건 브라우저 입장에서 큰 부담
애니메이션을 넣어도 성능에 큰 지장이 없게 만들고 싶으면 transform, opacity 같은 CSS 속성을 이용해 애니메이션을 주자!
transform은 사이즈 변경, 좌표이동, 회전 전부 가능한 좋은 속성이다.
3. 컴포넌트 import할 때 lazy 하게 import 하는 법
부제 : 컴포넌트 lazy loading 하기
App.js 가보시면 import가 매우 많다.
이게 웹앱 사이트들의 특징인데, App.js 라는 메인페이지 방문시 Detail, Cart 등을 모두 import해오기 때문이다.
따라서 컴포넌트파일을 import 해오라고 써놓으면 사이트 초기 접속속도가 굉장히 느려질 수 있다!
(App.js 상단)
import React, {useState, useContext} from 'react';
import Detail from './Detail.js';
import Cart from './Cart.js'
(App.js 상단)
import React, {useState, useContext, lazy, Suspense} from 'react';
let Detail = lazy( ()=>{ return import('./Detail.js') } );
(App.js 중단에 Detail 컴포넌트 쓰는 곳)
render (
<Suspense fallback={ <div>로딩중입니다~!</div> }>
<Detail/>
</Suspense>
)
이렇게 변경하자.
- react 라이브러리에서 lazy, Suspense를 import
- import Detail 하던걸 lazy 함수를 이용해 바꿔준다.
- <Suspense> 라는 컴포넌트로 <Detail>을 감싸준다.
- fallback 속성엔 <Detail> 컴포넌트 로딩 전까지 띄울 원하는 HTML을 적어준다.
⇒ <Detail> 컴포넌트가 필요해질 때 그제서야 import Detail!
⇒ <Suspense>는 로딩이 오래걸릴 때 띄워줄 안내문
4. React Dev Tools 개발자 도구 설치하기 (크롬 확장프로그램)
부제 : React Dev Tools 크롬 확장프로그램 설치해서 이것저것 테스트해보기
사용중인 props, state, hook 이런 것들이 나온다.
<확인 할 것>
- props가 잘 전해졌는지 확인
- state가 잘 변하고 있는지 확인
- 실시간 state, props 수정
- 시계모양 버튼을 눌러 해당 컴포넌트 렌더링을 잠깐 정지
- 컴포넌트 렌더링 속도를 보면서 어떤 컴포넌트가 렌더링 시간이 오래걸리는지, 쓸데없이 재랜더링이 자주 되는 컴포넌트가 있는지, 랜더링이 필요없는 컴포넌트가 있는지 확인
5. 재렌더링이 비효율적인 경우
컴포넌트는 컴포넌트와 관련된 state 혹은 props가 변경되면 항상 자동 재렌더링된다.
근데 문제는 변경이 안된 컴포넌트또한 이유없이 재렌더링되는 문제가 발생할 수 있다.
특히 , 컴포넌트 안에 컴포넌트가 있는 경우 부모 컴포넌트의 props 내용이 일부 변경되면 props를 전송받고 있는 자식 컴포넌트들도 전부 재렌더링된다.
이럴 경우 사이트 구동 속도가 저하될 수 있다.
이를 해결하기 위해 memo()를 사용한다.
예를들어
function Cart(){
return (
<Parent 이름="혜삔" 나이="25"></Parent>
)
}
function Parent(props) {
return (
<div>
<Child1 이름={props.이름}></Child1>
<Child2 나이={props.나이}></Child2>
</div>
);
}
function Child1() {
useEffect(() => {
console.log("랜더링됨1");
});
return <div>111</div>;
}
function Child2(){
useEffect( ()=>{
console.log('렌더링됨2') } );
return <div>2222</div>
}
이런 코드가 있다. 이때, Parent에 전송하고 있는 props 이름을 변경하면 Child1과 Child2 모두 재렌더링이 일어나게 된다.
근데 이름만 변경했는데 모두 재렌더링이 일어나므로 이는 불필요한 렌더링이 된다. 이럴 경우 Child2의 코드를 memo()함수를 이용하여 수정하면 된다.
6. memo() 를 이용해서 불필요한 재렌더링 막기
import React, {useEffect, memo} from 'react';
let Child2 = memo(function () {
useEffect(() => {
console.log("랜더링됨2");
});
return <div>222</div>;
});
일단 'react' 라이브러리로부터 import 해오고
Child2라는 원하는 컴포넌트를 memo로 감싼다.
이렇게 사용하면 아까와 같이 이름을 변경했을때, Child2를 재렌더링 되지 않는다.
컴포넌트가 크거나 잦은 렌더링이 부담스러울 때 사용하는 방법이다.
자바스크립트로 함수 만들 때 두가지 방법이 있다.
1. function 함수(){}
2. let 함수 = function(){ }
그럼 막 써도 되는가? No! 🤔
props가 방대하고 클 경우 비효율 적이다.
memo로 감싼 컴포넌트는 재렌더링을 안시키려고 기존 props와 바뀐 props를 비교하는 연산이 추가로 진행되기 때문에, 컴포넌트 내부에 있는 HTML 양이 매우 적을 경우엔 memo는 안쓰는 것이 좋다.
'Front-end > React' 카테고리의 다른 글
| [Node+React] 로그인 구현 (server) (0) | 2022.02.12 |
|---|---|
| Props vs State vs Redux (0) | 2022.01.30 |
| [React] 코딩애플 blog-part3-7 (state 변경함수 사용할 때 주의점 : async) (0) | 2022.01.11 |
| [React] 코딩애플 blog-part3-6 (리액트에서 자주쓰는 if문 작성패턴 5개) (0) | 2022.01.09 |
| [React] 코딩애플 blog-part3-4 (장바구니 기능 완성) (0) | 2022.01.09 |