diff --git a/ui/src/views/list/Card.tsx b/ui/src/views/list/Card.tsx
index 5d9dc8ef..dfa330a6 100644
--- a/ui/src/views/list/Card.tsx
+++ b/ui/src/views/list/Card.tsx
@@ -40,10 +40,20 @@ const Card = (props: CardProps) => {
const [pageSizeOptions, setPageSizeOptions] = useState
) : (
-
- {gridDataSource &&
- data.map((row, idx) => {
+ <>
+
+ {gridDataSource &&
+ data.slice(0, isProgressiveRendering ? renderedCount : data.length).map((row, idx) => {
const keyField = gridDto.gridOptions.keyFieldName
const rowId = row[keyField!]
const isSelected = selectedKeys.has(rowId)
@@ -707,7 +746,7 @@ const Card = (props: CardProps) => {
listFormCode={listFormCode}
dataSource={gridDataSource}
refreshData={loadData}
- getCachedLookupDataSource={getLookupDataSource}
+ getCachedLookupDataSource={memoizedGetLookupDataSource}
isSelected={isSelected}
isFocused={isFocused}
isHovered={isHovered}
@@ -720,7 +759,18 @@ const Card = (props: CardProps) => {
/>
)
})}
-
+
+
+ {/* Progressive rendering sırasında loading göster */}
+ {isProgressiveRendering && renderedCount < data.length && (
+
+
+
+ Yükleniyor... ({renderedCount}/{data.length})
+
+
+ )}
+ >
)}
{gridDto.gridOptions.pagerOptionDto?.visible && totalCount > pageSize && (
diff --git a/ui/src/views/list/CardItem.tsx b/ui/src/views/list/CardItem.tsx
index db3bffed..90c75a81 100644
--- a/ui/src/views/list/CardItem.tsx
+++ b/ui/src/views/list/CardItem.tsx
@@ -3,7 +3,7 @@ import { useLocalization } from "@/utils/hooks/useLocalization"
import { usePermission } from "@/utils/hooks/usePermission"
import { usePWA } from "@/utils/hooks/usePWA"
import CustomStore from "devextreme/data/custom_store"
-import { useMemo, useRef, useState, forwardRef } from "react"
+import { useMemo, useRef, useState, forwardRef, memo, useEffect } from "react"
import { useNavigate } from "react-router-dom"
import { GroupItem } from 'devextreme/ui/form'
import { PermissionResults, SimpleItemWithColData } from "../form/types"
@@ -66,15 +66,48 @@ const CardItem = forwardRef((
}, [gridDto])
const [formData, setFormData] = useState(row)
const refForm = useRef(null)
+ const cardElementRef = useRef(null)
const navigate = useNavigate()
const { translate } = useLocalization()
const { checkPermission } = usePermission()
const isPwaMode = usePWA()
+
+ // Lazy load form with Intersection Observer - sadece görünür kartları render et
+ const [shouldRenderForm, setShouldRenderForm] = useState(false)
+
+ useEffect(() => {
+ const element = cardElementRef.current
+ if (!element) return
+
+ // Intersection Observer ile görünürlük kontrolü
+ const observer = new IntersectionObserver(
+ (entries) => {
+ entries.forEach((entry) => {
+ if (entry.isIntersecting) {
+ // Kart görünür hale geldiğinde form'u render et
+ setShouldRenderForm(true)
+ // Bir kez render edildikten sonra observer'ı kaldır
+ observer.disconnect()
+ }
+ })
+ },
+ {
+ rootMargin: '50px', // 50px önceden yüklemeye başla
+ threshold: 0.01, // %1 görünür olduğunda tetikle
+ }
+ )
+
+ observer.observe(element)
+
+ return () => {
+ observer.disconnect()
+ }
+ }, [])
const keyField = gridDto.gridOptions.keyFieldName
const rowId = row[keyField!]
- // Form Items
+ // Form Items - memoized to prevent recalculation on every render
const formItems: GroupItem[] = useMemo(() => {
if (!gridDto) return []
@@ -165,7 +198,16 @@ const CardItem = forwardRef((
return (
{
+ // Forward ref to parent
+ if (typeof ref === 'function') {
+ ref(element)
+ } else if (ref) {
+ ref.current = element
+ }
+ // Also save to local ref for Intersection Observer
+ cardElementRef.current = element
+ }}
tabIndex={tabIndex}
onClick={onClick}
onDoubleClick={onDoubleClick}
@@ -233,14 +275,23 @@ const CardItem = forwardRef((
)}
-
+ {shouldRenderForm ? (
+
+ ) : (
+
+ )}
)
@@ -248,4 +299,15 @@ const CardItem = forwardRef((
CardItem.displayName = 'CardItem'
-export default CardItem
\ No newline at end of file
+// Memoize to prevent unnecessary re-renders when parent re-renders
+export default memo(CardItem, (prevProps, nextProps) => {
+ // Custom comparison to prevent re-render when not needed
+ return (
+ prevProps.row === nextProps.row &&
+ prevProps.isSelected === nextProps.isSelected &&
+ prevProps.isFocused === nextProps.isFocused &&
+ prevProps.isHovered === nextProps.isHovered &&
+ prevProps.gridDto === nextProps.gridDto &&
+ prevProps.listFormCode === nextProps.listFormCode
+ )
+})
\ No newline at end of file