두 문서나 이미지 등을 비교하는 뷰어에 Panning 기능이 있는데, 최근에 이 기능에 대한 개선요청이 들어왔다.
요청사항은 아니었지만 기능을 살펴보던 중 두 작업물에 싱크가 걸려있는 상태에서 Panning 기능을 수행하면, 싱크가 깨지는 문제를 발견했다. 또 각 뷰어에 중복된 코드가 존재해서 코드 공통화와 함께 싱크 문제를 해결해보기로 했다.
싱크 문제 해결: useEffect 활용
useEffect(() => {
element?.style.transform = `matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, ${xx}, ${yy}, 0, 1)`;
element_right?.style.transform = `matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, ${xx_right}, ${yy_right}, 0, 1)`;
}, [xx, yy, xx_right, yy_right, element, element_right]);
동일한 useEffect
블록에서 element
와 element_right
를 모두 업데이트 하고 있기 때문에 문제가 있을 수 있겠다 라고 생각했는데 아니나 다를까 싱크는 되지만 움직일 때 딜레이가 발생하는 것처럼 보였다.
딜레이 문제 해결: useLayoutEffect 활용
useLayoutEffect(() => {
element?.style.transform = `matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, ${xx}, ${yy}, 0, 1)`;
element_right?.style.transform = `matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, ${xx_right}, ${yy_right}, 0, 1)`;
}, [xx, yy, xx_right, yy_right, element, element_right]);
useEffect
는 비동기로 실행되는 훅으로 렌더링 이후에 실행되는 반면,useLayoutEffect
는 동기로 실행되는 훅으로 렌더링 이후에 화면에 그려지기 전에 실행된다.
따라서, 두 element의 값이 전부 바뀐 후 paint되서 화면상의 딜레이가 사라진 것처럼 보였다.
주의사항
useLayoutEffect
에 대한 공식문서(https://react.dev/reference/react/useLayoutEffect)를 읽어보면 제일 상단에 성능을 저하시킬 수 있기 때문에 가능하면 useEffect
를 사용하라고 쓰여있다.
이번 경우엔 문제 없이 쓸 수 있었는데 사용할 땐 항상 신중히 사용하는게 좋을 것 같다.
'React' 카테고리의 다른 글
[React] 다국어 지원 자동화하기 - i18next, Google Spreadsheet (0) | 2024.05.26 |
---|---|
[React] i18next를 이용한 다국어 지원 구현하기 (0) | 2024.05.20 |
[React] 회원가입 유효성 검사(react-material-ui-form-validator 라이브러리 사용) (0) | 2022.11.08 |