Closed lucasdinonolte closed 1 year ago
This is really lovely! I only have two small comments:
mechanicPreload
function isn't resettting its memoed objects whenever the design function is run, since the design function is re-run in a completely newly generated iframe
?memo
? People can always rename in the import if they want.Once these are taken care of, let's get it in :)
run
function that executes the handler
with the current values again. So it's not refreshing the page and the memoization function inside the handler still points to the singleton.main
and then request official review :blush:Excelllllleeeeent. Let's get it in! And let's remember to have a list of things to document for the docs.
Name | Link |
---|---|
Latest commit | 61542aabde9b04cb90e661d65500c465fb93fa53 |
Latest deploy log | https://app.netlify.com/sites/dsi-logo-maker/deploys/63e3c77f418915000864d435 |
Deploy Preview | https://deploy-preview-149--dsi-logo-maker.netlify.app |
Preview on mobile | Toggle QR Code...Use your smartphone camera to open QR code link. |
To edit notification comments on pull requests, go to your Netlify site settings.
I updated this, the big merge with the prettified main
messed a few things up. So to show the new behavior I updated Logo Canvas
on DSI Logo Maker with the new memo util. So you can switch between Logo Canvas
and Logo SVG
on the deploy preview to see the difference.
For Logo Canvas
you shouldn't see white flashes when editing a non-font parameter, while for the un-memoed Logo SVG
you should see a white flash for every input change.
@runemadsen @fdoflorenzano would you mind giving this a quick final pass?
Context
Some functions need to run slow code (like loading a bigger static file) upfront. This code is currently re-run on every preview, which can make things feel slow and less snappy in the UI.
To solve this the concept of function memoization could be used. Essentially a memoized function creates a cache based on it's input and immediately returns the cache, if its inputs didn't change – for example the
useMemo
hook in React.This PR explores the possibilities of adding memoization as a utility to Mechanic. It should serve as a starting point for debate how we want to implement this.
The actual implementation of memoization is fairly simple. The hard part is really: How do we want to expose this function to the users?
Prototypical Solution
mechanicPreload
function that is exported from mechanic coremechanicPreload
can be imported into a design functionmechanicPreload
to control what they want to be cached. It is an opt-in performance optimization.mechanicPreload
is modelled afteruseMemo
. It takes a function without arguments and an array of depedencies from the parent scope. Whenever the value of one of the dependencies changes the provided function is run.Other approaches to memoization
"Default" memoization in functional programming
The above implementation was chosen for the prototype based on the assumption that if people know about memoization they probably know about the way React does it
Traditionally memoization is realized by returning a memoizable function from another function (this sounds more confusing than the code looks):
While personally I find this approach more explicit I'm unsure if this is the right way to expose this functionality as this is deeply tied to functional programming, which probably not all of mechanic's users are super familiar with.
Ideal solution
The ideal solution from a user's perspective would be to not needing to worry about memoization and dependencies at all. Just wrap the things you want to cache inside a preload function and Mechanic will figure out how to cache it.
However this is also the hardest to implement. For the above example I can't think of a way for Mechanic to know about the function's dependencies (which it needs to build the cache key) that wouldn't involve some sort of parsing and AST magic. But maybe I'm missing an obvious solution.
TL;DR – I just want to see this in action
Logo Canvas
onDSI Logo Maker
has been updated to use memoization on the font loading. You can compare this to another design function to see the difference in rendering this makes.