Skip to content

Commit

Permalink
fix: reduce the ResizeObserver recreation
Browse files Browse the repository at this point in the history
* feat: add memo for useSize argument

add `React.useMemo` for `useSize` input param to prevent callback may accidentally recreated, which makes ResizeObserver recreation

* fix: reduce resize observer recreation

---------

Co-authored-by: Petyo Ivanov <[email protected]>
  • Loading branch information
dickeylth and petyosi authored Jul 12, 2024
1 parent 9a93e93 commit e27936a
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 24 deletions.
6 changes: 3 additions & 3 deletions src/TableVirtuoso.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ const Viewport: React.FC<React.PropsWithChildren<unknown>> = ({ children }) => {
const ctx = React.useContext(VirtuosoMockContext)
const viewportHeight = usePublisher('viewportHeight')
const fixedItemHeight = usePublisher('fixedItemHeight')
const viewportRef = useSize(u.compose(viewportHeight, (el) => correctItemSize(el, 'height')))
const viewportRef = useSize(React.useMemo(() => u.compose(viewportHeight, (el) => correctItemSize(el, 'height')), [viewportHeight]))

React.useEffect(() => {
if (ctx) {
Expand Down Expand Up @@ -217,8 +217,8 @@ const TableRoot: React.FC<TableRootProps> = /*#__PURE__*/ React.memo(function Ta
const fixedHeaderContent = useEmitterValue('fixedHeaderContent')
const fixedFooterContent = useEmitterValue('fixedFooterContent')
const context = useEmitterValue('context')
const theadRef = useSize(u.compose(fixedHeaderHeight, (el) => correctItemSize(el, 'height')))
const tfootRef = useSize(u.compose(fixedFooterHeight, (el) => correctItemSize(el, 'height')))
const theadRef = useSize(React.useMemo(() => u.compose(fixedHeaderHeight, (el) => correctItemSize(el, 'height')), [fixedHeaderHeight]))
const tfootRef = useSize(React.useMemo(() => u.compose(fixedFooterHeight, (el) => correctItemSize(el, 'height')), [fixedFooterHeight]))
const TheScroller = customScrollParent || useWindowScroll ? WindowScroller : Scroller
const TheViewport = customScrollParent || useWindowScroll ? WindowViewport : Viewport
const TheTable = useEmitterValue('TableComponent')
Expand Down
6 changes: 3 additions & 3 deletions src/Virtuoso.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ const Header: React.FC = /*#__PURE__*/ React.memo(function VirtuosoHeader() {
const Header = useEmitterValue('HeaderComponent')
const headerHeight = usePublisher('headerHeight')
const headerFooterTag = useEmitterValue('headerFooterTag')
const ref = useSize((el) => headerHeight(correctItemSize(el, 'height')))
const ref = useSize(React.useMemo(() => (el) => headerHeight(correctItemSize(el, 'height')), [headerHeight]))
const context = useEmitterValue('context')
return Header
? React.createElement(headerFooterTag, { ref }, React.createElement(Header, contextPropIfNotDomElement(Header, context)))
Expand All @@ -235,7 +235,7 @@ const Footer: React.FC = /*#__PURE__*/ React.memo(function VirtuosoFooter() {
const Footer = useEmitterValue('FooterComponent')
const footerHeight = usePublisher('footerHeight')
const headerFooterTag = useEmitterValue('headerFooterTag')
const ref = useSize((el) => footerHeight(correctItemSize(el, 'height')))
const ref = useSize(React.useMemo(() => (el) => footerHeight(correctItemSize(el, 'height')), [footerHeight]))
const context = useEmitterValue('context')
return Footer
? React.createElement(headerFooterTag, { ref }, React.createElement(Footer, contextPropIfNotDomElement(Footer, context)))
Expand Down Expand Up @@ -327,7 +327,7 @@ const Viewport: React.FC<React.PropsWithChildren<unknown>> = ({ children }) => {
const viewportHeight = usePublisher('viewportHeight')
const fixedItemHeight = usePublisher('fixedItemHeight')
const alignToBottom = useEmitterValue('alignToBottom')
const viewportRef = useSize(u.compose(viewportHeight, (el) => correctItemSize(el, 'height')))
const viewportRef = useSize(React.useMemo(() => u.compose(viewportHeight, (el) => correctItemSize(el, 'height')), [viewportHeight]))

React.useEffect(() => {
if (ctx) {
Expand Down
46 changes: 28 additions & 18 deletions src/VirtuosoGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,19 +72,24 @@ const GridItems: React.FC = /*#__PURE__*/ React.memo(function GridItems() {
const log = useEmitterValue('log')
const stateRestoreInProgress = useEmitterValue('stateRestoreInProgress')

const listRef = useSize((el) => {
const scrollHeight = el.parentElement!.parentElement!.scrollHeight
scrollHeightCallback(scrollHeight)
const firstItem = el.firstChild as HTMLElement
if (firstItem) {
const { width, height } = firstItem.getBoundingClientRect()
itemDimensions({ width, height })
}
gridGap({
row: resolveGapValue('row-gap', getComputedStyle(el).rowGap, log),
column: resolveGapValue('column-gap', getComputedStyle(el).columnGap, log),
})
})
const listRef = useSize(
React.useMemo(
() => (el) => {
const scrollHeight = el.parentElement!.parentElement!.scrollHeight
scrollHeightCallback(scrollHeight)
const firstItem = el.firstChild as HTMLElement
if (firstItem) {
const { width, height } = firstItem.getBoundingClientRect()
itemDimensions({ width, height })
}
gridGap({
row: resolveGapValue('row-gap', getComputedStyle(el).rowGap, log),
column: resolveGapValue('column-gap', getComputedStyle(el).columnGap, log),
})
},
[scrollHeightCallback, itemDimensions, gridGap, log]
)
)

if (stateRestoreInProgress) {
return null
Expand Down Expand Up @@ -124,7 +129,7 @@ const Header: React.FC = React.memo(function VirtuosoHeader() {
const Header = useEmitterValue('HeaderComponent')
const headerHeight = usePublisher('headerHeight')
const headerFooterTag = useEmitterValue('headerFooterTag')
const ref = useSize((el) => headerHeight(correctItemSize(el, 'height')))
const ref = useSize(React.useMemo(() => (el) => headerHeight(correctItemSize(el, 'height')), [headerHeight]))
const context = useEmitterValue('context')
return Header
? React.createElement(headerFooterTag, { ref }, React.createElement(Header, contextPropIfNotDomElement(Header, context)))
Expand All @@ -135,7 +140,7 @@ const Footer: React.FC = React.memo(function VirtuosoGridFooter() {
const Footer = useEmitterValue('FooterComponent')
const footerHeight = usePublisher('footerHeight')
const headerFooterTag = useEmitterValue('headerFooterTag')
const ref = useSize((el) => footerHeight(correctItemSize(el, 'height')))
const ref = useSize(React.useMemo(() => (el) => footerHeight(correctItemSize(el, 'height')), [footerHeight]))
const context = useEmitterValue('context')
return Footer
? React.createElement(headerFooterTag, { ref }, React.createElement(Footer, contextPropIfNotDomElement(Footer, context)))
Expand All @@ -147,9 +152,14 @@ const Viewport: React.FC<React.PropsWithChildren<unknown>> = ({ children }) => {
const itemDimensions = usePublisher('itemDimensions')
const viewportDimensions = usePublisher('viewportDimensions')

const viewportRef = useSize((el) => {
viewportDimensions(el.getBoundingClientRect())
})
const viewportRef = useSize(
React.useMemo(
() => (el: HTMLElement) => {
viewportDimensions(el.getBoundingClientRect())
},
[viewportDimensions]
)
)

React.useEffect(() => {
if (ctx) {
Expand Down

0 comments on commit e27936a

Please sign in to comment.