Add Lazy Loading for Dashboard Components with LazyWhenVisible
All checks were successful
farmcontrol/farmcontrol-ui/pipeline/head This commit looks good
All checks were successful
farmcontrol/farmcontrol-ui/pipeline/head This commit looks good
- Introduced LazyWhenVisible component to optimize rendering of dashboard sections based on scroll visibility, improving performance. - Updated DashboardOverviewPage to utilize LazyWhenVisible for sections containing stats, history, or tables, enhancing user experience by loading content only when visible. - Added useScrollVisibility hook to manage visibility state, ensuring efficient resource usage during scrolling.
This commit is contained in:
parent
b212331129
commit
e3a20e6b48
@ -16,6 +16,7 @@ import ScrollBox from './ScrollBox'
|
|||||||
import InfoCollapse from './InfoCollapse'
|
import InfoCollapse from './InfoCollapse'
|
||||||
import StatsDisplay, { StatsViewButton } from './StatsDisplay'
|
import StatsDisplay, { StatsViewButton } from './StatsDisplay'
|
||||||
import ModelHistoryDisplay from './ModelHistoryDisplay'
|
import ModelHistoryDisplay from './ModelHistoryDisplay'
|
||||||
|
import LazyWhenVisible from './LazyWhenVisible'
|
||||||
import ObjectTable from './ObjectTable'
|
import ObjectTable from './ObjectTable'
|
||||||
import DashboardOverviewFlexColumns from './DashboardOverviewFlexColumns'
|
import DashboardOverviewFlexColumns from './DashboardOverviewFlexColumns'
|
||||||
import useCollapseState from '../hooks/useCollapseState'
|
import useCollapseState from '../hooks/useCollapseState'
|
||||||
@ -734,12 +735,11 @@ const DashboardOverviewPage = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const renderCollapse = (section, dragHandle = null) => {
|
const renderCollapse = (section, dragHandle = null) => {
|
||||||
const statsObjectType =
|
const isStats = section.content?.type === StatsDisplay
|
||||||
section.content?.type === StatsDisplay
|
const statsObjectType = isStats ? section.content.props?.objectType : null
|
||||||
? section.content.props?.objectType
|
|
||||||
: null
|
|
||||||
const isHistory = section.content?.type === ModelHistoryDisplay
|
const isHistory = section.content?.type === ModelHistoryDisplay
|
||||||
const isTable = section.content?.type === ObjectTable
|
const isTable = section.content?.type === ObjectTable
|
||||||
|
const isLazyContent = isStats || isHistory || isTable
|
||||||
const resizable = isHistory || isTable
|
const resizable = isHistory || isTable
|
||||||
const defaultHeight = isHistory
|
const defaultHeight = isHistory
|
||||||
? DEFAULT_HISTORY_HEIGHT
|
? DEFAULT_HISTORY_HEIGHT
|
||||||
@ -757,6 +757,19 @@ const DashboardOverviewPage = ({
|
|||||||
: cloneElement(content, { scrollHeight: `${contentHeight}px` })
|
: cloneElement(content, { scrollHeight: `${contentHeight}px` })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isLazyContent && content) {
|
||||||
|
content = (
|
||||||
|
<LazyWhenVisible
|
||||||
|
scrollRootRef={scrollRef}
|
||||||
|
minHeight={
|
||||||
|
isHistory || isTable ? contentHeight : 120
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{content}
|
||||||
|
</LazyWhenVisible>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<InfoCollapse
|
<InfoCollapse
|
||||||
title={section.title}
|
title={section.title}
|
||||||
|
|||||||
34
src/components/Dashboard/common/LazyWhenVisible.jsx
Normal file
34
src/components/Dashboard/common/LazyWhenVisible.jsx
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import PropTypes from 'prop-types'
|
||||||
|
import useScrollVisibility from '../hooks/useScrollVisibility'
|
||||||
|
|
||||||
|
const LazyWhenVisible = ({
|
||||||
|
scrollRootRef,
|
||||||
|
minHeight,
|
||||||
|
enabled = true,
|
||||||
|
children
|
||||||
|
}) => {
|
||||||
|
const { targetRef, isVisible } = useScrollVisibility(scrollRootRef, {
|
||||||
|
enabled
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!enabled || isVisible) {
|
||||||
|
return children
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
ref={targetRef}
|
||||||
|
style={minHeight != null ? { minHeight } : undefined}
|
||||||
|
aria-hidden
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
LazyWhenVisible.propTypes = {
|
||||||
|
scrollRootRef: PropTypes.shape({ current: PropTypes.instanceOf(Element) }),
|
||||||
|
minHeight: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
||||||
|
enabled: PropTypes.bool,
|
||||||
|
children: PropTypes.node
|
||||||
|
}
|
||||||
|
|
||||||
|
export default LazyWhenVisible
|
||||||
50
src/components/Dashboard/hooks/useScrollVisibility.js
Normal file
50
src/components/Dashboard/hooks/useScrollVisibility.js
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
import { useEffect, useRef, useState } from 'react'
|
||||||
|
|
||||||
|
const useScrollVisibility = (
|
||||||
|
scrollRootRef,
|
||||||
|
{ rootMargin = '200px 0px', threshold = 0, enabled = true } = {}
|
||||||
|
) => {
|
||||||
|
const targetRef = useRef(null)
|
||||||
|
const [isVisible, setIsVisible] = useState(!enabled)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!enabled || isVisible) return undefined
|
||||||
|
|
||||||
|
const target = targetRef.current
|
||||||
|
if (!target) return undefined
|
||||||
|
|
||||||
|
let observer
|
||||||
|
let cancelled = false
|
||||||
|
|
||||||
|
const attach = () => {
|
||||||
|
if (cancelled) return
|
||||||
|
|
||||||
|
const root = scrollRootRef?.current
|
||||||
|
if (!root) {
|
||||||
|
requestAnimationFrame(attach)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
observer = new IntersectionObserver(
|
||||||
|
([entry]) => {
|
||||||
|
if (entry.isIntersecting) {
|
||||||
|
setIsVisible(true)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ root, rootMargin, threshold }
|
||||||
|
)
|
||||||
|
observer.observe(target)
|
||||||
|
}
|
||||||
|
|
||||||
|
attach()
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
cancelled = true
|
||||||
|
observer?.disconnect()
|
||||||
|
}
|
||||||
|
}, [scrollRootRef, rootMargin, threshold, enabled, isVisible])
|
||||||
|
|
||||||
|
return { targetRef, isVisible }
|
||||||
|
}
|
||||||
|
|
||||||
|
export default useScrollVisibility
|
||||||
Loading…
x
Reference in New Issue
Block a user