Search code examples
flutterdartbase64freezedio

How Optimize this HTTP Request Method for Dispose Freezes in UI Thread?


When i run this method, in flutter, for example when I onTap in gesture detector flutter freezes 2 times, when get method invoke (I'm think there because of Dio json converter, maybe, idk), and when base64Decode method invoke

On the flutter web when get method invoke, flutter frizzed at all (onSendProgress not work to at this time too) and after this application in chrome crash with code 5, after minute, or two maybe -_-

context is not BuildContext

httpClient is Dio HTTP client

transformOf check is request result is error, and if yes, transform request result to my flutter custom exceptions, and after throw it, else return request result.

Request result size is 20-50mb

Future<Uint8List> readBookFile(Identificator groupId, Identificator bookId) async {
  final result = await context.httpClient.get(
    '/book/file',
    queryParameters: {
      'groupId': groupId.toString(),
      'bookId': bookId.toString(),
    },
  ).transformOf(context);

  return base64Decode(result['bookBytes']);
}

How optimise this code for dispose freezes?


Solution

  • For fix this I create 2 parse and 2 compute functions

    Uint8List parseBase64(String base64) {
      return base64Decode(base64);
    }
    
    Future<Uint8List> parseBase64Compute(String base64) {
      return compute<String, Uint8List>(parseBase64, base64.trim());
    }
    
    Map<String, dynamic> parseJson(String json) {
      return jsonDecode(json);
    }
    
    Future<Map<String, dynamic>> parseJsonCompute(String base64) {
      return compute<String, Map<String, dynamic>>(parseJson, base64);
    }
    

    After I'm create simple dio transformer for json

    class JsonTransformer extends DefaultTransformer {
      JsonTransformer() : super(jsonDecodeCallback: parseJsonCompute);
    }
    

    And apply this

    httpClient.transformer = JsonTransformer();
    

    And refactored function is

    Future<Uint8List> readBookFile(Identificator groupId, Identificator bookId) async {
      final result = await context.httpClient.get(
        '/book/file',
        queryParameters: {
          'groupId': groupId.toString(),
          'bookId': bookId.toString(),
        },
      ).transformOf(context);
    
      return parseBase64Compute(result['bookBytes']);;
    }