LoopScrollRect: cell recycling for Unity UGUI ScrollRect
These scripts will make your UGUI ScrollRect reusing cells, to improve performance, loading time and draw calls.
At a glance
- What is it?
- LoopScrollRect replaces Unity's ScrollRect cell instantiation with a reusable pool, and its README frames the payoff as fewer draw calls, faster loading and lower memory. Here is what the package actually requires from you, and where it stops helping.
- Who is it for?
- Adopt LoopScrollRect when a ScrollRect holds enough cells that instantiation cost, memory or draw calls are visible in a profiler, and when you can supply a prefab source, a data source and cells with preferred width and height. Do not adopt it for short lists, or when your cells cannot carry a ScrollCellIndex method and a Layout Element.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 115 days ago.
- What is it written in?
- Mainly C#, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The cost LoopScrollRect removes from a UGUI ScrollRect
A plain ScrollRect builds every cell it contains. If your list has a thousand entries, the scene pays for a thousand GameObjects before the user has scrolled anywhere. The README states the project's purpose directly: the scripts make your ScrollRect reusable, because it will only build cells when needed, and it adds that with a large number of cells you absolutely need it, since it saves loading time, draw calls and memory.
The audience is Unity developers working in UGUI, the built-in UI system, on lists long enough that the population step shows up in a profiler. The package declares UGUI as its only dependency in package.json and targets Unity 2019.4 as the minimum editor version. It is not a general UI framework and it does not replace ScrollRect. It subclasses the behaviour and swaps out how cells come into existence.
Prefab source, data source, and the size helper
The mechanism is an indirection on two axes. The README names two interfaces you implement: LoopScrollPrefabSource, which provides cells and for which the README says a cache pool is highly recommended, and LoopScrollDataSource, which supplies data to a specified cell. The prefab source decides where a cell object comes from; the data source decides what that cell displays.
A third interface, LoopScrollSizeHelper, appears when cells are not uniform. The README points at SizeHelper.cs for cells with different sizes and describes it as providing precise cell sizes. Without it, the layout logic has to assume something about cell dimensions, which is exactly the assumption variable-height rows break.
Cells themselves carry two requirements. Each cell needs preferred width and height in its Layout Properties, and the README says the easiest route is attaching a Layout Element and setting preferred width and height. Each cell also needs a script that receives void ScrollCellIndex (int idx). That method is the handoff point: the layout code calls it with an index, and your data source is expected to fill the cell for that index.
Installing LoopScrollRect and getting a first list on screen
The README gives two install paths. With OpenUPM, the command is a single line. Run it from a shell in your Unity project directory, and the package is added to the project manifest under the name me.qiankanglai.loopscrollrect.
openupm add me.qiankanglai.loopscrollrectThe alternative is inside the editor: open Package Manager, choose Add package from git URL, and paste the repository URL. Both routes land the same package version, 1.1.5 as of the latest release listed in package.json.
https://github.com/qiankanglai/LoopScrollRect.gitFor a first real use, do not start from an empty scene. The README says to refer to DemoScene for quick startup, and points at InitOnStart.cs as the simplest example usage. Open that scene and read InitOnStart.cs before writing your own component, because it shows both interfaces wired together at the smallest scale the project ships.
// InitOnStart.cs, referenced by the README as the simplest example
// implement LoopScrollPrefabSource to hand out cells (use a cache pool)
// implement LoopScrollDataSource to fill a cell for a given index
// cell script must expose: void ScrollCellIndex (int idx)The cell prefab is where most first attempts fail. Attach a Layout Element and set preferred width and height, then attach a script with the ScrollCellIndex signature. The README also notes that DemoScene_MultiCell covers a more complex arrangement and DemoSceneSingle tests LoopScrollRects which are not fully filled, which is the case where a list is shorter than its viewport.
The Inspector controls and what they change
The package exposes several operations in the Inspector for testing without writing code, and the distinction between them matters for performance.
Total Count sets the number of cells, and the README states that a negative number means infinity, which suits endless feeds. Reverse Direction flips the scroll axis for bottom-to-top vertical or right-to-left horizontal scrolling, and the README notes you must also adjust the Content's pivot and anchor; enabling the flag alone is not enough.
Clear empties items and sets total count to zero. Refresh updates existing items without touching layout, and the README gives the reason: all cells only get data updated for performance concern. Refill and RefillFromEnd clear and rebuild from the start or the end respectively, and both recalculate layout fully. That pairing is the whole trade-off in miniature. Refresh is cheap and leaves layout alone; the two refill operations are correct after a size change and cost a full recalculation.
The scroll test group adds ScrollToCell, which moves to an item and offset at a given speed, and ScrollToCellWithinTime, which reaches the same target in a fixed duration. GetFirstItem and GetLastItem return the visible item index and offset, and their values feed the corresponding refill calls, which is how you restore scroll position after rebuilding a list.
Where the package asks you to do the work
Cell recycling is not free. The prefab source is yours to write, and the README's recommendation of a cache pool is doing real work: if your implementation instantiates on every request, you have moved the allocation rather than removed it. The data source is also yours, and it must be able to answer for an arbitrary index on demand. Code that assumes a linear build order will not fit.
The cell contract is stricter than it looks. A cell without preferred width and height gives the layout logic nothing to measure, and a cell without a ScrollCellIndex receiver cannot be filled. The README does not document rollback of a refill, nor does it describe how to reconcile a data source that mutates while cells are pooled. If your list changes underneath the scroll view, the README is silent on the ordering guarantees you should expect.
This is the wrong tool for short lists. If a ScrollRect holds a few dozen cells that all fit in memory and on screen, the two interfaces and the Layout Element requirement are overhead with no corresponding saving. It is also wrong when your UI is not UGUI, since the package depends on com.unity.ugui and subclasses ScrollRect behaviour.
How this differs from a virtualizing list built on your own pooling
The obvious alternative is hand-rolling the same idea: keep a pool of cell objects, compute which indices are visible, and move pooled objects into those slots. That is what LoopScrollRect does, and the difference is in what you inherit. Writing it yourself means owning the size calculation for variable-height cells, the reverse-direction pivot and anchor math, and the scroll-to-cell interpolation. The package ships SizeHelper.cs for the first, documents the pivot and anchor adjustment for the second, and exposes ScrollToCell and ScrollToCellWithinTime for the third.
The other comparison is Unity's own UI Toolkit ListView, which virtualizes items as part of a separate UI system. Choosing it means leaving UGUI entirely, which is a much larger migration than swapping one ScrollRect component. LoopScrollRect stays inside the UGUI world, which is why it can be dropped onto an existing hierarchy with a Layout Element and a ScrollCellIndex method.
Version history, licence and what maintenance looks like
The repository is not archived, and the last push was on 2026-06-07. Recent releases are v1.1.5 on 2026-01-17, v1.1.4 on 2025-07-18 and v1.1.3 on 2025-02-28, so the release cadence over the past year has been roughly two per year. The CHANGELOG.md file at the repository root is where the changes between those tags are recorded; read it before upgrading, because the README does not describe a migration path between versions.
The package is MIT licensed, and the LICENSE.md file sits at the repository root alongside it. For anyone embedding the package in a shipped product, the practical point is that MIT permits commercial use and modification, but the terms are the licence text's, not this article's. Read LICENSE.md rather than a summary.
The upgrade cost is tied to the interfaces. Because LoopScrollPrefabSource, LoopScrollDataSource and LoopScrollSizeHelper are implemented in your code rather than the package, a signature change in any of them is a change to your project. Nothing in the README promises those interfaces are frozen, and the version numbering has moved through 1.1.x rather than 2.x, which suggests incremental rather than breaking change so far.
Editorial conclusion
Adopt LoopScrollRect when a ScrollRect holds enough cells that instantiation cost, memory or draw calls are visible in a profiler, and when you can supply a prefab source, a data source and cells with preferred width and height. Do not adopt it for short lists, or when your cells cannot carry a ScrollCellIndex method and a Layout Element. Verify first that your Unity version is at least 2019.4 as package.json states, that your cell prefabs have preferred width and height set, and that your data source can answer index requests on demand rather than from a prebuilt list.
Frequently asked questions
What Unity version does LoopScrollRect require?
The package.json file declares a minimum of Unity 2019.4, and the only dependency listed is com.unity.ugui at version 1.0.0.
How do I install LoopScrollRect?
Either run openupm add me.qiankanglai.loopscrollrect with OpenUPM, or open Package Manager in Unity and use Add package from git URL with the repository URL.
What must a cell prefab have for LoopScrollRect to work?
The README states that the cell needs preferred width and height in its Layout Properties, most easily via a Layout Element, and that it needs a script receiving void ScrollCellIndex (int idx).
What is the difference between Refresh and Refill in LoopScrollRect?
Refresh updates existing cells without affecting layout, and the README says all cells only get data updated for performance concern. Refill and RefillFromEnd clear and rebuild items from the start or the end and recalculate layout fully.
What licence is LoopScrollRect released under?
It is MIT licensed, with the LICENSE.md file at the repository root and the licence also stated in the README badge.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/qiankanglai-loopscrollrect)