首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么我的UI会冻结,直到api调用终止?

UI冻结通常是因为在等待API调用完成时,主线程被阻塞了。以下是一些基础概念和相关解决方案:

基础概念

  1. 主线程:在大多数现代Web应用中,JavaScript运行在单线程环境中,即主线程。这个线程负责处理所有的DOM操作、事件处理和UI渲染。
  2. 异步编程:为了避免阻塞主线程,通常会使用异步编程技术,如回调函数、Promise、async/await等。
  3. API调用:当浏览器向服务器发送请求并等待响应时,如果这个过程是同步的,那么主线程会被阻塞,导致UI冻结。

原因分析

  • 同步API调用:如果你使用了同步的XMLHttpRequest或Fetch API,主线程会在等待响应时被阻塞。
  • 长时间运行的JavaScript任务:如果在主线程上执行了耗时的计算或操作,也会导致UI冻结。

解决方案

  1. 使用异步API调用
    • 使用fetch API并返回Promise。
    • 使用fetch API并返回Promise。
  • Web Workers
    • 对于特别耗时的任务,可以将其移到Web Workers中执行,以避免阻塞主线程。
    • 对于特别耗时的任务,可以将其移到Web Workers中执行,以避免阻塞主线程。
  • 优化JavaScript代码
    • 避免在主线程上执行长时间运行的任务,可以将任务分解为更小的部分,并使用setTimeoutrequestAnimationFrame来分批处理。
  • 使用框架提供的异步机制
    • 如果你在使用React、Vue等框架,它们通常提供了内置的异步处理机制,如React的useEffect钩子或Vue的async组件。

应用场景

  • 实时应用:如在线游戏、实时聊天应用等,需要保持UI的流畅性。
  • 数据处理密集型应用:如数据分析工具、图像处理软件等,可能需要处理大量数据而不会阻塞UI。

通过上述方法,可以有效避免UI冻结的问题,提升用户体验。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

【Web技术】850- 深入了解页面生命周期API

现在的现代浏览器有时会在系统资源紧张的情况下暂停页面或完全丢弃页面--菲利普-沃尔顿。 那么你可能会有疑问,既然浏览器已经处理好了,我们为什么还要担心这个问题呢? 并非完全如此,浏览器会照顾到一切。...此外,这些浏览器的干预会直接影响到JavaScript的执行。好消息是,几乎所有的现代浏览器都通过页面生命周期API将这些干预作为事件暴露出来。...但是,正在运行的任务会继续进行,直到完成。但定时器、回调函数执行和DOM操作将被停止以释放CPU。...Chrome浏览器资源消耗 当我查看电脑上Chrome浏览器的资源消耗时,我观察到两个活动标签页分别消耗了14.7%和11%的CPU,而冻结的标签页消耗了近0%的CPU。...DISCARDED - 为了节省资源,将冻结状态移动到Discarded状态。 假设一个网页长时间处于冻结状态,在这种情况下,浏览器会自动将网页卸载到丢弃状态,以节省资源。

1.3K20

浏览器中实现JavaScript计时器的4种创新方式

UI线程的成本几乎为零。 利用 Web Workers 的消息传递设计,从UI线程角度完全异步。...安全结束,与 setInterval 不同,调用 worker.terminate 保证不会再收到任何消息。 引用MDN:“ Worker 的 Terminate() 方法立即终止 Worker。...它不会为等待 Worker 完成里面执行的程序,而是会立即停止。” 缺点 即使你可以做出毫秒级的决策,但返回UI线程的消息传递也是异步的。你无法像在 Worker 中做出决定那样及时渲染。...这就是为什么我建议创建一个像这样的任意不存在的标记的原因 。...不准确 根据我的测试,它可能会延迟15ms。 直到整页加载才开始。是的,可能是一个缺点,但是也是一个功能。 使用 Web Animations API ?

