diff --git a/src/views/Company/components/DynamicTracking/components/DynamicTrackingSkeleton.tsx b/src/views/Company/components/DynamicTracking/components/DynamicTrackingSkeleton.tsx
new file mode 100644
index 00000000..335b0bba
--- /dev/null
+++ b/src/views/Company/components/DynamicTracking/components/DynamicTrackingSkeleton.tsx
@@ -0,0 +1,101 @@
+/**
+ * 动态跟踪 Tab 骨架屏组件
+ * 用于懒加载时显示,提供即时反馈
+ */
+
+import React from 'react';
+import { Box, VStack, HStack, Skeleton, SkeletonText, Card, CardBody } from '@chakra-ui/react';
+
+/**
+ * 新闻动态骨架屏
+ */
+export const NewsPanelSkeleton: React.FC = () => (
+
+ {[1, 2, 3, 4, 5].map((i) => (
+
+
+
+
+
+
+
+
+
+
+
+ ))}
+
+);
+
+/**
+ * 公告列表骨架屏
+ */
+export const AnnouncementsSkeleton: React.FC = () => (
+
+ {[1, 2, 3, 4].map((i) => (
+
+
+
+
+
+
+
+
+
+
+
+ ))}
+
+);
+
+/**
+ * 财报披露日程骨架屏
+ */
+export const DisclosureScheduleSkeleton: React.FC = () => (
+
+
+
+ {[1, 2, 3].map((i) => (
+
+
+
+
+ ))}
+
+
+);
+
+/**
+ * 业绩预告骨架屏
+ */
+export const ForecastPanelSkeleton: React.FC = () => (
+
+
+
+
+
+
+
+
+
+
+
+
+);
+
+/**
+ * 通用内容骨架屏(默认 fallback)
+ */
+export const ContentSkeleton: React.FC = () => (
+
+
+
+);
+
+export default {
+ NewsPanelSkeleton,
+ AnnouncementsSkeleton,
+ DisclosureScheduleSkeleton,
+ ForecastPanelSkeleton,
+ ContentSkeleton,
+};
diff --git a/src/views/Company/components/DynamicTracking/components/index.js b/src/views/Company/components/DynamicTracking/components/index.js
index 44bc24a1..5c37b1bd 100644
--- a/src/views/Company/components/DynamicTracking/components/index.js
+++ b/src/views/Company/components/DynamicTracking/components/index.js
@@ -2,3 +2,12 @@
export { default as NewsPanel } from './NewsPanel';
export { default as ForecastPanel } from './ForecastPanel';
+
+// 骨架屏组件
+export {
+ NewsPanelSkeleton,
+ AnnouncementsSkeleton,
+ DisclosureScheduleSkeleton,
+ ForecastPanelSkeleton,
+ ContentSkeleton,
+} from './DynamicTrackingSkeleton';
diff --git a/src/views/Company/components/DynamicTracking/index.js b/src/views/Company/components/DynamicTracking/index.js
index 71b14540..3110220a 100644
--- a/src/views/Company/components/DynamicTracking/index.js
+++ b/src/views/Company/components/DynamicTracking/index.js
@@ -1,37 +1,73 @@
// src/views/Company/components/DynamicTracking/index.js
// 动态跟踪 - 独立一级 Tab 组件(包含新闻动态等二级 Tab)
+// 优化:子组件懒加载,骨架屏即时反馈
-import React, { useState, useEffect, useMemo } from 'react';
+import React, { useState, useEffect, useMemo, useCallback, memo, lazy } from 'react';
import { Box } from '@chakra-ui/react';
import { FaNewspaper, FaBullhorn, FaCalendarAlt, FaChartBar } from 'react-icons/fa';
import SubTabContainer from '@components/SubTabContainer';
-import AnnouncementsPanel from '../CompanyOverview/BasicInfoTab/components/AnnouncementsPanel';
-import DisclosureSchedulePanel from '../CompanyOverview/BasicInfoTab/components/DisclosureSchedulePanel';
-import { NewsPanel, ForecastPanel } from './components';
+import {
+ NewsPanelSkeleton,
+ AnnouncementsSkeleton,
+ DisclosureScheduleSkeleton,
+ ForecastPanelSkeleton,
+} from './components/DynamicTrackingSkeleton';
-// 二级 Tab 配置
+// 懒加载子组件
+const NewsPanel = lazy(() => import('./components/NewsPanel'));
+const ForecastPanel = lazy(() => import('./components/ForecastPanel'));
+const AnnouncementsPanel = lazy(() =>
+ import('../CompanyOverview/BasicInfoTab/components/AnnouncementsPanel')
+);
+const DisclosureSchedulePanel = lazy(() =>
+ import('../CompanyOverview/BasicInfoTab/components/DisclosureSchedulePanel')
+);
+
+// 二级 Tab 配置(带骨架屏 fallback)
const TRACKING_TABS = [
- { key: 'news', name: '新闻动态', icon: FaNewspaper, component: NewsPanel },
- { key: 'announcements', name: '公司公告', icon: FaBullhorn, component: AnnouncementsPanel },
- { key: 'disclosure', name: '财报披露日程', icon: FaCalendarAlt, component: DisclosureSchedulePanel },
- { key: 'forecast', name: '业绩预告', icon: FaChartBar, component: ForecastPanel },
+ {
+ key: 'news',
+ name: '新闻动态',
+ icon: FaNewspaper,
+ component: NewsPanel,
+ fallback: ,
+ },
+ {
+ key: 'announcements',
+ name: '公司公告',
+ icon: FaBullhorn,
+ component: AnnouncementsPanel,
+ fallback: ,
+ },
+ {
+ key: 'disclosure',
+ name: '财报披露日程',
+ icon: FaCalendarAlt,
+ component: DisclosureSchedulePanel,
+ fallback: ,
+ },
+ {
+ key: 'forecast',
+ name: '业绩预告',
+ icon: FaChartBar,
+ component: ForecastPanel,
+ fallback: ,
+ },
];
/**
* 动态跟踪组件
*
* 功能:
- * - 使用 SubTabContainer 实现二级导航
- * - Tab1: 新闻动态
- * - Tab2: 公司公告
- * - Tab3: 财报披露日程
- * - Tab4: 业绩预告
+ * - 使用 SubTabContainer 实现二级导航(同步渲染,无 loading)
+ * - 子组件懒加载,减少初始包体积
+ * - 每个 Tab 有专属骨架屏,提供即时视觉反馈
*
* @param {Object} props
* @param {string} props.stockCode - 股票代码
*/
-const DynamicTracking = ({ stockCode: propStockCode }) => {
+const DynamicTracking = memo(({ stockCode: propStockCode }) => {
const [stockCode, setStockCode] = useState(propStockCode || '000001');
const [activeTab, setActiveTab] = useState(0);
@@ -50,6 +86,11 @@ const DynamicTracking = ({ stockCode: propStockCode }) => {
[stockCode]
);
+ // Tab 切换回调
+ const handleTabChange = useCallback((index) => {
+ setActiveTab(index);
+ }, []);
+
return (
{
componentProps={componentProps}
themePreset="blackGold"
index={activeTab}
- onTabChange={(index) => setActiveTab(index)}
+ onTabChange={handleTabChange}
isLazy
size="sm"
/>
);
-};
+});
+
+DynamicTracking.displayName = 'DynamicTracking';
export default DynamicTracking;