150 likes | 377 Views
Optimizing Memory for Smooth Infinite Scrolling . Oct 22, 2013 Sumit Amar Director of Engineering, Electronic Arts. Agenda. Perceived Performance Unnecessary memory vs. Leaks Scrolling scenarios Snap-In vs. Inertial (aka Momentum) Scrolling Ever-growing memory with images
E N D
Optimizing Memory for Smooth Infinite Scrolling Oct 22, 2013 SumitAmar Director of Engineering, Electronic Arts
Agenda • Perceived Performance • Unnecessary memory vs. Leaks • Scrolling scenarios • Snap-In vs. Inertial (aka Momentum) Scrolling • Ever-growing memory with images • Optimizing image memory for the viewport • Discussion – Keeping a memory pool • Q&A
Outcomes • Learn about memory profiling tools • Gauge memory utilization and collection • Learn to keep allocated memory in check • Explore future ideas on optimizing further.
Introduction • Scriptable elements • Challenges in Inertial Scrolling • Blocked UI thread on momentum in iOS • More than required calls for other browsers • Seamless integration of new records (flicker free) • Why care? • Sluggishness and App crashes! • Keeping memory in your control (to some extent)
Remedies • Have a “Load More” button at the bottom • Really? • Remove elements not seen by user • Challenges: • Easy for Snap-in scenario but not for the inertial • How and when to bring the elements back • Snap-In experience (page by page swipe) • Ideal for horizontal scroll, but tiring for vertical
Idea 1 – Use a stack • Track scroll distance (scrollTop) for a container • If there are enough items scrolled-up • Push those elements’ (viz. images) metadata onto a Stack (a tuple with ID and metadata) • Attempt to remove the element from the DOM • Serialize the stack onto localStorage • If user scrolls back • Load the stack from localStorage • Pop n items from stack • Reload the element with metadata
Idea 1..contd. Idea 1 – Using stack works, but: • In a fast scroll or drag scenario, it can miss items • In a far drag scenario, loading all intermediary elements is sub-optimal because they’re not being seen anyway Sample structure [[“h1”,”http://localhost/a.jpg”], [“h2”,”http://localhost/b.jpg”]]
Idea 2 – Range hash table • Track scroll distance (scrollTop) for a container • If there are enough items scrolled-up • Grab offsetTop of n items sequentially • Determine a ‘range’ where this pixel position lies • E.g. item on 2560 will be between 2000-3000 • Create a pair with key being the element ID and value being the metadata such as image URL • Store the pair in the range key created • Serialize the hash table onto localStorage
Idea 2 – Range hash table..contd • If the user scrolls or drags quickly back up • Grab scrollTop position of container • Determine a ‘range’ where this pixel position lies • E.g. being at pixel 2560 will be between 2000-3000 • Load items from 2000-3000, and 1k-2k + 3k-4k ranges, and add them back to DOM • Delete restored keys from respective ranges • Serialize the modified hash table onto localStorage
Idea 2 – Contd. Idea 2 – Using a range hash table works, but: • Inefficient for minor scrolls Sample structure: {“0-1000”: { “h1”:”http://localhost/a.jpg”, “h2”:http://localhost/b.jpg }, “1000-2000”: { “h3” :http://localhost/c.jpg } }
Idea 1 + Idea 2 • Track scroll distance (scrollTop) for a container • If there are enough items scrolled-up • Grab offsetTop of n items sequentially • Determine a ‘range’ where this pixel position lies • E.g. item on 2560 will be between 2000-3000 • Create a pair with key being the element ID and value being the metadata such as image URL • Create a tuple containing ID and metadata • Push tuple onto stack • Store the pair in the range key created • Serialize hash table and stack to localStorage
Idea 1 + Idea 2 • When user backs up • Grab scrollTop of container • Load from stack, and delete corresponding key from the Range hash table • If a large distance between last two scroll positions found: • Load from Range hash table, delete the loaded item’s key • DEMO at http://www.amar.co.in/view.html
Issues – Future ideas • Loading an item from Hashtable-only, doesn’t remove from stack because O(n) would be suboptimal • Scrolling down, and then up restores items, but doesn’t remove items from the bottom of the container • Pooling and Recycling of DOM elements – The infinite scrolling scenarios can be addressed by using a finite set of elements and translate3d, but requires implementing inertia in JS (no Hard Acceleration)
Summary • Keep an eye on increasing memory • Try to remove memory allocated to elements not seen by user • Inertial scrolling preferred in vertical scrolls, but challenging to optimize • Further optimizations
Questions ? Contact/Suggestions - sumit@amar.co.in Source Code - www.amar.co.in/code/memory.zip