Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: remove lodash #164

Open
wants to merge 19 commits into
base: main
Choose a base branch
from

Conversation

christianEconify
Copy link
Contributor

@christianEconify christianEconify commented Feb 20, 2025

Removes lodash and replaces with internal functions, or regular javascript APIs
Have tested on internal projects and everything seems to work okay so far, however plan on more QA.

I think it's a good idea to get this PR open early for feedback

  • add tests for utils

Sorry, something went wrong.

@predikament predikament self-requested a review February 25, 2025 13:10
Copy link
Collaborator

@predikament predikament left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello @christianEconify,

Thanks again for opening the PR.

We had some discussions around this internally now, as well as double- (and triple-checked) how it is currently working.

A couple of things should be pointed out and discussed here, before we consider this or any related changes -

  1. If the primary motivator for this PR is related to issues with tree shaking, then this is entirely driven by the host application, as per how lodash is referenced and bundled: https://github.com/NoriginMedia/Norigin-Spatial-Navigation/blob/main/webpack.config.prod.js#L19

    From what we can see when the tree-shaking is working as it should, only the intended lodash dependencies are required in the final bundle:
- lodash/debounce
- lodash/difference
- lodash/filter
- lodash/findKey
- lodash/first
- lodash/forEach
- lodash/forOwn
- lodash/noop
- lodash/sortBy
- lodash/throttle
- lodash/uniqueId
  1. The current lodash imports are from trusted, well maintained and battle-tested sources
    We have been using these lodash imports for many years now, in the current cherry-picked form since at least 2019: https://github.com/NoriginMedia/react-spatial-navigation/releases/tag/v1.0.2

    (As well as this being something we do not need to manually maintain ourselves. ➕)

The proposed replacement utils.ts would be a couple of kilobytes lighter in the end, which is of course a good thing, but there are a couple of other discrepancies to note when comparing these two as well:

  • difference
    • Doesn't use any deep equality checks (like lodash.difference does), and it only seems support string and numbers types, so its more "targeted"
  • findKey
    • Directly calls Object.keys().find(), which is generally an optimization
  • debounce and throttle
    • Similar functionality, but lodash handles more edge-cases than the suggested functions do -
      F.ex. debounce correctly calls the function immediately with leading: true, but it doesn't reset the timeout when invoked immediately. This means that if the function is called multiple times right after the initial call it would not delay properly. The current lodash debounce version ensures subsequent calls adhere to the wait period and don't fire immediately.

That said we do understand the motivation for looking into removing lodash, especially considering bundle size constraints when shipping to TVs.

While the proposed implementation does reduce the bundle size a bit, it also introduces a couple of trade-offs, initially in terms of functionalities and edge-case handling, but perhaps more importantly the long-term maintainability of this project.

As such, it's a bit difficult to provide a definitive yes or no on whether we should proceed with this change.

@predikament predikament added the enhancement New feature or request label Feb 25, 2025
@christianEconify
Copy link
Contributor Author

christianEconify commented Feb 26, 2025

Thanks for the feedback on the PR!

Bundle with my PR Bundle with main Bundle with main no tree shaking
image image image
N/A image N/A
27.79 KB 24.31 + 26.34 94..21 + 26.34

Even with tree shaking, lodash is requiring an awful lot of helper functions that means the required size for Norigin to work is almost double. With my changes we're looking at around 22 kilobytes saved.

I can add additional test cases for the utils to ensure debounce and throttle match Lodash, which should help us be more confident in the implementations.

The difference function has been written on purpose to not do any deep equality checks as we were only using it for string comparisons anyway. You could argue that debounce has been setup this way too, it works for our use case, but I do think we should match lodash more for this in case we ever want to use leading: true in the future with the multiple immediate calls.

@predikament
Copy link
Collaborator

predikament commented Feb 26, 2025

@christianEconify: Fair points.

We have discussed this again today and we're still a bit unsure, to be entirely honest, but I am doing my best to see if we can find a good way forward with this.

The main reasoning for moving away from lodash is completely fair, but if the client (host) app that uses this library is already depending on lodash itself, then this will in the end result in a doubling of a lot of the same utilities.

(Technically this is the case today, if the host app has additional (equivalent or similar) "custom utilities", or even something like underscore for that matter, the outcome would still be a doubling of the "same" code.)

It's almost tempting to expose an alias / interface where you could supply your "variant" of these functions yourself, be it through lodash functions or your own.

We'll get back to you once I've had time to go over this a bit more and get closer to a proper answer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants