spatial-navigation
spatial-navigation copied to clipboard
Performance Issues - Layout Thrashing
The current implementation uses getBoundingClientRect()
and element properties like .clientHeight
, .clientWidth
, etc extensively. All of these will trigger the browser to synchronously calculate the style and layout. See https://gist.github.com/paulirish/5d52fb081b3570c81e3a for a complete list. This will cause issues if using animations or running apps on slow devices. Since one very good use-case for spatial navigation is SmartTVs, this is a real issue. SmartTVs are generally much slower than your average PC browser, and SmartTV apps usually have lots of animations.
I added this library to a an existing open-source movie application project, and navigated around a little bit. 30 elements were focused during this short navigation session, but getBoundingClientRect()
was called 15587 times. Many elements were called repeatedly with getBoundingClientRect()
.
- The app I'm using as an example is this: https://github.com/WayneMorganUK/sveltekit-movie-app (People tab)
- There is a demo deployment of the app here: https://sveltekit.athena-designs.com/ (without spatial-navigation-polyfill - the demo isn't mine)
- I have included spatial-navigation-polyfill in the head of src/app.html
Maybe it is possible to configure the library in a better way, which I'm not aware of? One improvement would be if it was possible to add a focusable
attribute to those elements that should be focusable, and then limit the focus candidate search to those. An id
attribute for each focusable element would enable memoization of the boundingClientRects to avoid repeated calls to getBoundingClientRect()
. Memoization would work well for SmartTV apps, since they don't resize. For web pages, memoization would have to be reset in case of resizing. In any case memoization should be optional and resettable.