Skip to content

Enable Size Caching by default #80

@andersio

Description

@andersio

Problem Statement

Enable size caching by default in Bento, for both UITableView and UICollectionView (if using UICollectionViewFlowLayout).

This helps scrolling performance for use cases with a low frequency of changes & a moderate amount of screen complexity.

The problem is, however, the incurred cost during re-rendering of new Boxs. Bento must invalidate all cached sizes before starting to render any new Box, unless the component does not change at a given ID path. Pragmatically speaking, this cannot happen for a majority of components (e.g. BentoKit) falling back to the pointer equality (conservative but correct), due to them carrying non-equatable properties e.g. callback.

So if we enable size caching without addressing this issue, for screens that have high burst of state changes e.g. reacting to continuous text input, the cost of precomputation would be incurred every time a new Box is rendered, which is incredibly unideal.

Synthetic Benchmark

TitledDescription, 1000 iterations, -O -wholemodule
Source

Item Result (1000 iterations)
Full equality of layout affecting properties* Small Strings: 
sub 1 ms.
5000+ character strings: sub 2 ms

Custom Height Computation 
sub 100 ms

AutoLayout height computation
 > 1000 ms

* Style sheets & RAS properties are compared by value.

Observation

Evaluating equality of a subset of component properties is considerably cheaper (2-3 order of magnitude) than computing the actual layout height.

In order words, it is beneficial and pragmatic to evaluate equality so as to avoid as much layout computation as possible, lowering the performance impact of sizing ahead of time.

Proposed optimization

  • Introduce a notion of “component layout equivalence” to replace component equation.





    When we say C.isLayoutEquivalent(a, b) == true, all properties contributing to the layout from both instances are equal. In other words, rendering a and b should result in the same exact layout.

    Renderable would however provide a false returning default implementation. This effectively replicates the current behaviour (still correct but more expensive), while being (mostly) source compatible.

    BentoKit components should provide implementations for this requirement.

  • Remove Equatable inheritance from Renderable.

    We should not reappropriate == for component layout equivalence, since it would violate the substitutability requirement mandated by the Equatable contract.

  • With the above two measures in place, Bento may start pre-compute component height using AutoLayout by default
.

    Bento should invalidate only cached size for ID paths failing the component layout equivalence test.

  • (Optionally) Replacing HeightCustomizing with something more general.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions