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

getImageData slow #198

Closed
runrevben opened this issue Nov 18, 2020 · 10 comments
Closed

getImageData slow #198

runrevben opened this issue Nov 18, 2020 · 10 comments

Comments

@runrevben
Copy link

This is a super component and we've been using extensively in a project. Happy to contribute should someone be able to point me in the right direction:

I'm implementing a component that has to use getImageData() multiple times in a loop. Of the 10 or so calls in each loop, some take up to 500ms to resolve, others just 5ms. I'm guessing that the performance issue relates to the messaging between RN and the WebView, rather than the getImageData() call.

  1. Is there a work around?
  2. If not, Would implementing a custom function like getImageDataMultiple(RectangleArray) likely solve the issue by reducing the RN -> WebView interaction to a single call?
  3. Would it be accepted back into the source? I'd prefer not to maintain a custom fork if poss.
@iddan
Copy link
Owner

iddan commented Nov 19, 2020

Hey, thank you for taking the time for explaining your issue. I’d say getImageDataMultiple is a little too specific but I’d be glad to add some batching functionally. I think it can be done if the component will wait for the next tick before sending the request to the WebView then multiple requests can be sent together and return together (assuming they are called with Promise.all or without await). Even without changes to the code if you are not using Promise.all right now it should really help with performance of multiple calls to the webview

@runrevben
Copy link
Author

runrevben commented Nov 23, 2020

OK thanks. We are currently using a mixture of promise.all and await.. I'll look at refactoring to remove the await.

Batching sounds like a great idea though. If you think that's something that can realistically be added we'd be happy to help with development, unless it's straightforward for you? I'm expecting our app will increase its dependance on getImageData so being able to batch would be a bit benefit.

Cheers,

Ben

@runrevben
Copy link
Author

runrevben commented Nov 23, 2020

I removed all my awaits and put the calls the getImageData in to a Promise.all call. It didn't make a great deal of difference to the performance. I'm wondering if I'm doing it right?

   const data = await Promise.all(
      parts.map(async (part) => {
        const [a, b, c, d] = getBoundsFromPath(part.path);
        ctx.getImageData(
            a * devicePixelRatio,
            b * devicePixelRatio,
            (c - a) * devicePixelRatio,
            (d - b) * devicePixelRatio
          )
          .then((imageData) => {
            return {
              name: part.name,
              data: Object.values(paintImageData.data),
            };
          });
      })
    );

All the data is returned as expected but there is a considerable wait between data being returned during the map

@iddan
Copy link
Owner

iddan commented Nov 24, 2020

I'm not sure how this get code works as you don't return the promise in the map function. But assuming you are, yes this is the correct way to do this (using async/await in the map function is fine). As I wrote in the previous comment. It is realistic to add on the RPC level between React Native and the WebView a batching mechanism that waits for the next tick and sends multiple calls to the WebView at once.

@runrevben
Copy link
Author

Hi @iddan, we changed our code again as per your comments to return the promises and then resolved all our data once then promise.all returned. Unfortunately the performance improvement was minimal.

I'd be interested in your thoughts re implementing batching in your code. I think that would help us and others as it appears this library is the best on out there for Canvas and ReactNative. I'd be happy to show you what our app is doing and even get a developer to try and help implement the changes if that's useful.

@iddan
Copy link
Owner

iddan commented Nov 29, 2020

Check the code here: https://github.com/iddan/react-native-canvas/blob/master/src/Bus.js this is the object managing communication with the webview on the React Native side.

@ASKNJ
Copy link

ASKNJ commented Mar 19, 2022

Hi @idan,

I have found that getImageData is taking too long , Could you please help us with the batch approach ?

Thanks

@ASKNJ
Copy link

ASKNJ commented Apr 8, 2022

Hey @iddan ,

Can you please help me in finding out the batch approach?
I am fetching imageData pixels but it is taking 30 seconds for reading 1080*1080 data

Thanks in advance for help!!

@nora-soderlund
Copy link
Contributor

Can someone post a MRE because nothing here proves that it's an underlying issue to the messager here.

getImageData is very slow by default, and calling it multiple times in a loop is expected to be very slow, in javascript.

@iddan
Copy link
Owner

iddan commented Jul 3, 2024

Closing this issue due to inactivity

@iddan iddan closed this as completed Jul 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants