Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
160 changes: 154 additions & 6 deletions src/pages/center/MyPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,35 +16,167 @@ import DefaultProfile from '@/assets/images/elder-basic-profile.png';
export default function MyPage() {
const navigate = useNavigate();
const [profileSrc, setProfileSrc] = useState(DefaultProfile);
const [performanceMetrics, setPerformanceMetrics] = useState({
componentMountTime: null,
dataLoadStartTime: null,
dataLoadEndTime: null,
imageLoadStartTime: null,
imageLoadEndTime: null,
});

const { data: managerProfile, isLoading, saveManagerProfile } = useManagerProfile();
const { isEditMode, toggleEditMode, setFormData } = useManagerProfileStore();
const setHeaderProps = useHeaderPropsStore((state) => state.setHeaderProps);
const clearHeaderProps = useHeaderPropsStore((state) => state.clearHeaderProps);

// 컴포넌트 마운트 시간 측정
useEffect(() => {
const mountTime = performance.now();
setPerformanceMetrics((prev) => ({ ...prev, componentMountTime: mountTime }));
console.log('🚀 MyPage 컴포넌트 마운트 시작');

setHeaderProps({ type: 'logo' });
return () => clearHeaderProps();
}, [clearHeaderProps, setHeaderProps]);

// fallback profile image
// React Query 데이터 로딩 상태 추적
useEffect(() => {
if (!isLoading && managerProfile) {
const dataLoadEndTime = performance.now();
setPerformanceMetrics((prev) => ({
...prev,
dataLoadEndTime,
dataLoadStartTime: prev.dataLoadStartTime || prev.componentMountTime,
}));

const dataLoadTime = (prev) =>
prev.dataLoadEndTime && prev.dataLoadStartTime
? (prev.dataLoadEndTime - prev.dataLoadStartTime).toFixed(2)
: 'N/A';

console.log('📊 React Query 데이터 로딩 완료:', {
isLoading,
hasData: !!managerProfile,
dataSource: 'cache', // react-query 캐시에서 가져온 경우
loadTime: dataLoadTime(performanceMetrics),
});
}
}, [isLoading, managerProfile, performanceMetrics]);

// 프로필 이미지 로딩 및 성능 측정
useEffect(() => {
if (!managerProfile) return;

const imageLoadStartTime = performance.now();
setPerformanceMetrics((prev) => ({ ...prev, imageLoadStartTime }));
console.log('🖼️ 프로필 사진 로딩 시작');

// if profile image exists, set profileSrc
if (managerProfile?.imgAddress) {
console.log('📸 기존 프로필 이미지 사용:', managerProfile.imgAddress);
setProfileSrc(managerProfile.imgAddress);
const imageLoadEndTime = performance.now();
setPerformanceMetrics((prev) => ({ ...prev, imageLoadEndTime }));

const imageLoadTime = (imageLoadEndTime - imageLoadStartTime).toFixed(2);
console.log(`⚡ 프로필 사진 로딩 완료 (기존 이미지): ${imageLoadTime}ms`);

// 전체 성능 메트릭 출력
logPerformanceMetrics();
} else {
// if profile image doesn't exist, set default profile image
console.log('🔄 기본 프로필 이미지 로딩 중...');
fetchDefaultImage()
.then((url) => setProfileSrc(url))
.catch(() => setProfileSrc(DefaultProfile));
.then((url) => {
setProfileSrc(url);
const imageLoadEndTime = performance.now();
setPerformanceMetrics((prev) => ({ ...prev, imageLoadEndTime }));

const imageLoadTime = (imageLoadEndTime - imageLoadStartTime).toFixed(2);
console.log(`⚡ 프로필 사진 로딩 완료 (기본 이미지): ${imageLoadTime}ms`);
console.log('📸 기본 이미지 URL:', url);

// 전체 성능 메트릭 출력
logPerformanceMetrics();
})
.catch(() => {
setProfileSrc(DefaultProfile);
const imageLoadEndTime = performance.now();
setPerformanceMetrics((prev) => ({ ...prev, imageLoadEndTime }));

const imageLoadTime = (imageLoadEndTime - imageLoadStartTime).toFixed(2);
console.log(`⚡ 프로필 사진 로딩 완료 (fallback): ${imageLoadTime}ms`);
console.log('⚠️ 기본 이미지 로딩 실패, fallback 이미지 사용');

// 전체 성능 메트릭 출력
logPerformanceMetrics();
});
}
}, [managerProfile]);

// 전체 성능 메트릭 로깅 함수
const logPerformanceMetrics = () => {
const metrics = performanceMetrics;
const now = performance.now();

console.group('📈 전체 성능 메트릭');
console.log(
'🚀 컴포넌트 마운트 시간:',
metrics.componentMountTime ? `${(now - metrics.componentMountTime).toFixed(2)}ms` : 'N/A',
);
console.log(
'📊 데이터 로딩 시간:',
metrics.dataLoadEndTime && metrics.dataLoadStartTime
? `${(metrics.dataLoadEndTime - metrics.dataLoadStartTime).toFixed(2)}ms`
: 'N/A',
);
console.log(
'🖼️ 이미지 로딩 시간:',
metrics.imageLoadEndTime && metrics.imageLoadStartTime
? `${(metrics.imageLoadEndTime - metrics.imageLoadStartTime).toFixed(2)}ms`
: 'N/A',
);
console.log(
'⚡ 총 로딩 시간:',
metrics.componentMountTime ? `${(now - metrics.componentMountTime).toFixed(2)}ms` : 'N/A',
);
console.groupEnd();
};

const handleImgError = useCallback(() => {
const startTime = performance.now();
console.log('❌ 이미지 로딩 에러 발생, 대체 이미지 로딩 시작');

fetchDefaultImage()
.then((url) => setProfileSrc(url))
.catch(() => setProfileSrc(DefaultProfile));
}, []);
.then((url) => {
setProfileSrc(url);
const endTime = performance.now();
console.log(`⚡ 대체 이미지 로딩 완료: ${(endTime - startTime).toFixed(2)}ms`);
console.log('📸 대체 이미지 URL:', url);

// 에러 복구 후 성능 메트릭 업데이트
setPerformanceMetrics((prev) => ({
...prev,
imageLoadEndTime: endTime,
imageLoadStartTime: startTime,
}));
logPerformanceMetrics();
})
.catch(() => {
setProfileSrc(DefaultProfile);
const endTime = performance.now();
console.log(`⚡ fallback 이미지 로딩 완료: ${(endTime - startTime).toFixed(2)}ms`);
console.log('⚠️ 대체 이미지 로딩도 실패, 최종 fallback 이미지 사용');

// 에러 복구 후 성능 메트릭 업데이트
setPerformanceMetrics((prev) => ({
...prev,
imageLoadEndTime: endTime,
imageLoadStartTime: startTime,
}));
logPerformanceMetrics();
});
}, [performanceMetrics]);

// if profile data doesn't exist, redirect to signin page
useEffect(() => {
Expand Down Expand Up @@ -123,6 +255,22 @@ export default function MyPage() {

if (isLoading || !managerProfile) return <Spinner />;

console.log('📊 현재 프로필 사진 상태:', {
profileSrc,
hasManagerProfile: !!managerProfile,
hasImgAddress: !!managerProfile?.imgAddress,
imgSeq: managerProfile?.imgSeq,
reactQueryStatus: {
isLoading,
isFetching: false, // react-query의 isFetching 상태도 확인 가능
dataSource: 'cache', // 캐시에서 가져온 데이터인지 확인
},
zustandState: {
isEditMode,
hasFormData: !!useManagerProfileStore.getState().formData,
},
});

return (
<article className='flex flex-col'>
{/* profile header */}
Expand Down