1.9K30
  • 【QT】解决继承QThread的子线程导致程序无法关闭&主线程关闭太快导致子线程中的槽方法未执行

    就是因为run函数中的while(open_flag)没有被更改为false从而终止循环。 为什么没被更改? 因为我们的信号对应的槽函数没有被执行?...为什么没被执行? 因为使用参数Qt::QueuedConnection被放到了主线程的事件队列中,等待当前代码执行完毕之后被执行. 解决方式 在该发送信号后手动调用事件处理。...阻塞线程,直到满足以下任一条件: 与此QThread对象关联的线程已完成执行(即,当它从run()返回时)。如果线程已完成,此函数将返回true。如果线程还没有启动,它也会返回true。...的第五个参数,Qt会根据情况自动的选取。...,我可能还没有细挖,感兴趣的小伙伴可以自行查阅资料,有好的内容可以告诉我。

    1K10

    【译】使用 Web Workers 优化 JavaScript 应用程序性能

    像是UI更新,用户交互,图片缩放之类的任务需要被放进一个任务队列,并使用浏览器的 JavaScript 引擎依次执行。 这个单线程的设计模式为性能带来的最大问题就是阻塞。...当主线程执行一个需要非常长时间的任务时,阻塞就会发生,阻塞会影响其他所有任务的执行,会导致web程序执行缓慢或是卡顿,这对于用户体验来说是非常糟糕的。...终止 Web Worker 创建 Web Worker 会在用户的计算机上生成实际线程,从而消耗系统资源。因此,一个比较好的做法是在 worker 执行完毕后终止 worker。...可以通过调用 worker 上的 terminate() 方法终止 worker。无论是否正在执行任务,这都会立即终止 worker。worker 也可以在它自己的线程内被终止。...然后点击页面上的 Start 按钮,随后点击 Run calculation 按钮。 在动画冻结几秒后,点击开发者工具中的结束录制,你会获得一张和下图相似的结果: ?

    1.8K10

    技术速递|调用异步功能 - WinForms 在 .NET 9 中的未来发展

    这些新增功能包括: Control.InvokeAsync – 在 .NET 9 中全面发布的 API,有助于异步调用调用 UI 线程。...当调用 Control.Invoke 时,它会将指定的委托同步发送到 UI 线程的消息队列。这是一个阻塞操作,意味着调用线程会等待 UI 线程处理完该委托后才能继续。...这种方法不仅有助于防止“冻结的 UI”体验,还能保持应用程序的响应性,即使在处理大量与 UI 绑定的任务时也能保持流畅。...为什么要避免这种做法?当你使用 async void 时,调用者无法等待或观察方法的完成。这可能导致未处理的异常或意外行为。...接着它启动一个后台运行的 WaitAsync-Waiter,直到等待期结束。然后,触发 WaitAsync-Callback,实际上要求消息循环重新进入调用并完成所有跟随该异步调用的操作。

    9110

    W3C TPAC 大会上的 Service workers 内容总结

    但是在规范中有一个地方讲到:如果一个名为 serviceWorker.register() 的页面具有相同的作用域,则被注销的 service worker 注册将会“复苏”。我不知道为什么要这么做。...页面生命周期和 service workers 我是 page lifecycle API (https://developers.google.com/web/updates/2018/07/page-lifecycle-api...对冻结的客户端的 client.postMessage() 调用将被缓冲,就像 BroadcastChannel 一样。...常规注销将保持不变,但是我将指定一种方法来立即注销 service worker,这可能会终止正在运行的脚本并中止正在进行的提取。...有人担心,无论这些东西出现在什么UI上,网站都可以使用它来发送垃圾邮件。但是,浏览器可以自由地忽略或验证所告知的任何内容。 这是个非常新的提案,它已作提交给小组。

    84910

    Service 知识要点

    在调用这个 api 之后应马上调用 Service#startForeground(int, Notification),来设置 Notification,否则系统会自动停止 Service,并发生 ANR...注:API 大于等于 26 时,当 app 不在前台的时候,后台服务会受到限制,这种情况下,官方文档推荐使用 Schedule jobs。...多个 Activity 绑定和解绑时,Service 会重复走 onBind()/onUnbind()这两个生命周期,但不会销毁,直到没有 Activity 和它有绑定关系的时候,才会销毁。...IntentService 原理 大家都知道,IntentService 的特性是运行在非 UI 线程,可执行耗时操作,当执行完后会自动销毁。...在函数执行结束后调用 stopSelf(msg.arg1) 终止服务,这也就是为什么任务执行完毕后会自动销毁的原因。

    73510

    【愚公系列】2023年11月 WPF控件专题 2023秋招WPF高频面试题

    可以轻松绘制可缩放的矢量图形而不会出现锯齿状锯齿。2. 说说WPF中的XAML是什么?为什么需要它?它只存在于WPF吗? XAML 是用来组织 WPF UI 的 XML 文件。...冻结 Freezable 可以提高其性能,因为它不再需要在更改通知上花费资源。 冻结的 Freezable 也可以跨线程共享,而未冻结的 Freezable 则不能。...39.为什么需要依赖属性?...如果没有设置本地值,则依赖属性会向上导航逻辑树,直到找到一个值。 当您在根元素上设置 FontSize 时,它适用于下面的所有文本块,除非在元素中覆盖该属性值。...如果没有设置本地值,则依赖属性会向上导航逻辑树,直到找到一个值。 当您在根元素上设置 FontSize 时,它适用于下面的所有文本块,除非在元素中覆盖该属性值。

    53222

    Android面试:怎么理解 onStart可见但不可交互?不要小瞧了这个问题,涉及面很多!

    这就涉及到进程的分类。 为了确定在内存不足时应该终止哪些进程,Android 会根据每个进程中运行的组件以及这些组件的状态,将它们放入“重要性层次结构”。...优先级的高低其实就代表了 终止进程的顺序,也代表了对用户的影响程度。 当然实际代码中,进程优先级是有数字表示的,也就是ADJ,而上面说的进程类型都有相应的进程优先级数字范围。...应用会一直保持这种状态,直到某些事件发生,让焦点远离应用。此类事件包括接到来电、用户导航到另一个 Activity,或设备屏幕关闭。...另外,我自己也珍藏了好几套视频,有需要的我也可以分享给你。 2、进行系统梳理知识,提升储备 客户端开发的知识点就那么多,面试问来问去还是那么点东西。...开发+API操作+微信对接 Hybrid 开发与Flutter:Html5项目实战+Flutter进阶 知识梳理完之后,就需要进行查漏补缺,所以针对这些知识点,我手头上也准备了不少的电子书和笔记,这些笔记将各个知识点进行了完美的总结

    1.2K12

    线程间通讯:WaitHandler使用实例及分析

    实例效果: 1.点击“启动线程”会启动一个线程t每隔2秒在listbox上插入一条新记录。 2.点击“关闭线程”会停止线程t,但不是马上停止而是等待线程t当次循环的工作后再结束。...而WaitOne()就是阻塞当前线程直到实例被设为终止状态,而WaitOne()方法有多个重载方法,可以设定阻塞时间,超过了阻塞时间实例状态依然为非终止的话就放弃阻塞,让线程继续执行WaitOne语句以下的内容...上述代码中线程t自杀时通过另一个ManualResetEvent实例告诉ui线程“我挂了!”,好让ui线程做善后工作。...检查线程t是否已死的过程是一直占用ui线程的,而窗口上控件的交互也是由ui线程来处理,这时会出现画面假死的状态,如果发出了调用ui线程处理其他事件的话就会有异常。...要实现上述的子线程自杀方式也可以用两个静态变量来做控制,至于实现方法我这里就不写了。

    63650

    React 并发功能体验-前端的并发模式已经到来。

    节流限制特定函数被调用的次数。使用节流,我们可以避免重复调用昂贵和耗时的API或函数。这个过程能够提高性能,尤其是在用户界面上呈现信息。 防抖会在预定的时间内忽略对函数的调用。...函数调用仅在经过预定时间后进行。 下图描述了卡顿现象: 在等待非紧急 API 调用完成时,UI 卡顿,从而阻止呈现用户界面。解决方案是使用并发模式进行可中断渲染。 ?...如果获取详细信息花费的时间太长,用户界面可能会冻结。 useTransition 方法返回两个Hook的值:startTransition 和 isPending。...": null} 使用 useTransition 钩子,React.js 继续显示没有用户详细信息的用户界面,直到用户详细信息准备好,但 UI 是响应式的。...在为每次击键并行重新渲染画布时,UI 不会停止或停止。 ? 重新渲染完成后,React 会更新 UI。

    6.3K20

    Android面试题大全

    跨进程通讯的几种方式 Android中为什么子线程不能更新UI 如果不做这个校验,是不是我也可以正常在子线程更新UI 但是google为什么要这样去设计呢 ViewRootImp是在onActivityCreated...则会抛出异常 如果不做这个校验,是不是我也可以正常在子线程更新UI // 如果不做这个校验,是不是我也可以正常在子线程更新UI?...为什么一定需要checkThread呢 // 为什么一定需要checkThread呢? 因为UI控件不是线程安全的 那为什么不加锁呢 // 那为什么不加锁呢?...一是加锁会让UI访问变得复杂; 二是加锁会降低UI访问效率,会阻塞一些线程访问UI。...(只是拿阿里打个比方,其实BAT系都差不多) 白色保活 // 白色保活 白色保活手段非常简单,就是调用系统api启动一个前台的Service进程,这样会在系统的通知栏生成一个Notification

    1.3K50

    使用CountDownTimer实现倒计时

    相信大家在项目里面不少会用到倒计时操作吧,倒计时功能在我们业务开发中使用概率非常高,例如用户操作姿势错误,我们给一个提示,提示是带有倒计时的对话框,当然你会问为什么不直接用Toast呢?...handler+Thread 正如大家所见我们在主线程中创建一个Handler,通过handler机制来更新我们的UI,这里更新UI是指我们展示给大家看的倒计时,这里我只介绍倒计时的逻辑和实现,具体应用在什么场景大家自己发挥吧...创建线程开启循环 这里的show方法大家可以不用关心,因为我这里倒计时放在对话弹框里面,属于对话框的逻辑,大家可以调用new Thread(new MyThread()).start()直接开启我们的倒计时...不过这种方式我用的是Kotlin实现的,如果第一次接触Kotlin的可能看起来不是很舒服,但是对于会Java的人来说应该不是太大问题,你也可以根据这个逻辑用java实现这个倒计时。...先拿到们系统当前时长,然后再加上我们倒计时时长,相当于再代码中对终止时间做了一个标记mStopTimeInFuture,接着看,是不是出现很熟悉的代码——sendMessage(),原来CountDownTime

    1.5K20

    (转载非原创)React 并发功能体验-前端的并发模式已经到来。

    节流限制特定函数被调用的次数。使用节流,我们可以避免重复调用昂贵和耗时的API或函数。这个过程能够提高性能,尤其是在用户界面上呈现信息。 防抖会在预定的时间内忽略对函数的调用。...函数调用仅在经过预定时间后进行。 下图描述了卡顿现象: 在等待非紧急 API 调用完成时,UI 卡顿,从而阻止呈现用户界面。解决方案是使用并发模式进行可中断渲染。...如果获取详细信息花费的时间太长,用户界面可能会冻结。 useTransition 方法返回两个Hook的值:startTransition 和 isPending。...": null} 使用 useTransition 钩子,React.js 继续显示没有用户详细信息的用户界面,直到用户详细信息准备好,但 UI 是响应式的。...在为每次击键并行重新渲染画布时,UI 不会停止或停止。 重新渲染完成后,React 会更新 UI。

    5.9K00

    你真的了解AsyncTask?

    ;直到核心线程数目到达corePoolSize(常驻线程就位) 如果线程池中线程的数目大于或者等于corePoolSize,但是工作队列workQueue没有满,那么新的任务会放在队列workQueue...在AsyncTask全部执行完毕之后,进程中还是会常驻corePoolSize个线程;在Android 4.4 (API 19)以下,这个corePoolSize是hardcode的,数值是5;API...并非在UI线程执行,而是被Handler post到创建它的那个线程执行;如果你在这两个线程更新了UI,那么直接导致崩溃。...事实上,在Android 4.1(API 16)以后,在APP主线程ActivityThread的main函数里面,直接调用了AscynTask.init函数确保这个类是在主线程初始化的;另外,init...Android 3.0以上的AsyncTask默认是串行执行任务的;如果要并行执行需要调用低版本没有的API,处理麻烦。

    46620

    怒肝 JavaScript 数据结构 — 递归篇

    大家好,我是杨成功。 前面我们学习了很多线性的数据结构,包括数组,栈,队列,链表等,当需要操作其中的元素时,大多时候是通过遍历数据结构来实现的。 接下来我们会学习更复杂的数据结构 —— 树和图。...比如前端 UI 组件库里的树形组件,就是一个典型的例子。通俗的说,递归的含义就是 自己调用自己。 在 JavaScript 当中,一个函数内部调用自身,我们就认为这是一个递归函数。...这样一层一层调用下去,直到最后一层。...看清递归的执行顺序 递归函数会不断调用自己,直到触发终止条件才会停止。有时候可能调用链比较长,导致调试困难。那有没有办法能够看清楚调用的顺序呢? 有的,下面我介绍两个方法。...最后我们思考一下:如果递归没有终止条件,会一直调用下去吗? 其实不会的,浏览器在升级中已经对这种情况做了处理。

    50020

    精读《如何抽象可视化搭建》

    如果不抽象,当搭建项目做到后期可能会出现 API 杂乱,难以维护的问题;做到一半甚至会怀疑为什么需要一个搭建框架,怀疑把框架去掉会不会效率更高;在后期发现不能自然的水平拓展到仪表盘、大屏、表单搭建场景等...提供所有业务层都需要的能力,比如性能优化的组件冻结、状态管理、对组件树增删改查的 API。...比方说,我们在组件 Mount 的实际监听了联动、实现取数、设置冻结等等效果,虽然也可以实现,但会遇到要不要抽象的问题: 如果不抽象,业务代码就会乱糟糟的,比较难读。...如果抽象,就要把联动、取数、冻结等等模块归类,封装成函数,甚至可以提供主动调用机制,UI 与逻辑解耦,但当业务层精细的去做这件事就会发现,这就是在做框架层的抽象工作,所以还不如一开始就把这些生命周期抽象到框架里...如果想要做到每一层独立正交,你会如何设计 API 呢? 版权声明:自由转载-非商用-非衍生-保持署名(创意共享 3.0 许可证)

    80030

    Web Workers 介绍

    Web Workers 是个啥 有时候,我们写的脚本需要执行一些耗时的大计算量的操作。在脚本执行过程中,浏览器会出现冻结用户界面的情况(用户对页面进行操作,但浏览器没有响应)。...为什么会出现这种情况呢?因为浏览器响应用户的操作和执行脚本是在一个进程中的,脚本在执行的过程中,就没办法响应用户的操作,so sad。 那怎么避免出现这种情况呢?...以前我的做法是,将大计算的操作分成若干个子操作,每个子操作都在 setTimeout 中。用 setTimeout 是为了让浏览器在每个子操作执行完后,会有一小段时间来响应用户的操作。...因为 Worker 是在浏览器创建的独立线程里运行的,因此,即使在 Worker 中运行再复杂的任务也不会冻结浏览器的用户界面。...DedicatedWorkerGlobalScope 中只支持很一小部分与 DOM 相关的 API。DedicatedWorkerGlobalScope 中所有的 API 见这里。

    34020
    领券