jonsaw/amazon-cognito-identity-dart

Using of BigInt values cause UI to freeze

BobbyStatev opened this issue · 3 comments

When I was testing on emulator the login UI works fine. But on a real device (especially iOS) the UI just freeze and I was not able to display loading. So I debugging to the source code found out that the cause of this was operations on BigInt values. For my case I separate some of the functions to be run on Isolate (to not be run on the main thread). Now it works fine. I implemented this only on login. To be implemented in the whole library will be much more work. And I am not sure is there a better solution?

I can confirm I am seeing similar behaviour. Login takes 10+ seconds on iOS device, elsewhere only a couple seconds. But still in general a couple times slower than e.g. amplify react-native.

@BobbyStatev would you consider posting an example (or fork/PR) of how you are using isolates to work around it? I only desire a speedy login, as well.

Unfortunately doesn't make the process of login faster. But at least doesn't freeze the UI. Maybe if some of the calculations are made before clicking on the login button it can be faster. Also, I found out there is a general problem in Flutter with Big Int calculation on iOS. flutter/flutter#24827. I hope they fix it in the future.

Here is the example of parsing Big Int value in Isolate:

parseBitIntInIsolation(SendPort` sendPort) async {
  // Open the ReceivePort for incoming messages.
  var port = new ReceivePort();

  // Notify any other isolates what port this isolate listens to.
  sendPort.send(port.sendPort);

  await for (var msg in port) {
    var data = msg[0];
    SendPort replyTo = msg[1];
    replyTo.send(BigInt.parse(data, radix: 16));
    port.close();
  }
}

Future<BigInt> parseBigIntAsync(String hexCode) async
{
  var receivePort = new ReceivePort();
  await Isolate.spawn(parseBitIntInIsolation, receivePort.sendPort);
  var sendPort = await receivePort.first;
  var result = await sendReceive(sendPort, hexCode);
  return result;
}

Future sendReceive(SendPort port, msg) {
  ReceivePort response = new ReceivePort();
  port.send([msg, response.sendPort]);
  return response.first;
}

final String initN = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1' +
    '29024E088A67CC74020BBEA63B139B22514A08798E3404DD' +
    'BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31' +
    '43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF';

example() async {
  var result = await parseBigIntAsync(initN);
}

Hope this will help. Also I was thinking of uploading it to a separate repository. Or maybe to make a pull request in the future.

Hmm, I may have to try that!

Thanks for indicating that flutter repo issue, sounds like iOS release mode will not be affected, so that's good enough for me.

FWIW, I am also using the flutter_sodium package, and the performance from the native wrapping of libsodium is great. Maybe it's an option for this repo, too?