Conversation
index.html
Outdated
| <head> | ||
| <meta charset="UTF-8" /> | ||
| <link rel="icon" href="/favicon.ico" /> | ||
| <link rel="icon" href="public/favicon.ico" /> |
0a87c03 to
e02afe6
Compare
|
|
||
| const useShowCommitDetails = () => { | ||
| const commitList = useCommitStore((state) => state.commitInfo.commitList); | ||
| const needsVirtualScroll = commitList.length > MAX_LENGTH_RENDERING_BOX; |
There was a problem hiding this comment.
보여주어야 할 결과가 300개 이상일 때 virtual scroll이 적용되도록 해주셨는데 300개로 정해주신 이유가 궁금합니다~ 여러 레포지토리로 테스트한 결과로 나온 평균치일까요?!
There was a problem hiding this comment.
네 맞습니다!
우선은 지금 일일히 확인하기 어렵기 때문에, 여러 레포지토리로 테스트한 결과로 나온 평균치로 300으로 정의하였습니다
| commit={commit} | ||
| /> | ||
| ))} | ||
| </VirtualScroll> |
There was a problem hiding this comment.
컴포넌트는 self closing tag가 가능하니 <VirtualScroll /> 로 변경하는 것이 더 좋을 것 같습니다!
There was a problem hiding this comment.
VirtualScroll 은 self closing tag 로 사용이 불가능합니다!
이유는, 스크롤의 전체 높이를 감싸야지만, children 의 length 를 계산해주고 있기 때문에, 감싸야지 가상 스크롤이 적용됩니다:)
children 을 사용하면, [참고링크]
<ParentComponent>
<ChildComponent/>
</ParantComponent>const ParantComponent =(props) =>{
return <>
{props.children}
</>
}이렇게 children 을 활용할 수 있습니다! 이렇게 활용된 children 을 아래 VirtualScroll.jsx에서, children.length로 활용하고 있습니다!
const containerHeight = (itemHeight + columnGap) * children.length;
const startIndex = Math.max(
Math.floor(relativeY / (itemHeight + columnGap)) - renderAhead,
0
);
const endIndex = Math.min(
Math.ceil(height / (itemHeight + columnGap) + startIndex) + renderAhead,
children.length
);
const visibleItem = children.slice(
Math.max(startIndex, 0),
Math.min(endIndex + 1, children.length)
);There was a problem hiding this comment.
Childern prop인 경우엔 직접 컴포넌트를 감싸주는군요..! 설명 감사합니다~
| children, | ||
| itemHeight, | ||
| columnGap = 0, | ||
| renderAhead = 5, |
There was a problem hiding this comment.
동작과정에서 renderAhead의 의미가 무엇인가요?!
변수명으로 파악되는 부분은 이미 렌더된 값이라고 되어있는데 정확히 어떤 부분인지 궁금합니다!
viewport에 보여지는 부분만 알기 위해 커밋내용의 개수를 미리 파악하여 높이를 계산 후
이 높이만큼 transform을 통해 공간을 확보하게되는 동작 과정으로 봤을 땐 renderAhead이 어떤 역할인지 잘 떠오르지 않아 리뷰남깁니다~!
There was a problem hiding this comment.
우선 스크롤이 아래로 움직일 때, dom 이 스크롤 위치에 따라 붙게 됩니다.
하지만 lazyloading 이라던가, dom 이 늦게 따라서 html 에 붙게 되면 사용자는 스크롤을 내리다가 흰 배경 혹은 Skeleton UI 가 먼저 뜨고 0.몇초후에 dom 이 뜨는 것을 보게 됩니다! 이런 사용자 경험을 개선하기 위해서 미리 먼저 로드를 해주는 갯수를 추가하여, 미리 dom 에 몇개 더 붙도록 해주는 역할을 합니다.
즉, 사용자가 현재 스크롤 위치 위 아래로 추가적인 DOM 요소를 미리 렌더링하여 스크롤 경험을 더 부드럽게 만드는 데 활용된다고 보면 될 것 같습니다!
5개로 잡은 이유는, renderAhead 값이 너무 크면 실제 필요한 데이터보다 많은 DOM 요소를 유지해야 하므로 메모리 사용량이 많아지게 되기 때문에 일반적으로 5-10 개를 적용한다고 합니다!
There was a problem hiding this comment.
일반적으로 5~10개를 잡는지 처음 알았네요! 자세한 설명 감사합니다!
There was a problem hiding this comment.
추가적인 돔 요소를 뜻하는 것이었군요..! 감사합니다~
| const [scrollPosition, setScrollPosition] = useState(() => ({ | ||
| x: window.scrollX, | ||
| y: window.scrollY, | ||
| })); | ||
|
|
||
| useEffect(() => { | ||
| const handleScroll = () => { | ||
| setScrollPosition({ | ||
| x: window.scrollX, | ||
| y: window.scrollY, | ||
| }); | ||
| }; | ||
|
|
There was a problem hiding this comment.
x를 사용하지 않기 때문에 사용하지 않는 state에 대한 불필요한 리소스 소모가 있을 것 같아 조금 조사를 해보았습니다.
- x와 y를 따로 구독해서 이용하기 때문에 x만 변경사항이 있더라도 y에 대한 구독된 요소는 렌더링 되지 않습니다.
- 다만 setter를 이용하기 때문에 비교작업이 일어나 아주 약간의 리소스 소모가 발생합니다.
- 물론 사용하지 않는 x state를 제거하는 것이 이상적이지만, 모듈로 이용하기 위해 놔두는 것이 좋겠습니다.
어떻게 생각하시나요?
There was a problem hiding this comment.
네! 좋은 의견 감사합니다. 저도 고민해보지 못한 부분이라 더 생각해볼만한 주제인 것 같네요 :)
우선 y 값만 사용하고 있지만, 훅을 x, y 로 나누기 보다 useWindowScroll 에서 각 값을 메모이제이션을 활용하여 최적화를 해볼 수 있을 것 같습니다!
useMemo는 특정 값이 변경되지 않으면 이전에 계산된 값을 재사용하기 때문에, x 값이 바뀔때만 다시 계산하도록 최적화해보겠습니다 👍
There was a problem hiding this comment.
네! 유진님 처럼 저도 조금 더 해결방법을 찾아보겠습니다!
There was a problem hiding this comment.
넵! 우선 useMemo 로 수정하여 커밋을 올려두었었는데, 당장 useMemo 를 쓴다고 y 에서만 렌더링 트리거를 할 수 있는 부분이 아니라고 생각하여 해당 커밋 revert 해두었습니다 :)
이후, 같이 논의해보아요~!
| children, | ||
| itemHeight, | ||
| columnGap = 0, | ||
| renderAhead = 5, |
There was a problem hiding this comment.
추가적인 돔 요소를 뜻하는 것이었군요..! 감사합니다~
| commit={commit} | ||
| /> | ||
| ))} | ||
| </VirtualScroll> |
There was a problem hiding this comment.
Childern prop인 경우엔 직접 컴포넌트를 감싸주는군요..! 설명 감사합니다~
This reverts commit 24f8f94.
이슈
🔗 이슈 링크 #68
요약
구현화면 [performance 탭]
virtual scroll 적용안했을 때, INP 첫 로딩의 경험이 굉장히 안좋음
virtual scroll 적용시, CLS 가 조금 안좋지만 이는 개선의 여지가 있음 (-> 추후 skeleton UI 만들기 등으로 해결가능)
작업내용
참고사항
virtualScroll브랜치로 이동하여, 잘 동작하는지 확인부탁드립니다 !PR 체크 사항
주의 사항
PR 전 체크리스트
리뷰 반영사항