-
-
Notifications
You must be signed in to change notification settings - Fork 355
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
AltTab is slow to appear when many windows are open #171
Comments
Thank you for sharing this feedback! By the way, there is a "send feedback" menu if you click on the menubar item. It creates a form that will basically open a github issue for you. It is very handy for performance issue as it will attach a debug profile of your machine, similar to what you intuitively listed at the top of your message, but more detailed. I think you may want to just put random text and submit it, just to grab the profile from the newly made ticket and paste it here. I would then clean the new ticket so only this one here exists. Another thing to help investigate this issue would be to use Instruments on the app. It's more involved of course, but that would be way more helpful as we would have hard data to understand where time is spent on your system. On my system everything is instant for instance. You could just run the app with instruments and save the Time Profiler report file as an attachment in this ticket. Lastly, a simple context questions:
I'm trying to imagine the amount of work needed to display the thumbnails in your case. |
Meh, thanks 😄 Wouldn't occur to me that this is an github template, thx 👍 Btw, I believe it doesn't work. I was prompted with a textarea like entry and when I hit "Send", nothing happened but AltTab also disappeared from the menubar 🤷♀️
No, didn't use any external monitors at all for these tests.
With HyperSwitch I count 13, with AltTab 16. Seems that AltTab does not hide hidden/minimized application.
Not sure .. is this ? First hit of https://www.google.com/search?hl=en&q=osx%20instruments => https://en.wikipedia.org/wiki/Instruments_(software) Means I need xcode from app store for this, right? Thanks! |
@mfn thanks for finding out that the feedback form was crashing the app on submit! I released a fix for that. Could you try to submit using the new version? You can update AltTab by clicking there: You should see the new version 3.1.2 I just released. That one should let you send feedback, with the useful debug profile.
It seems you're unfamiliar with the XCode ecosystem. I think it's going to be a bit too tricky for you to investigate the issue then. If you want to invest the time and learn, I'll give you some pointers: Download and install XCode, Apple official IDE. It is (almost) the only way to work on macOS software. In a terminal, run You may need a lot of learning and OS knowledge. If you don't feel like investing time, then just update to 3.1.2 and submit the feedback form to help us see what's unique about your system that's triggering poor performance in alt-tab ;) |
I opened 25 windows on my retina screen, and indeed alt-tab pops up after a few milliseconds. I think i would be hard to shave even more time than what we are currently doing. The way HyperSwitch is faster is because they show you old thumbnails they cached. They show you incorrect information basically, then they refresh the thumbnails on a schedule every few seconds. |
Well, basically this is the answer, isn't it? 😄 I commented on this in #45 (comment) but I'm not sure what was the actual decision not to consider the caching. You immediate answer in #45 (comment)
🤷♀️ From my user perspective:
I can only tell that this works really well for me with HyperSwitch but makes it not possible for me to use AltTab sadly
Yeah totally, never did anything with it.
😢 But I figured it's this cocoapod, so Btw, is it updated the lockfile: diff --git a/Podfile.lock b/Podfile.lock
index 1e903bb..4604eb4 100644
--- a/Podfile.lock
+++ b/Podfile.lock
@@ -17,4 +17,4 @@ SPEC CHECKSUMS:
PODFILE CHECKSUM: 465451026269525f0f1d2dc7053cf0b789a35421
-COCOAPODS: 1.8.4
+COCOAPODS: 1.9.1 Tried to run this profiler, but: Also the regular Build didn't work: But given what you said, I guess for this purpose it doesn't make sense to continue down this pat anyway as you already pinpointed the difference in behaviour. Not sure were this leaves this issue. Are you open to consider the caching approach? |
You're close to being able to running it locally. You are missing one step that is running
Overall, I think if we introduce caching, then we need a proper ticket to explain details about the UX, and things like refresh frequency and other specs. Please have a look at prior discussion where I highlight issues I perceive with caching:
If we don't introduce caching, but still want better performance, then I don't know if a ticket is a good supporting material as performance is a never-ending endeavor. We can always be faster, and what is currently fast enough for someone is not for another person. I want to avoid a never-closing ticket where we track performance. I do want to improve performance as much as possible though. Not sure how to achieve that best though. We are reaching a point where we need low-level experts now that can understand interaction with the GPU and the OS. I tried my best, but I don't have 10 years of experience doing C or C++ so my best is limited. What do you think? |
Honestly? Despite all the feedback you gave regarding caching / showing wrong information: I still think it's the way to solve the problem that some (obviously not you) experience a delay they cannot "configure away" 🤷♀️ |
How about the UI? Would you communicate the fact that the thumbnails are stale to the user with some UI language? (e.g. adding a spinner somewhere on the window until all thumbnails are fresh, dimming a bit the stale thumbnails, marking them with some icon or text if they are stale, etc). Or do you think it's okay to not communicate that info? I actually think it would be pretty easy to implement caching. Today there is a function to refresh all thumbnails on shortcut press. It may be as easy as calling that function on a timer, then on shortcut press show the UI then call it once more, or even do like HyperSwitch and not even trigger a refresh on shortcut, but just wait for the timer to trigger the next refresh. To enable caching, there would be a checkbox in the preferences panel "Cache thumbnails for more responsiveness" with a slider to decide the frequency. Something between 1 and 5s maybe? I'm worried about these background refreshes using the computer resources a lot, especially the battery on unplugged laptops. I wonder if HyperSwitch has a considerable impact on battery life with its continuous background work |
It's a valid question. HyperSwitch just went ahead, implemented caching and, to me knowledge, there's no UI info about it. HyperSwitch also (again, to my knowledge) doesn't have a dedicated public forum or something, so there's hardy any info / user feedback how users of it perceive it. I guess they just a) don't care b) cope with it c) chose another tool.
Why would there need to be a frequency? Sounds more complex than just chaching. When I enable caching I will have these two expectations (based on our dialog here):
If they would be continuously (i.e. frequency) I would be too but I don't follow where this comes from. thanks! |
I thought HS used a scheduled refresh! I just tested, and it refreshes the thumbnails after a few seconds after you interact with the app. This includes invoking the UI, but also just moving the selected thumbnail left/right triggers it, which is why I assumed in the past that there was a scheduled refresh. Ok so if there is no periodic re-cache, it means that the thumbnails can get really stale. I'm fine with adding cache as a preference. Like I said I think the implementation may be trivial. Feel free to open a PR if you want this fast. The current next milestone is focusing on keyboard shortcuts issues. |
I experimented with some kind of basic caching. Here is the branch where the logic is: show the UI, then update the thumbnails and refresh the UI. I noticed some interesting things. The UI still has some ms of latency before it shows in high load situation. I simulate high load by having 63 windows open on my retina display. That's a lot of pixels to push on screen (each thumbnail is a full high dpi image, downscaled, which takes memory and cpu/gpu). Because it's slow to simply display the cached content, I wondered "is this poor implementation of our HS only shows 27 thumbnails in this scenario for some reason. 5 x 5 + 2 offscreen at the bottom. It means it's hard to compare because if I only keep 27 windows, suddently AltTab performs quickly too. Not as quickly, but almost instant too. Conclusions: caching may be the wrong target here. I think there may be a perf bottleneck with either layout. Only measuring/profiling will reveal where time is actually spent. I did a whole bunch of that already however, and it's extremely hard to find the bottleneck lots of computation is not done in our threads, but on the OS threads. Also the profiling is not showing memory recopy, gpu vs cpu rendering of NSView, layer caches, buffering, etc, which is where I think the bottleneck is. |
I used Instruments to profile while having hundreds of windows open. I see the following: All the We see all the latency is coming from The first is 112ms spent on layout: The second is internal CALayer rendering: This confirms my suspicion that it's not so much about caching the pictures as it's actually quite fast to retrieve them all (I know this because I tried to retrieve them 60 times a second in the past to have them be live/video). The issue is with layouting the view. I think the layout code is pretty poor and can greatly be enhanced. The main issue I believe is in this function. Especially the |
I pushed code in the @mfn could you please test it and tell me if you would prefer that experience to the current one? I'll attach a build here for your convenience: AltTab.app.zip This illustrates that is it possible to have no latency with fresh images being fetched, but that the issue is layout performance. There are many ways to go about optimizing layout:
Update: another option I forgot would be to use a third-party OSS library to replace |
Oh wow, the performance is like day and night! WOW, really!
That's a big 👍 |
One drawback I noticed is: every time switching to a new window, it now appears instantly but after a few ms it shuffles the recently switches windows in to their (I suppose chronological?) place, which is visible and distracting. Hard to explain 😄 |
I'm finally able to use it daily. I just never could because of this latency. I'm so grateful you did bear with my on this matter! (Now I can also give more feedback finally 😏 ) |
I worked deeper on this. It's such a complex problem. I've noticed that HyperSwitch has many limitations:
A general thing about caching:
@mfn note that the version you're using has many issues with corner cases I think. In other words, it's easy to make the app seem fast if you break functionality with some use-cases. Like I don't use the setting to pop the UI on the screen including the mouse, but we have it in AltTab, and if you use that, or have apps open while AltTab is open, or other complex use-cases, I'm sure you will start seeing problems. I think the way forward is about small optimizations to scrap off a few dozen ms, or complete rewrite to leave |
Very interesting discussion here for a similar issues where people discuss AppKit as layer on top of OpenGL/Metal and that either you tune AppKit but it's very hard cause poor documentation, or you just draw it yourself in OpenGL/Metal then you have understanding. I found especially interesting to learn that WindowServer is doing the rendering work which explains why i don't see rendering in the profiler in Instruments. Something like 20-50ms is spent on AltTab threads, yet i feel it's taking more frames that than to display e2e. I'll also look into finding ways to measure how many frames it takes to render the window in a more scientific way. I found this tool but there may be better ways like recording the display and keyboard with my iphone slow-mo camera and just counting the frames. But even then, the OS is probably generating lag on it's own so i need to compare to a baseline fast app like maybe typing a character in the terminal? Anyway lots to study here |
How does it compare with the public release in that scenario? Better, worse? I'm actually surprise to hear that because on my laptop if I bring up 200 windows AltTab is still blazing fast to show up. When checking in Instruments, I see around 1-2 frames (16-30ms) of delay to render |
I still feel some kind of lag with this build, but that might be due to system being overloaded with so many open windows anyway and not switching to the AltTab app quick enough. In other cases it feels more snappy than the current stable release. Update: also, Chrome window thumbnail in place of iTerm2 window thumbnail. |
@nfekete thank you so much for sharing this feedback! You uncovered a logical bug. I think I found the reason why you see the wrong thumbnails in the wrong places. Could you please try this new build? AltTab.app.zip
You say there are 3 "waves" of update? It should be only 1. Could you possible share a video of that in action, using the build I just shared? (Loom is a really fast way to share such video) |
Hah, didn't notice there was a lag until it was pointed out! Wow this test build (quoted one from 30 mins ago) is way snappier. Amazing! A big 'works' from me! I don't notice any lag with any thumbnails. Entire grid of my 28 windows showed immediately. |
I would say there was the initial display of the thumbnail, then followed by two waves of updates. I have tried the new build too, and I can confirm the incorrect thumbnail problem that was present in the previous build is now gone and that it's only doing one wave of (visible) update. I put visible there because there might be a second wave as before, but now that the thumbnails are correct it would not be noticeable or visible at all. I tried doing a recording with the previous build but I couldn't reproduce the double update problem again. I'm not sure why. Most of the time, AltTab appears real quick, most of the time it's perceived as close to instant. Rarely, especially if switching from one complex GUI app to another, then quickly switching back to the previous complex GUI app, there is a slight lag in appearance of the thumbnails, then a delayed update mostly for just the first two thumbnails in the grid (the two thumbnails corresponding to the two complex GUI apps I'm switching back and forth between). This is a huge improvement compared to the current release where - with this amount of open windows - most of the time I had close to one second lag initially, but I could easily trigger 3-4 second lags too, with system under load. The system I am using is a 6 core 2019 MacBook Pro w/ 3k retina + 4k UHD external display, both with fractional scaling - that means most of the time an app window is about 16 million pixels on the external display (fractional scaling @ 2560x1440 is actually 5120x2880 pixels) - I am using full-screen windows most of the time). |
The current code is supposed to work like this:
Could you share a video of the action? I would really like to see it for myself to try to understand what you're witnessing |
Here's a demo video. I recorded the video with KeyCastr running so that you can see when the keys were pressed compared to when AltTab appears on screen and the timing of the updates. Edit: if you take a look at about 30 seconds in the video, after I switch to the SCAD window and do another Sometimes I still experience some kind of lag, up to about one second. Many times it's real quick though so I'm not sure where the variation in lag comes from. Note that at this time my system is really heavily overloaded and it might be simply from just MacOS task scheduling, swapping, or some other blocking kernel level task that is preventing AltTab from running. Side note: I observed that the system in general runs much nicer with application windows minimized. I also set AltTab to only show apps that are not minimized so I can keep the number of non-minimized windows low. This way, usually everything is nice and snappy. |
This is fantastic, night and day difference for me, much more responsive. |
@nfekete I think at 30s, what we are seeing, is macOS paint cycle being a bit late. It seems to display without the changes for a few frames, then update the view later. I made a build where I force an update of the view before showing the window. Could you please tell me if the issue still happen? AltTab.app.zip Regarding the lag, yes it's most likely the computer being slow, not AltTab doing something wrong. AltTab is very dependent on its environment. The thumbnails are coming from the WindowServer. If it's too busy, it will block AltTab while it's getting the info ready. |
I can still see a delayed update that is related to a change in the MRU list in the first few thumbnails. See a recording about it. At about 3 seconds, I switch from the Chrome window to an empty Safari Window, skipping over the iTerm2 window. Then, immediately triggering AltTab again (at 9 seconds), I am presented with a thumbnail order of Chrome, iTerm2, Safari, while in fact, the current app is Safari, the and the MRU apps would be Chrome, iTerm2 in that order. So the displayed thumbnails should be of Safari, Chrome, iTerm2 instead. At 10 seconds, the thumbnails are refreshed, now with the correct order.
True, with this many windows open, WindowServer is using ever more CPU cycles. The more open windows you have, the more CPU it's using, and this happens independent of AltTab, even if I don't use AltTab at all. I found that minimizing windows have a huge impact on this aspect. Otherwise I have to say I am really satisfied with this performance improvement on AltTab's behalf. I think the WindowServer performance problem can not be avoided with so many open, but not minimized windows, so I'm not sure how much more could be improved on AltTab side. Minimizing them works wonderfully though. |
Could you please try this another build? I tried a more aggressive forcing of the update before the window is displayed AltTab.app.zip
Yes, during my tests, I had like 40 Chrome windows open with a big animated gif on each. That way I could see the thumbnails being updated in details as each would update and show a different visual on each alt-tab summon. However, I thought I was going crazy because I was seeing lots of them not updating in AltTab, when I was sure the code was correct. I think some apps like Chrome notice if their windows are not visible (obstructed by other windows, or minimized), and stop rendering, which reduces the burden on the WindowServer, and the system in general. |
BREAKING CHANGE: the window thumbnails are now updated *after* the UI is shown. AltTab will first display its window, with the first 3 thumbnails up-to-date, then asynchronously update the rest of the thumbnails one-by-one. This improves the experience of users with lots of windows open.
It still happens sometimes, but I would say it's really difficult to trigger it in the sense that I have to really push the system hard to happen. See a short video here. Analyzing the video, considering what I did, this is what happens here:
Based on the above sequence seems that the behavior of AltTab is correct and the grid refresh is only because of the real underlying sequence of these events. |
Oh I see. Basically AltTab starts rendering, and right after the window focus changes, so AltTab refreshes. This looks normal indeed. In your previous videos, it was different though. You were doing slow actions like slowly pressing Would you say that that second kind of issue is gone with the latest build I shared? |
I am unsure even about the previous behavior, wether we've seen something else or the same thing as this last time. But based on the testing I did last time, this is as much as I could trigger. Overall it feels really nice and snappy, I am very satisfied with it. |
# [6.0.0](v5.3.0...v6.0.0) (2020-08-27) ### Bug Fixes * alt-tab own windows were not shown in alt-tab (closes [#555](#555)) ([8bcbc04](8bcbc04)) * clicking the main window would steal focus ([de02e5b](de02e5b)) * display firefox develop edition fullscreen windows (closes [#558](#558)) ([3250d37](3250d37)) * guarantee alt-tab window is always up-to-date on display ([be4c5f1](be4c5f1)) * ignore zombie processes ([50c8c82](50c8c82)) * moving some of the preferences sliders was very laggy ([a552c4c](a552c4c)) * shortcuts stop working if active app is quit (closes [#557](#557)) ([023561d](023561d)) ### Features * display quickly even with many open windows (closes [#171](#171)) ([da16a0b](da16a0b)) * improve the 3 colored buttons when hovering (closes [#516](#516)) ([3ddedff](3ddedff)) * update chinese localization ([e150a9a](e150a9a)) ### Performance Improvements * alt-tab appears quicker when summoned ([c2bb896](c2bb896)) * main window appears (a few frames) faster on trigger ([2bc09e6](2bc09e6)) ### BREAKING CHANGES * the window thumbnails are now updated *after* the UI is shown. AltTab will first display its window, with the first 3 thumbnails up-to-date, then asynchronously update the rest of the thumbnails one-by-one. This improves the experience of users with lots of windows open.
Holy COW, this is SOOO much faster! Amazing work, thank-you for taking care of this so fast! Bummed I missed out on the fun prior to release (it's been one of those weeks), but was pleasantly surprised today when I updated. |
@lwouis |
@jaekyeom in the current release, and for a few releases now, the logic is to drop UI operations such as refreshing thumbnails, when the user releases the shortcut quickly. If you alt-tab really fast, the app will not refresh thumbnails. The experience should be smooth. Is it not for you? |
@lwouis Actually there were some cases that the AltTab window stays open when I alt-tab quickly, but now I get what the "Apparition delay" is for. After adding a small "Apparition delay", it feels very smooth on quick alt-tabs. Thank you! ADD: |
@jaekyeom yes, AltTab has gotten so fast at this point that on most machines I expect the UI to show within only a few frames (less than 50ms) of you pressing the shortcut. Thus if you release it "fast", you are physically still slower than those 50ms, so the app has no chance to recognize it and cancel showing the UI. This result in a visual flicker of the UI. This is a limitation of the user's finger speed. The workaround is to allow user to have a window of time, a delay before showing the UI. This is what you have set in the preferences. This way AltTab refrains from showing until that time window is over, then it shows. This lets you release quickly and not see the UI at all |
@lwouis Thanks for the answer. To clarify, what I ADDed in my last comment was that the behavior is different for my Shortcut 1 (for "All apps") and Shortcut 2 (for "Active app"). My current setting of the "Apparition delay" is 199ms. If I press Shortcut 1 quickly, then switching happens without the UI showing up. However, when I press Shortcut 2 quickly, windows don't switch instantly and the UI always shows up after the delay. |
Oh thank you for sharing this other bug! Indeed I was able to reproduce it on v6.6.0. Good news is that the issue is gone in my local build. I'm waiting for people in #556 to give me more feedback to release that version. When that happens, that bug will be fixed for you. Could you please test the build I shared there to help testing it before release? My current worry is that some people say that shortcut with the |
@lwouis Sorry for the huge delay on my side. In fact, I had downloaded the test build and have been using/testing it. I was going to write a reply at some point, but instead I got totally engaged with some work and thus too busy ;) This test build indeed solves the original problem I was having! |
This issue is still happening when computing previews |
Using Version 3.1.0 on 10.15.3 (19D76) using a MacBook Pro (15-inch, 2018) 2,9 GHz 6-Core Intel Core i9.
On my endeavor to mimic the HyperSwitch behavior, I set the "Apparition delay" to 0.
Yet it has a noticeable delay before showing me the grid of application. Not just the first time, all the time.
I've HyperSwitch running next to it and, comparatively, it comes up instantly.
In my super-scientific-not-really benchmarking, I would say the delay is about 250-300ms.
How did I came to this number? Apparently, HyperSwitch also has a way to change the delay, it's called "Delay activation for" I've set it to 0. I increased it gradually until I felt the delay matched that of AltTab 🤷♀️
I've searched existing issues:
Thanks
Debug profile:
The text was updated successfully, but these errors were encountered: