1 분 소요

TIL

과제 전형 진행

구현

Input lagging

input 입력 느린 현상

이미지

input에 값을 입력할 때 value가 1~2초 뒤에 나오는 현상을 해결하는 과제였다.

예상 해결 방법

처음 생각했던 것은 uncontrolled input 을 사용해야하나 싶었다.
하지만, 일반적인 경우에 react에서는 controlled input 를 사용해야하므로 이것은 정답이 아닐 것이라고 판단했다.

한참 검색한 결과, input이 입력될때 동안 계속해서 re-rendering이 일어나기 때문에 input value 가 늦게 나타나는 현상이 있는 것이라고 했다.

구현

그래서 어떤 부분이 re-render를 계속해서 일으키는지를 알아야 했다.

일단 리스트를 나타내는 부분이 느릴 것이라고 생각했다.
다른 부분은 input form 부분, tab 부분이므로 굳이 렌더링에 문제가 있을 것이라고 생각하지 않았다.

따라서 먼저 List 나타내는 컴포넌트를 따로 빼서 memo하였다.

  • memo 전

    // App.tsx
    // return
    <Grid container spacing={5} justify="center">
      {/* 아래 라인은 렌더링 부하를 증가시키기 위해 의도한 코드이므로 수정하지 말아주세요 */}
      {[...new Array(10)].flatMap(() =>
        data.map(({ name, price, category }, i) => (
          <Grid item xs={4}>
            <ProductItem
              name={name}
              price={price}
              imgUrl={`https://picsum.photos/345/240?random=${i}`}
              category={category}
            />
          </Grid>
        ))
      )}
    </Grid>
    
  • memo 후

    // App.tsx
    const MemoItemList = memo(({ data }: ItemListProps) => {
      return <ItemList data={data} />;
    });
    
    const { query, data } = useFakeQuery();
    
    // return
    <MemoItemList data={filteredDataOne} />;
    

그러나 memoization을 했음에도 똑같이 input lagging 현상이 있었다.

검색을 더 해보다가, 스택오버플로우에서

setState by itself is not slow, it is only when your renders get very expensive that it starts causing issues.를 보았다.

setState 자체가 느려서 input value가 늦게 나오는 것이 아니라, 렌더될 때 굉장히 무거운/비싼 작업을 하고 있기 때문에 생기는 것이라고 한다.

그래서 보통 해결 방법은 무거운 연산을 하는 함수를 useCallback, useMemo 등을 통해 최적화하는 방법이 있다고 했다.

여기서 어떤 부분이 무겁고 비싼 작업인지 확인했는데, data를 가져오는 부분이었다.

따라서 data를 useMemo 하거나 밖으로 빼야겠다고 생각했다.

// App.tsx
const [filteredData, setFilteredData] = useState<ItemProps[]>([])

// FilterForm.tsx
const { data, query } = useFakeQuery()

data를 따로 뺀 Form 컴포넌트 안에 넣었다.
App은 data를 가져와서 ListItem으로 계속 나타낸다.
그래서 input을 입력하면 계속 렌더링이 일어나고, 또 data를 가져오는 연산을 하니 느려질 수 밖에 없었다.

App에서 관리하던 data는 app에서 state를 하나 생성해서 setState함수를 fakequery data가 있는 곳(FilterForm)으로 넘기고
그 안에서 검색어마다 query하여 필터된 data를 set해주는 방식으로 변경하였다.

결과는 다음과 같다.

이미지

회고 (TIL)

2022.03.28 Daily 회고

✏오늘 한 일

  • 과제 전형
    • ts react 과제

⁉느낀 점

꽤 간단한 것 같은 과제임에도 불구하고 고전을 했다.
tab하고 필터링하는 것이 이리 어려운 것이었나.

어찌어찌 구현은 해놓기는 했으나 매우 더럽고, 보기 좋지 않아보인다.
성능도 좋지 않다. (filter가 적용되지 않은 tab을 누를 때 느리다.)

피드백 주시는 거면 떨어지더라도 공부가 되었음 좋겠다.

🎃현재 나의 상태

과제 전형 어렵구나!
이번 주만 마지막으로 힘내보자!


댓글남기기