I have an AJAX heavy website. There's hundreds of buttons that momentarily put up an animated loading GIF when the server is processing a request.
I noticed that my site is sluggish after using it for several minutes. The animated GIFs play at lower framerate. They sometimes even stop animating. Hover effects on buttons have a noticeable lag. Is it possible that these hundred animated GIFs are still locking up the CPU even while they're hidden (style="display: none")? At most, only a few GIFs are visible at any point in time.
Things that are hidden using style-sheets still exist in, and are resolved by the browser (and can therefore be manipulated by script), they are just not displayed to the user.
This is in contrast to when controls are marked as .visible=false in which case they are not marked up in the browser (and therefore cannot by manipulated by script)
Related
I have two pages, first page I have a ScrollView control and the other page I used RepeatBox control.
My problem is the ScrollView page scroll is smooth, But the RepeatBox page scrolling is not smooth (i.e. flickering while scrolling).
Could any one help on this? Thanks in advance.
Performance of repeatbox can change according to the objects you used in it. Because it is drawn with rowRender event, it can take more time with different objects. Also, in some old devices, especially for Android, you can see these kind of performance differences in applications.
Maybe you can test with other devices, or you can test with more simple project in order to see if it is always flickering or not.
The problem comes with all images on the visible screen are opening again from the local storage by rowRender method. In the native RepeatBox after image comes on visible area are stored and not again opening from local storage and creates performance problem.
I'm looking for help with a performance issue in an Objective-C based iOS app.
I have an iOS application that captures the screen's contents using CALayer's renderInContext method. It attempts to capture enough screen frames to create a video using AVFoundation. The screen recording is then combined with other elements for research purposes on usability. While the screen is being captured, the app may also be displaying the contents of a UIWebView, going out over the network to fetch data, etc... The content of the Web view is not under my control - it is arbitrary content from the Web.
This setup is working but as you might imagine, it's not buttery smooth. Since the layer must be rendered on the main thread, there's more UI contention than I'd like. What I'd like to do is to have a setup where the responsiveness of the UI is prioritized over the screen capture. For instance, if the user is scrolling the Web view, I'd rather drop frames on the recording than have a terrible scrolling experience.
I've experimented with several techniques, from dispatch_source coalescing to submitting the frame capture requests as blocks to the main queue to CADisplayLink. So far they all seem to perform about the same. The frame capture is currently being triggered in the drawRect of the screen's main view.
What I'm asking here is: given the above, what techniques would you suggest I try to achieve my goals? I realize the answer may be that there is no great answer... but I'd like to try anything, however wacky it might sound.
NOTE: Whatever techniques need to be App Store friendly. Can't use something like the CoreSurface hack that Display Recorder used/uses.
Thanks for your help!
"Since the layer must be rendered on the main thread" this is not true, as long as you don't touch UIKit.
Please see https://stackoverflow.com/a/12844171/136305
Maybe you can record at half resolution to speed up things, if that fits the requirements?
I tried to implement the lazy loading solution for UIScrollView with paging enabled, as in the PageControl example from Apple. It seems to work fine, the only problem is that as the user scrolls past the 50% of the page, there is this short hitch as the content of the next page is loaded (obviously because loading the next ViewController takes some time and it seems to happen on the main thread).
Is there some way to make the scrolling seem more smooth that would work no matter how fast the user scrolls ?
You need to make sure that anything which takes time happens asynchronously. The techniques for this will vary based on what kind of content you're loading or what sort of drawing you're doing that causes the delays. Try to load images in the background, do custom drawing in the background, use operations or gcd to break up large tasks into smaller chunks that can happen concurrently, etc.
You should be lazy loading the surrounding pages so that they're already loaded when the user scrolls.
So if the user scrolls to page 2, load pages 1 and 3 (if they aren't already)
I've got an app I'm working on where we handle a LOT of images at once in a scrollview. (Here's how it looks, each blue block being in image on a scrollview expanding to the right: http://i.stack.imgur.com/o7lFx.png) So to be able to handle the large strain doing this puts on memory. So I've implemented a bunch of techniques such as reusing imageviews etc which have all worked quite successfully in keeping my memory usage down. Another thing I do is instead of keeping the actual image in memory (which I of course couldn't do for all of them because that would run out of memory very quickly) I only keep the image's filepath in memory and then read the image when the user scrolls to an area of the scroll view near that image. However, although this is memory efficient, it's causing a LOT of lag in the scrollview because of the fact that it has to constantly read images from the disk. I can't think of a good solution on how to fix this. Basically right now the app draws to the screen only the visible uiimageviews and while the user scrolls the app will look to see if it can dequeue another imageview so it doesn't have to allocate another one and at that point it reads the image into memory, but as I said it's causing the scrolling action to be very slow. Any ideas on a strategy to use to fix this? Does anyone know what the native photos app does to handle this kind of thing? Thanks so much!
I can suggest you a simple solution to balance both the memory and the computer processing. You only keep small images like thumbnails in memory and only keep about 20 of them. One project that I am doing, I keep 20 thumbnail images (100 x 100) recently accessed, which doesn't cost a lot of memory. I believe that it costs about 200 kb all the time but comparing to a general available memory. I think it is good enough.
It also depends on your use case : if user scroll really fast and you don't know when will they go. You can have even smaller images than the thumnail and when you show it on the UIImageView, you resize it to fit. When user stops scrolling for a while. You can start loading bigger images and then you have a nicer images. User may not even notice about the process
I don't think there is a solution that can be fast and using as less memory as possible. Because we have memory, maybe not big but have enough if we use it smartly.
Slow scrolling performance might mean that you're blocking the main thread while loading images. In that case, the scrolling animation won't continue until the images are loaded, which would indeed cause pretty choppy scrolling performance.
It would be better to lazily load requested images in the background, while the main thread continues to handle the scrolling animation. A library that provides this functionality (among other things) is the 'three20' library. See the Tidbits document, and scroll down to the bottom where the 'TTImageView' class is described.
I had a similar issue with a PDF viewer, The recommended way to do this is to have as low a res image as you can get away with and if you are allowing the user to blow the image up/zoom, then have two versions or three versions of that image increasing the res as you go.
Put as much code as you can get away with in the didDecelerate method (like loading in higher res images like vodkhang talks about), rather than processing loads in didScroll. Recycle Views out of scope as you have said. and beware of autoreleased Context based Image Creation functions.
Load images in on background threads intelligently (based on the scrollView Offset position and zoom level), and think about using CALayer/Tiled Layer drawing for larger images.
Three20 (an open source iOs lib) has a great Photo Viewer that can be subclassed, it has thumbnail navigation, large image paging, caching and gestures right out of the box.
I want to fetch images into my application cache in a faster way.
I do a map kinda app by loading at about 25 images at a time in a UIscrollView in which each image takes about 1 second for downloading.
All images are of size 64KB and 256*256 dimensions. I am doing caching, So after the first time when i scroll there will be around 7-8 images to load and that too takes each second each. So in the middle of scrolling the map it stops for around 7-8 seconds.
Is there a way that I can increase the speed of getting images, so that I will be able to load atleast 4-6 images a second?
You should use CATiledLayer, which spins off a separate thread for rendering each tile. It's how the Maps app does its drawing. You can have it download the images within the drawing code, and it won't block the main thread, so scrolling will be smooth. It'll still take time to download the images, but if you have a low-resolution proxy image you can show that while it loads the real image.
You need to free the main thread and do this on a background thread. When you're doing heavy work on the main thread, it will block and you app will appear unresponsive. (If you don't know on what thread you're running, your are probably on the main thread.)
Take a look at the apple concurrency guide.
Your web browser does this by spinning up a number of background fetch threads in parallel (reducing the overall download time) and displaying the map tiles as they come in (giving the illusion of higher responsiveness).
You can get a better feel for this by installing Firebug on Firefox, and then activate it while loading a complex page. It'll show you a graph over time of how long it takes each page component to be fetched, and this shows the parallelism.