最简单的new Date()展示,也能做优化

问题诊断

首先,大家来看下这段代码

js 复制代码
function TimeDisplay() {
  const time = new Date().toLocaleTimeString();
  return <div>{time}</div>;
}

是不是看着很简单,很眼熟,很常见,但是这段代码每次渲染都会创建new Date()实例 ➔ 执行toLocaleTimeString() ➔ 触发垃圾回收,在高频更新场景下会产生不必要的性能损耗

优化方案

1. 静态时间展示(只需初始值)
js 复制代码
const [time] = useState(() => new Date().toLocaleTimeString()); // 初始化只执行一次
return <div>{time}</div>;
  • 优点:彻底避免重复实例化,且无副作用
  • 局限:时间不能自动更新
  • 适用场景:展示固定时间
2. useRef固定值
js 复制代码
const timeRef = useRef(new Date().toLocaleTimeString());
return <div>{timeRef.current}</div>;
  • 优点:避免重复实例化;内存占用稳定
  • 局限:时间永不更新
  • 适用场景:静态时间快照
3. useMemo空依赖缓存
js 复制代码
const time = useMemo(() => new Date().toLocaleTimeString(), []);
return <div>{time}</div>;
  • 优点:减少垃圾回收次数;代码简洁

  • 缺点:时间锁定初始值;滥用易导致隐蔽的 BUG

    这里解释一下所谓隐蔽的bug指的是什么

    useMemo是用来缓存结果,避免重复计算的,但是时间这个东西,我们在很多时候属于要么不更新,要么频繁更新,在这种情况下,如果组件频繁挂载或者卸载的话,旧的格式化器无法被GC回收,同时累积大量的缓存对象,会造成内存膨胀。

  • 适用场景:需要复杂计算的初始值缓存

4. useEffect基础动态更新
jsx 复制代码
const [time, setTime] = useState('');
useEffect(() => {
  const timer = setInterval(() => {
    setTime(new Date().toLocaleTimeString());
  }, 1000);
  return () => clearInterval(timer);
}, []);
  • 优点:实现动态更新时间;代码直观易理解
  • 缺点:多组件实例导致定时器泛滥;父组件渲染可能打断计时
  • 适用场景:独立组件的简单时钟
5. 单例模式 + 自定义 Hook
js 复制代码
// 单例服务
const timeService = {
  subscribers: new Set(),
  start() {
    setInterval(() => {
      const time = new Date().toLocaleTimeString();
      this.subscribers.forEach(cb => cb(time));
    }, 1000);
  }
};

// Hook封装
const useGlobalTime = () => {
  const [time, setTime] = useState('');
  useEffect(() => {
    timeService.subscribers.add(setTime);
    return () => timeService.subscribers.delete(setTime);
  }, []);
  return time;
};
  • 优点:全应用共享单一定时器;内存占用恒定 O(1)
  • 缺点:需要维护额外服务模块
  • 适用场景:企业级应用;多组件时间同步需求
6. Web Worker 后台计算
js 复制代码
// worker.js
self.onmessage = () => {
  setInterval(() => {
    self.postMessage(new Date().toLocaleTimeString());
  }, 1000);
};

// 组件
useEffect(() => {
  const worker = new Worker('worker.js');
  worker.onmessage = (e) => setTime(e.data);
  return () => worker.terminate();
}, []);
  • 优点:不阻塞主线程;适合复杂计算场景
  • 缺点:通信成本较高;增加构建复杂度
  • 适用场景:计算密集型任务(如实时图表渲染)
7. Intl.DateTimeFormat 高效格式化
js 复制代码
const formatter = useMemo(() => 
  new Intl.DateTimeFormat('zh-CN', {
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit'
  }), []);

const [time, setTime] = useState('');
useEffect(() => {
  const timer = setInterval(() => {
    setTime(formatter.format(new Date()));
  }, 1000);
  return () => clearInterval(timer);
}, []);
  • 优点:性能比 toLocaleTimeString 快 3 倍;支持本地化配置
  • 缺点:需手动管理格式化实例
  • 适用场景:高频更新场景(如秒表);多语言/时区支持

项目中有很多很不起眼的代码,其实都可以进行优化,有的时候就是这些不起眼的小东西,累积起来会造成大麻烦,快去看看你的项目里有没有可以优化的时间吧,如果有更好的方法,欢迎评论区分享讨论

相关推荐
2501_9153738819 分钟前
Electron 从零开始:构建你的第一个桌面应用
前端·javascript·electron
贩卖黄昏的熊1 小时前
JavaScript 笔记 --- part8 --- JS进阶 (part3)
前端·javascript·笔记
CodeCipher1 小时前
Java后端程序员学习前端之CSS
前端·css·学习
Enti7c2 小时前
JavaScript 实现输入框的撤销功能
开发语言·javascript·ecmascript
每次的天空3 小时前
Android学习总结之GetX库篇(场景运用)
android·javascript·学习
卡戎-caryon3 小时前
【项目实践】boost 搜索引擎
linux·前端·网络·搜索引擎·boost·jieba·cpp-http
清源妙木真菌3 小时前
高并发内存池
linux·性能优化·内存管理
eqwaak04 小时前
基于DrissionPage的高效爬虫开发:以小说网站数据抓取为例
爬虫·python·语言模型·性能优化·交互·drissionpage
别催小唐敲代码4 小时前
解决跨域的4种方法
java·服务器·前端·json
溪饱鱼4 小时前
Nuxt3还能用吗?
前端·个人开发·seo