Re: ItemRenderer Render Order
HaHaha!!! Thanks for the suggestions Javier, your input has been invaluable. I am not the most elegant of coders, so I tend to like neanderthal approaches ;) Homo sapiens may be a little too enlightened for me. I saw all of the information about the priority groups that you mention with the content cache, but I couldn't make heads or tails of it. The explanations are so sparse as to not mean much to me. I need a good example or tutorial to understand these concepts, and I haven't been able to find much on the internet regarding these specialized methods, just very basic contentCache examples. But your suggestion is currently working great for me, so thanks for taking the time to post!! -- Sent from: http://apache-flex-users.246.n4.nabble.com/
Re: ItemRenderer Render Order
Nice going! Erik On Oct 12, 2017, at 4:12 PM, bilbosaxwrote: I initially tried Erik's solution to use a contentCache with queueing enabled, and set maxActiveRequests to 3, but I still got the same results - one of the first three images was always the last to render. So I finally took a more neanderthal approach and have two url ArrayCollections. The first just has the first three image url's, and the second has the the entire list of url's. I set the dataprovider for the list to to the first ArrayCollection, and when updateComplete fires, I set the dataprovider to the second ArrayCollection. The whole time I use a contentCache, so all the the images are available to my application for other uses. So now the first three images load quickly, and by the time I start scrolling, all of the other images are ready to go. Thanks for the suggestions guys!! -- Sent from: http://apache-flex-users.246.n4.nabble.com/
Re: ItemRenderer Render Order
I initially tried Erik's solution to use a contentCache with queueing enabled, and set maxActiveRequests to 3, but I still got the same results - one of the first three images was always the last to render. So I finally took a more neanderthal approach and have two url ArrayCollections. The first just has the first three image url's, and the second has the the entire list of url's. I set the dataprovider for the list to to the first ArrayCollection, and when updateComplete fires, I set the dataprovider to the second ArrayCollection. The whole time I use a contentCache, so all the the images are available to my application for other uses. So now the first three images load quickly, and by the time I start scrolling, all of the other images are ready to go. Thanks for the suggestions guys!! -- Sent from: http://apache-flex-users.246.n4.nabble.com/
Re: ItemRenderer Render Order
Thanks for the ideas Javier, they are all excellent! I will try some of them out this afternoon and post my results! -- Sent from: http://apache-flex-users.246.n4.nabble.com/
Re: ItemRenderer Render Order
Another few options: 1. Set the dataprovider to only the first 3 entries 2. Wait for complete rendering 3. Set the dataprovider to the whole list of entries and caching will do its job Or just set items 4-99 to not visible, and then turn them back on when items 1-3 finish loading. (you could even bind itemRender visibility it to a "numLoaded" variable like visibility="{numLoaded>=3}", and update numLoaded++ on your item renderers loaded event each time and image gets loaded} Or use a contentCache with queueing enabled, and set maxActiveRequests to 3 (Erik solution). Note that caching itself is pretty useless (or at least doubtfull) in your scenario and will just consume memory, so maybe you also want to adjust contentCache cache size to 0 or 1. Or check and fiddle with the numElements property of the dataGroup (maybe that's what you were looking for, not sure) https://flex.apache.org/asdoc/spark/components/DataGroup.html#propertySummary Or make the httpService return 2 lists (only first three, and the rest) and switch dataProvider between them once rendering of the first list is complete Or use two lists (3-first as "shown" and full list as "hidden"), and switch visibility once the first one finishes rendering Etc... etc... etc... On Thu, Oct 12, 2017 at 8:13 AM, Alex Haruiwrote: > There are probably other options as well. You could overlay the list with > a single image and have the server concatenate the images into a single > long image and send that up. Then under the covers, you bring the > individual images into the cache and display them in item renderers. It > is more work, but "magic" uses illusions like that. > > I'm not sure why some intermediate numbers of renderers would work better > than the two choices "virtual = as many as are visible" or "non-virtual = > as many as are in the data provider". I don't recall any particular code > that would let you control that, but I didn't go look either. I keep > urging you to get good data when dealing with asynchronous data problems > instead of guessing because if you guess wrong and it starts to work on > one computer it might not work on some other computer. > > HTH, > -Alex > > On 10/11/17, 6:54 PM, "bilbosax" wrote: > > >Thanks for the replies Erik and Alex. When I get back to my computer > >tomorrow, I will give your suggestions a try and see how it works out. > >This > >is a realestate app where property images are displayed when a property is > >clicked on, so caching beforehand really isn't an option. But I am > >interested in trying the datagroup. What about my second second question, > >do > >you know if it is possible to force a certain number of itemrenderers. > >Right > >now, it looks like it is using 3 itemrenderers, but I feel like 6 or 7 > >would > >be a happy medium for my situation, but I don't know if this is possible > >either? > > > >Looking forward to trying datagroup. > > > > > > > >-- > >Sent from: > >https://na01.safelinks.protection.outlook.com/?url= > http%3A%2F%2Fapache-fle > >x-users.246.n4.nabble.com%2F=02%7C01%7C% > 7C611d2f3321d64995e0be08d > >51114310c%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0% > 7C636433700791157091& > >sdata=bPjPls6Hn9GV1GQJEvbnGUj5dOyaxe4%2FVGF9WMIKo%2BA%3D=0 > >
Re: ItemRenderer Render Order
There are probably other options as well. You could overlay the list with a single image and have the server concatenate the images into a single long image and send that up. Then under the covers, you bring the individual images into the cache and display them in item renderers. It is more work, but "magic" uses illusions like that. I'm not sure why some intermediate numbers of renderers would work better than the two choices "virtual = as many as are visible" or "non-virtual = as many as are in the data provider". I don't recall any particular code that would let you control that, but I didn't go look either. I keep urging you to get good data when dealing with asynchronous data problems instead of guessing because if you guess wrong and it starts to work on one computer it might not work on some other computer. HTH, -Alex On 10/11/17, 6:54 PM, "bilbosax"wrote: >Thanks for the replies Erik and Alex. When I get back to my computer >tomorrow, I will give your suggestions a try and see how it works out. >This >is a realestate app where property images are displayed when a property is >clicked on, so caching beforehand really isn't an option. But I am >interested in trying the datagroup. What about my second second question, >do >you know if it is possible to force a certain number of itemrenderers. >Right >now, it looks like it is using 3 itemrenderers, but I feel like 6 or 7 >would >be a happy medium for my situation, but I don't know if this is possible >either? > >Looking forward to trying datagroup. > > > >-- >Sent from: >https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fapache-fle >x-users.246.n4.nabble.com%2F=02%7C01%7C%7C611d2f3321d64995e0be08d >51114310c%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636433700791157091& >sdata=bPjPls6Hn9GV1GQJEvbnGUj5dOyaxe4%2FVGF9WMIKo%2BA%3D=0
Re: ItemRenderer Render Order
Thanks for the replies Erik and Alex. When I get back to my computer tomorrow, I will give your suggestions a try and see how it works out. This is a realestate app where property images are displayed when a property is clicked on, so caching beforehand really isn't an option. But I am interested in trying the datagroup. What about my second second question, do you know if it is possible to force a certain number of itemrenderers. Right now, it looks like it is using 3 itemrenderers, but I feel like 6 or 7 would be a happy medium for my situation, but I don't know if this is possible either? Looking forward to trying datagroup. -- Sent from: http://apache-flex-users.246.n4.nabble.com/
Re: ItemRenderer Render Order
Here's another idea. It's logical to assume if using non-virtual List, that when the dataProvider is assigned to an ArrayCollection that the collection order (natural, or ordered if you set a Sort in an extended collection) is also the order the ItemRenderers will indeed start rendering in the order of the collection because the view needs to add each UI element to the UI container in the visual order. I see no logical reason why Flex creators would create the elements in an order other than visual order since that's all a List does is add elements to a parent container ordered the same as the underlying dataProvider. It's the asynchronous GET calls that makes it appear there is some order in which they are called as they render in parallel. So here's my idea. Use a ContentCache and set maxActiveRequests to the number of images that will be visible for the given device or screen. If the ItemRenderers are being rendered in the underlying collection order (I bet they are) it will not ask for more images until the first GET completes so your first visible items will always render first and you'll limit the number of parallel GET calls to minimize bandwidth used at once. This might help. Erik On Oct 11, 2017, at 11:12 AM, Erik J. Thomaswrote: Despite the fact that a non-virtual List or DataGroup will attempt to render all ItemRenderer instances by iterating the dataProvider in some sequential order, the speed at which the images appear is only influenced very little by the order the instances are rendered. This is because as each renderer is laying out, the moment the Image.source is set to a URL, it's Loader will make an asynchronous HTTP GET request for the image bytes. The UI thread does not wait on the image to show up to complete laying out the renderer. Essentially the time it takes for each renderer to layout while the images are waiting on async responses happens so quickly, the speed at which the images appear will seem almost random based on the asynchronous nature of the HTTP GET calls. It's highly likely that all the Image.loader GET calls will have fired before the first image's response is received. The size of the response payload (size of the image byte array) will influence to how quickly a given HTTP response is received as well. But practically speaking, all image requests are happening very nearly in parallel for the entire list, meaning you are slowing down how fast images will appear because your internet bandwidth is being utilized for all images at once. If you use List with virtualization set to true, the number of image loader requests will be reduced to the visible renderers in the viewport (plus some number of buffered renderers for better scrolling performance). So the initial display of the visible images will be faster with virtualized List since you're not receiving so may image byte arrays at the same time. If you were able to force the order of the requests, it should make very little difference in how fast the images render because all HTTP requests are happening in parallel. Your only solution is to preload a ContentCache with images before displaying your list using your own Loader, OR, don't load offscreen images until your onscreen images have loaded. You can't do this with data binding using a List and dataProvider, except to set the List to use virtualized item renderers. Again, List performance optimization was a high priority for Adobe (and Apache) developers and I doubt you are going to improve this much if at all. Another idea is to use DataGroup or non-virtual List and set the dataProvider before the user views the list (includeInLayout true, but visible false) so it is collecting and caching all the image bytes in the background before your view is visible, then when the user navigates to the view with the list, all images will already have been loaded (HTTP Get requests for all images have completed) and then they simply have to render. Erik On Oct 11, 2017, at 9:17 AM, Alex Harui wrote: I don't know enough about the layers of the internet to answer your question, but a network monitor can help show why things are happening the way you describe them, and then you will have more data to use to form a solution/workaround. Right now, all we have is speculation. Think of it this way: if you create an HTML page with 20 tags, will the images pop in in the same order every time (assuming you've flushed the browser cache beforehand)? I don't know the answer, maybe someone else does. And the server might be serving those images in an unexpected order and maybe there is a way to correct that. Pre-loading the images as someone else suggested should help. You could also try to coordinate between renderers and only have one renderer make an image request and queue the others until the first one comes back. HTH, -Alex On 10/11/17, 6:39 AM, "bilbosax"
Re: ItemRenderer Render Order
Despite the fact that a non-virtual List or DataGroup will attempt to render all ItemRenderer instances by iterating the dataProvider in some sequential order, the speed at which the images appear is only influenced very little by the order the instances are rendered. This is because as each renderer is laying out, the moment the Image.source is set to a URL, it's Loader will make an asynchronous HTTP GET request for the image bytes. The UI thread does not wait on the image to show up to complete laying out the renderer. Essentially the time it takes for each renderer to layout while the images are waiting on async responses happens so quickly, the speed at which the images appear will seem almost random based on the asynchronous nature of the HTTP GET calls. It's highly likely that all the Image.loader GET calls will have fired before the first image's response is received. The size of the response payload (size of the image byte array) will influence to how quickly a given HTTP response is received as well. But practically speaking, all image requests are happening very nearly in parallel for the entire list, meaning you are slowing down how fast images will appear because your internet bandwidth is being utilized for all images at once. If you use List with virtualization set to true, the number of image loader requests will be reduced to the visible renderers in the viewport (plus some number of buffered renderers for better scrolling performance). So the initial display of the visible images will be faster with virtualized List since you're not receiving so may image byte arrays at the same time. If you were able to force the order of the requests, it should make very little difference in how fast the images render because all HTTP requests are happening in parallel. Your only solution is to preload a ContentCache with images before displaying your list using your own Loader, OR, don't load offscreen images until your onscreen images have loaded. You can't do this with data binding using a List and dataProvider, except to set the List to use virtualized item renderers. Again, List performance optimization was a high priority for Adobe (and Apache) developers and I doubt you are going to improve this much if at all. Another idea is to use DataGroup or non-virtual List and set the dataProvider before the user views the list (includeInLayout true, but visible false) so it is collecting and caching all the image bytes in the background before your view is visible, then when the user navigates to the view with the list, all images will already have been loaded (HTTP Get requests for all images have completed) and then they simply have to render. Erik On Oct 11, 2017, at 9:17 AM, Alex Haruiwrote: I don't know enough about the layers of the internet to answer your question, but a network monitor can help show why things are happening the way you describe them, and then you will have more data to use to form a solution/workaround. Right now, all we have is speculation. Think of it this way: if you create an HTML page with 20 tags, will the images pop in in the same order every time (assuming you've flushed the browser cache beforehand)? I don't know the answer, maybe someone else does. And the server might be serving those images in an unexpected order and maybe there is a way to correct that. Pre-loading the images as someone else suggested should help. You could also try to coordinate between renderers and only have one renderer make an image request and queue the others until the first one comes back. HTH, -Alex On 10/11/17, 6:39 AM, "bilbosax" wrote: > I hear your logic, but I'm not sure that I follow. I make a database > request > that downloads a bunch of url strings to an array collection that are in > the > order that I want them displayed and the priority that I want them > rendered. > After the arraycollection is populated, a component is instantiated > containing the list and the array collection is set as the data provider > and > the images begin to render. The problem is that it seems that the first > three images that are initially on the screen are the LAST to be loading. > If > the data provider is being set all at once, you are telling me there is no > way to force the render order from 1 to 24 instead of 24 to 1? > > It sounds like you are saying whoever gets their data first will render > first, but if I just hand off the data provider, I can't control who will > have their photo delivered first so it will always be random. Is that > right? > > > > -- > Sent from: > https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fapache-fle > x-users.246.n4.nabble.com%2F=02%7C01%7C%7Cd0797f4884ac4a5f1fef08d > 510ad7591%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636433259549007197& > sdata=THUXvhnsmFF%2F3FpxTl%2B6eHIPry%2Fjaij96M2VdfoDDx4%3D=0
Re: ItemRenderer Render Order
I don't know enough about the layers of the internet to answer your question, but a network monitor can help show why things are happening the way you describe them, and then you will have more data to use to form a solution/workaround. Right now, all we have is speculation. Think of it this way: if you create an HTML page with 20 tags, will the images pop in in the same order every time (assuming you've flushed the browser cache beforehand)? I don't know the answer, maybe someone else does. And the server might be serving those images in an unexpected order and maybe there is a way to correct that. Pre-loading the images as someone else suggested should help. You could also try to coordinate between renderers and only have one renderer make an image request and queue the others until the first one comes back. HTH, -Alex On 10/11/17, 6:39 AM, "bilbosax"wrote: >I hear your logic, but I'm not sure that I follow. I make a database >request >that downloads a bunch of url strings to an array collection that are in >the >order that I want them displayed and the priority that I want them >rendered. >After the arraycollection is populated, a component is instantiated >containing the list and the array collection is set as the data provider >and >the images begin to render. The problem is that it seems that the first >three images that are initially on the screen are the LAST to be loading. >If >the data provider is being set all at once, you are telling me there is no >way to force the render order from 1 to 24 instead of 24 to 1? > >It sounds like you are saying whoever gets their data first will render >first, but if I just hand off the data provider, I can't control who will >have their photo delivered first so it will always be random. Is that >right? > > > >-- >Sent from: >https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fapache-fle >x-users.246.n4.nabble.com%2F=02%7C01%7C%7Cd0797f4884ac4a5f1fef08d >510ad7591%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636433259549007197& >sdata=THUXvhnsmFF%2F3FpxTl%2B6eHIPry%2Fjaij96M2VdfoDDx4%3D=0
Re: ItemRenderer Render Order
Hey Bilbosax, I don't see how that setting will help. For best look and feel, I suggest you let the ItemRenderer do it's job which will render the visible ones first but use ContentCache so that the images are loaded only once, so scrolling will be pretty good. That said, you might consider caching the first page of images on app startup, whenever you populate your ArrayCollection, assuming it's sometime before it is rendered, adding them to your ContentCache so the list will render fast when the view does become visible. But the idea would be to use a Loader and set the ContentCache member and explicitly load the first n images without displaying them. Set your renderer's image loader to the same ContentCache and when it first tries to render, it will find the image already in the cache and simply render it without making the Loader request. This only works if you have time to preload the cache with the items you want to display first before displaying them to the user. If this isn't your scenario then I suggest living with the delay and just using virtualization. Adobe developers put a lot of time into optimizing list rendering in Flash/Flex, and unless you want to deep dive and recreate a lot of code, I doubt you'll find a simply solution. I'm an ACE from back in the Adobe Flex days and don't recall anything like you are asking about being supported out of the box. However, another idea might be using a DataGroup which doesn't reuse renderers, perhaps it will render the first visible images before the rest. I have never tried that. But when you set a List to not reuse renderers you are essentially making it a DataGroup anyway. But perhaps DataGroup handles this scenario better? May be worth a try. Here's how you can horizontally scroll a DataGroup with ItemRenderer that won't recycle the renderers. I'd be interested to know if this works better since I use a lot of lists with images in my various mobile apps and performance is ALWAYS a concern. Erik On Oct 11, 2017, at 6:39 AM, bilbosaxwrote: I hear your logic, but I'm not sure that I follow. I make a database request that downloads a bunch of url strings to an array collection that are in the order that I want them displayed and the priority that I want them rendered. After the arraycollection is populated, a component is instantiated containing the list and the array collection is set as the data provider and the images begin to render. The problem is that it seems that the first three images that are initially on the screen are the LAST to be loading. If the data provider is being set all at once, you are telling me there is no way to force the render order from 1 to 24 instead of 24 to 1? It sounds like you are saying whoever gets their data first will render first, but if I just hand off the data provider, I can't control who will have their photo delivered first so it will always be random. Is that right? -- Sent from: http://apache-flex-users.246.n4.nabble.com/
Re: ItemRenderer Render Order
Well, the player uses deferred rendering, so if you send 20 requests for images and only 10 come back in the next frame interval, those 10 will be rendered all at once and you won't know which of those 10 came back first. Flex item renderers, like all Flex components, use invalidation/validation, so they each put themselves in a list to have the code runs that requests the image through the player. There could be some issue in the code or in the player where the requests go out in the opposite order, or there could be something about the browser, network and/or server where the images come back in a different order. A network monitor might provide clues. HTH, -Alex On 10/10/17, 7:07 PM, "bilbosax"wrote: >I am writing a mobile app and there is a horizontal list at the bottom of >the >app that the user can horizontally scroll through a row of photos. I >have a >custom itemrenderer in the list to just upload and display photos based >on a >url value. There will never be more than 24 photos, so I thought that it >wouldn't hurt too badly to set useVirtualLayout to false so that all the >photos would get rendered at once and the user wouldn't have to wait on >images loading while they scrolled. The problem is that the List is >rendering the itemrenderers off screen first, and the first three that a >user can see are rendering last. I have two itemrenderer questions: > >1. Can you force the order that itemrenderers render? For instance, can >you >set useVirtualLayout to false, and then tell AIR to render the >itemRenderers >starting at 1 and ending at 24? > >2. I know that you can turn virtualization on or off so that itemrenderers >are recycled, or one is created for every object. But can I force the >list >to create and recycle say 10 itemrenders? Can I force the number of >itemrenderers I want created?? > >Thanks!! > > > >-- >Sent from: >https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fapache-fle >x-users.246.n4.nabble.com%2F=02%7C01%7C%7Cd75121ae405f4915e52a08d >5104cd43f%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636432844520750048& >sdata=sKJYgf456kDLpHEdtMvthqCc%2FAP3DY6bVmNpsOGRaE0%3D=0