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

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

相关推荐
snakeshe10101 分钟前
剖析 React Commit 阶段:详解工作流程与三大核心模块
前端
爱生活的前端狗2 分钟前
一次大批量处理视频文件的性能优化记录
前端·javascript·vue.js
不讲道理的柯里昂4 分钟前
基于 JSXGraph + Vue3.0 的交互式几何作图组件开发实践
前端
wordbaby5 分钟前
Axios 封装:集成 Loading、Token、401 与 503 智能重试
前端
Mike_jia8 分钟前
一篇文章带你了解一款强大的LLM应用开发平台---Dify
前端·开源
Riesenzahn9 分钟前
React Hooks 的优势和使用场景
前端·javascript
和和和12 分钟前
前端面试中常见的 CSS 相关问题
前端·css
pe7er14 分钟前
一篇文章教会你使用命令行工具vi
前端·程序员
北京_宏哥15 分钟前
🔥PC端自动化测试实战教程-7-pywinauto等待方法大集合 (详细教程)
前端·windows·python
BabyShell16 分钟前
浏览器插件开发-创建自己的启动页
前端·chrome