{ "id": "131622", "key": "AC-1572", "fields": { "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false }, "project": { "id": "12217", "key": "AC", "name": "Appcelerator - INBOX", "projectCategory": { "id": "10000", "description": "", "name": "Customer Service" } }, "resolution": { "id": "3", "description": "The problem is a duplicate of an existing issue.", "name": "Duplicate" }, "resolutiondate": "2014-06-16T20:59:15.000+0000", "created": "2014-06-11T23:09:38.000+0000", "labels": [ "cacheSize", "ios", "scrollableview" ], "versions": [], "issuelinks": [ { "id": "38336", "type": { "id": "10003", "name": "Relates", "inward": "relates to", "outward": "relates to" }, "outwardIssue": { "id": "131637", "key": "TIMOB-17147", "fields": { "summary": "IOS: ScrollableView: cacheSize property does not work when the view has a child view component", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "priority": { "name": "Low", "id": "4" }, "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false } } } } ], "assignee": { "name": "sliang", "key": "sliang", "displayName": "Shuo Liang", "active": true, "timeZone": "Asia/Harbin" }, "updated": "2016-03-08T07:38:02.000+0000", "status": { "description": "A resolution has been taken, and it is awaiting verification by reporter. From here issues are either reopened, or are closed.", "name": "Resolved", "id": "5", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "components": [ { "id": "14548", "name": "Titanium SDK & CLI", "description": "Please enter tickets related to the MobileSDK here." } ], "description": "The \"[cacheSize|http://docs.appcelerator.com/titanium/latest/#!/api/Titanium.UI.ScrollableView-property-cacheSize]\" property of the ScrollableView allows the developer to define how many \"pages\" are to be pre-rendered when the ScrollableView is loaded. As the user scrolls, additional pages are pre-redendered as needed. This is useful for complex scrollable views with many items as it increases performance and reduces memory use.\r\n\r\nProblem: \r\n\r\nIf the pages (views) contains child views, the cacheSize property does not work and all pages are pre-rendered at once. When loading hundreds of complex pages, this results on the ScrollableView becoming very slow as it is not taking advantage of the cache logic.\r\n\r\nTest case:\r\n\r\nThe code below shows this problem. You can set the TEST_CASE variable between 1 and 4 to test the four different cases. \r\n\r\nThe first two cases load only a single view control (a view, and an imageview). These two cases work, and as can be seen from the console log, only 3 pages are pre-rendered initially, and as you scroll additional pages are pre-rendered as needed. Remote images are loaded as needed as well.\r\n\r\nThe last two cases load views with children (3 = a view with a child imageview, and 4 = a view with a child view). As can be seen from the console, these two cases fail, as cacheSize is ignored and the ScrollableView pre-renders all 100 pages at once.\r\n\r\napp.js\r\n{code}\r\n// window\r\nvar win = Ti.UI.createWindow({\r\n\ttitle: 'TEST',\r\n\tbackgroundColor: '#ffffff'\r\n});\r\n\r\n\r\n// returns array of remote images (from kitchensink)\r\nfunction getPhotos() {\r\n\tvar data = [];\r\n\tvar baseUrl = 'http://placehold.it/';\r\n\tvar imageUrl;\r\n\tfor (i=30;i<40;i++){\r\n\t\tfor (j=30;j<40;j++){\r\n\t\t\timageUrl = baseUrl+i+'x'+j;\r\n\t\t\tdata.push(imageUrl);\r\n\t\t}\r\n\t}\t\r\n\treturn data;\r\n}\r\n\r\n\r\n// load event for remote image\r\nfunction img_load(e) {\r\n\tTi.API.info('Loaded remote image ' + e.source.id + ': ' +e.source.image);\r\n}\r\n\r\n\r\n// postlayout event for view\r\nfunction view_postlayout(e) {\r\n\tTi.API.info('Post-layout ' + e.source.id);\r\n}\r\n\r\n\r\n// scrollable view with set cache size set to 3\r\nvar pager = Ti.UI.createScrollableView({\r\n\tcacheSize: 3\r\n});\r\n\r\n\r\n// assemble and open\r\nwin.add(pager);\r\nwin.open();\r\n\r\n\r\n//\r\n// TEST CASE SELECTOR (1, 2, 3 or 4)\r\n//\r\nvar TEST_CASE = 1;\r\n\r\n\r\n// simulate 2s delayed xhr call to bind scrollable view with data\r\nsetTimeout(function() {\r\n\t\r\n\tvar photos = getPhotos(),\r\n\t\tpages = [];\t\r\n\t\r\n\t// TEST CASE BRANCH\r\n\tif (TEST_CASE == 1)\r\n\t{\r\n\t\t// CACHESIZE WORKS HERE: ONLY 3 VIEWS ARE LOADED\r\n\t\t\r\n\t\t// load empty container views\r\n\t\tfor (var i = 0; i < photos.length; i++)\r\n\t\t{\t\r\n\t\t\t// container view\r\n\t\t\tvar cont = Ti.UI.createView({ id: i, width: 300, height: 300, backgroundColor: 'red' });\r\n\t\t\tcont.addEventListener('postlayout', view_postlayout);\r\n\t\t\t\r\n\t\t\t// add container views to list\r\n\t\t\tpages.push(cont);\r\n\t\t}\t\t\r\n\t}\r\n\telse if (TEST_CASE == 2)\r\n\t{\r\n\t\t// CACHESIZE WORKS HERE: ONLY 3 IMAGES ARE LOADED\r\n\t\t\r\n\t\t// load imageviews directly (no container view)\r\n\t\tfor (var i = 0; i < photos.length; i++)\r\n\t\t{\t\r\n\t\t\t// image\r\n\t\t\tvar img = Ti.UI.createImageView({ id: i, image: photos[i], width: 200, height: 200 });\r\n\t\t\timg.addEventListener('load', img_load);\r\n\t\t\t\r\n\t\t\t// add imageview to list\r\n\t\t\tpages.push(img);\r\n\t\t}\t\t\t\r\n\t}\r\n\telse if (TEST_CASE == 3)\r\n\t{\r\n\t\t// CACHESIZE DOES NOT WORK HERE: ALL CONTAINERS AND CHILD REMOTE IMAGES ARE LOADED AT ONCE\r\n\t\t\r\n\t\t// load imageviews inside a container view\r\n\t\tfor (var i = 0; i < photos.length; i++)\r\n\t\t{\t\r\n\t\t\t// image view\r\n\t\t\tvar img = Ti.UI.createImageView({ id: i, image: photos[i], width: 200, height: 200 });\r\n\t\t\timg.addEventListener('load', img_load);\r\n\t\t\t\r\n\t\t\t// container view\r\n\t\t\tvar cont = Ti.UI.createView({ id: 'container '+i, width: 300, height: 300, backgroundColor: 'blue' });\r\n\t\t\tcont.addEventListener('postlayout', view_postlayout);\r\n\t\t\tcont.add(img);\r\n\t\t\t\r\n\t\t\t// add container to list\r\n\t\t\tpages.push(cont);\r\n\t\t}\t\t\r\n\t}\r\n\telse if (TEST_CASE == 4)\r\n\t{\r\n\t\t// CACHESIZE DOES NOT WORK HERE: ALL CONTAINERS AND CHILD VIEWS ARE LOADED AT ONCE\r\n\t\t\r\n\t\t// load view inside a container view\r\n\t\tfor (var i = 0; i < photos.length; i++)\r\n\t\t{\t\r\n\t\t\t// child view\r\n\t\t\tvar child = Ti.UI.createView({ id: 'child '+i, width: 200, height: 200, backgroundColor: 'red' });\r\n\t\t\tchild.addEventListener('postlayout', view_postlayout);\r\n\t\t\t\r\n\t\t\t// container view\r\n\t\t\tvar cont = Ti.UI.createView({ id: 'container '+i, width: 300, height: 300, backgroundColor: 'blue' });\r\n\t\t\tcont.addEventListener('postlayout', view_postlayout);\r\n\t\t\tcont.add(child);\r\n\t\t\t\r\n\t\t\t// add container to list\r\n\t\t\tpages.push(cont);\r\n\t\t}\t\t\r\n\t}\r\n\t\r\n\t// bind pages to scrollable view\r\n\tpager.applyProperties({\r\n\t\tviews: pages,\r\n\t\tcurrentPage: 0\r\n\t});\r\n\t\r\n\t\r\n}, 2000);\r\n{code}\r\n\r\nExpected result:\r\n\r\ncacheSize should work regardless if the pages are single controls or composite controls. \r\n\r\n\r\nNote: I experienced this problem on an Alloy app, but it can be reproduced in classic Ti as shown by the code above. My app loads up to 500 pages with child views and remote images. I noticed cacheSize was having no effect and it was taking a very long time and consuming a lot of memory to load the scrollable view.", "attachment": [], "flagged": false, "summary": "iOS: ScrollableView: cacheSize does not work if page views have children...", "creator": { "name": "bcproductions", "key": "bcproductions", "displayName": "Ed", "active": true, "timeZone": "America/Havana" }, "subtasks": [], "reporter": { "name": "bcproductions", "key": "bcproductions", "displayName": "Ed", "active": true, "timeZone": "America/Havana" }, "environment": "Ti SDK 3.2.3, iOS 7.1, Simulator 7.1", "comment": { "comments": [ { "id": "308612", "author": { "name": "sliang", "key": "sliang", "displayName": "Shuo Liang", "active": true, "timeZone": "Asia/Harbin" }, "body": "Hi,\r\n\r\nThank you for your ticket. It is a actual bug. I will file a ticket to engineer team to get this fixed.\r\n\r\nRegard,\r\nShuo", "updateAuthor": { "name": "sliang", "key": "sliang", "displayName": "Shuo Liang", "active": true, "timeZone": "Asia/Harbin" }, "created": "2014-06-12T07:15:30.000+0000", "updated": "2014-06-12T07:15:30.000+0000" }, { "id": "309194", "author": { "name": "rtlechuga", "key": "rtlechuga", "displayName": "Radamantis Torres-Lechuga", "active": false, "timeZone": "Asia/Dubai" }, "body": "duplicate of [TIMOB-17147|https://jira.appcelerator.com/browse/TIMOB-17147]", "updateAuthor": { "name": "rtlechuga", "key": "rtlechuga", "displayName": "Radamantis Torres-Lechuga", "active": false, "timeZone": "Asia/Dubai" }, "created": "2014-06-16T20:59:15.000+0000", "updated": "2014-06-16T20:59:15.000+0000" } ], "maxResults": 2, "total": 2, "startAt": 0 } } }