最简单的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 倍;支持本地化配置
  • 缺点:需手动管理格式化实例
  • 适用场景:高频更新场景(如秒表);多语言/时区支持

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

相关推荐
Hilaku13 分钟前
为什么死磕 1px 的团队,用户体验反而更差?
前端·javascript·程序员
lichenyang45325 分钟前
鸿蒙元服务跳转 H5 太慢?从 Web 内核预热、网络预连接到骨架屏的完整优化方案
前端
aa小小34 分钟前
大屏的数据应该怎么做“实时更新“?大屏页面如果一直开着不关(比如挂了几天几夜),你觉得可能会出现什么问题,需要怎么预防?
前端·数据可视化
陈拉斯42 分钟前
给公司年会写了个大屏抽奖系统:动画在前端跑,凭什么说结果没被改?
javascript
aa小小1 小时前
Proxy 响应式原理
前端·proxy
计算机魔术师1 小时前
Latent Space 访谈 TypeSafe CEO Diogo Almeida:Jev 是面向生产环境的 System One 模型而非万能 God 模型
前端
yzy851 小时前
Vue中下载或打开文件的JavaScript方法
前端·javascript·vue
用户298698530141 小时前
在 React 中用 JavaScript 将 Word 转换为文本
前端·javascript·react.js
计算机魔术师2 小时前
马斯克称 Grok 4.7 使 xAI 在智能体编码领域位列第三
前端