You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We'll need to virtualize a user's gallery in order to minimize UX jank and unnecessary network requests. This is particularly important given the heftiness of NFTs and some of them being large, high-res videos. This article does a great job summarizing the approach.
The industry standard library to accomplish virtualization is react-window, which is by the same author who wrote the preceding react-virtualized. Data efficiency around loading each asset should be handled out-of-the-box, since an unrendered literally won't trigger a network request.
The problem
Unfortunately, virtualization tools rely heavily on the height of each row being known in advance. In other words, it wants to have an idea of the scaffolding needed for your list (or grid) before anything renders.
This is easy to deal with if the elements within your grid have uniform height (e.g. chess board), and becomes a lot more difficult if each row has varying heights (e.g. gallery with both tall and short NFTs). We also can't use the tallest possible NFT as a bottleneck, as this would stretch out each row to be taller than necessary, and cause otherwise normal-sized NFTs to be spread out. Discussion around this issue can be found here: bvaughn/react-window#190
The solution(s)
There are two potential solutions:
Variable Size List. This supports rows of varying sizes. However, this still requires the a known height for each row in advance. We can do this by storing the dimensions of each NFT in the database, and retrieving those dimensions when loading a user's gallery:
Then we can use the user's current browser width to determine the max height + width for any NFT, and apply that against the aspect ratio from the server. We'll also need to know how many columns the user should see (again from browser width) to finalize the height of each row. For example, a tall NFT may appear on row 1 / col 3 in desktop view, but row 3 / col 1 in mobile view, affecting the heights we assign to each row for the virtualizer.
The only downside to the approach is a) storing extra metadata on the server and b) client-side computations we'll have to perform on fetch. We can mitigate b) by having the server handle the aspect ratio for each screen width as a pre-processing step, like so:
Dynamic Size List. In theory, this supports variable list sizes without knowing row heights in advance. This uses just-in-time measuring of each row based on its content, and is outlined here: Support just-in-time measured content bvaughn/react-window#6. This feature is only available as an alpha and does exhibit some issues around jittery scroll position.
DynamicSizeList would make our lives a lot easier. We should try this first, see if it works for our use case, and resort to VariableSizeList as a backup.
Another problem ...
Not only will the rows be varying heights, but there will also be intermittent collection headers we'll have to squeeze in (e.g. title, description, whitespace). This is arguably more challenging than the image issue since the server can't tell us how "tall" someone's description text will be.
... and another solution
We should be able to solve this by giving all collection headers a fixed height and virtualizing it themselves, by interspersing them within the array of NFTs. Feels a bit hacky but there should be a clean solution.
It may also be a bit awkward if a collection has no title while another has a full title + long description. Perhaps we could guesstimate the height of a collection header simply by checking whether a title and/or description exists.
The text was updated successfully, but these errors were encountered:
Gallery Virtualization Strategy
We'll need to virtualize a user's gallery in order to minimize UX jank and unnecessary network requests. This is particularly important given the heftiness of NFTs and some of them being large, high-res videos. This article does a great job summarizing the approach.
The industry standard library to accomplish virtualization is react-window, which is by the same author who wrote the preceding react-virtualized. Data efficiency around loading each asset should be handled out-of-the-box, since an unrendered literally won't trigger a network request.
The problem
Unfortunately, virtualization tools rely heavily on the height of each row being known in advance. In other words, it wants to have an idea of the scaffolding needed for your list (or grid) before anything renders.
This is easy to deal with if the elements within your grid have uniform height (e.g. chess board), and becomes a lot more difficult if each row has varying heights (e.g. gallery with both tall and short NFTs). We also can't use the tallest possible NFT as a bottleneck, as this would stretch out each row to be taller than necessary, and cause otherwise normal-sized NFTs to be spread out. Discussion around this issue can be found here: bvaughn/react-window#190
The solution(s)
There are two potential solutions:
Then we can use the user's current browser width to determine the max height + width for any NFT, and apply that against the aspect ratio from the server. We'll also need to know how many columns the user should see (again from browser width) to finalize the height of each row. For example, a tall NFT may appear on row 1 / col 3 in desktop view, but row 3 / col 1 in mobile view, affecting the heights we assign to each row for the virtualizer.
The only downside to the approach is a) storing extra metadata on the server and b) client-side computations we'll have to perform on fetch. We can mitigate b) by having the server handle the aspect ratio for each screen width as a pre-processing step, like so:
DynamicSizeList
would make our lives a lot easier. We should try this first, see if it works for our use case, and resort toVariableSizeList
as a backup.Another problem ...
Not only will the rows be varying heights, but there will also be intermittent collection headers we'll have to squeeze in (e.g. title, description, whitespace). This is arguably more challenging than the image issue since the server can't tell us how "tall" someone's description text will be.
... and another solution
We should be able to solve this by giving all collection headers a fixed height and virtualizing it themselves, by interspersing them within the array of NFTs. Feels a bit hacky but there should be a clean solution.
It may also be a bit awkward if a collection has no title while another has a full title + long description. Perhaps we could guesstimate the height of a collection header simply by checking whether a title and/or description exists.
The text was updated successfully, but these errors were encountered: