Skip to content

[google_maps_flutter] Performance drop when loading markers from bytes #41731

@tzvc

Description

@tzvc

Hi there,

I'm building a map application in which I have A LOT of different marker designs to display (depending on the kind of POI).
As I have to constantly renderer different marker on the map, I decided to optimize performance by loading all the marker design from assets file (using BitmapDescriptor.fromImageAsset() function) at the beginning and storing that in a

Map<int, BitmapDescriptor>

It worked great, the performance was good.

I then decided to generate my markers with code instead of loading them from image assets using the following code:

Future<BitmapDescriptor> generatePostClusterMarker(
    String text, double sizeFactor, double pixelRatio) async {
  print(pixelRatio);
  Function wRatio = (input) => input * pixelRatio;
  final stopwatch = Stopwatch()..start();
  final ui.PictureRecorder recorder = ui.PictureRecorder();
  final Canvas canvas = Canvas(recorder);

  final TextSpan textSpan = TextSpan(
    style: TextStyle(
        color: Colors.pink,
        fontSize: wRatio(13 * sizeFactor),
        fontWeight: FontWeight.w900),
    text: text,
  );

  final TextPainter textPainter = TextPainter(
      text: textSpan,
      textDirection: TextDirection.ltr,
      textAlign: TextAlign.center);
  textPainter.layout();

  double diameter = 100 * sizeFactor;
  double blurSigma = wRatio(5);
  Size boxSize = Size(diameter, diameter);
  Size outputSize =
      Size(boxSize.width + 2 * blurSigma, boxSize.height + 2 * blurSigma);

  // paint shadow
  canvas.drawCircle(
      Offset(outputSize.width / 2, outputSize.height / 2),
      diameter / 2,
      Paint()
        ..color = Colors.black.withAlpha(50)
        ..maskFilter = MaskFilter.blur(BlurStyle.normal, blurSigma / 2));
  // paint rounded box
  canvas.drawCircle(
      Offset(outputSize.width / 2, outputSize.height / 2),
      diameter / 2,
      Paint()
        ..color = Colors.white
        ..isAntiAlias = true
        ..style = PaintingStyle.fill
        ..filterQuality = FilterQuality.high);
  // paint text
  textPainter.paint(
      canvas,
      Offset((outputSize.width / 2) - (textPainter.size.width / 2),
          (outputSize.height / 2) - (textPainter.size.height / 2)));

  final ui.Picture picture = recorder.endRecording();

  final ByteData pngBytes = await picture
      .toImage(outputSize.width.toInt(), outputSize.height.toInt())
      .then((image) => image.toByteData(format: ui.ImageByteFormat.png));
  print(
      'Marker $text [${outputSize.width}x${outputSize.height}] generated in ${stopwatch.elapsed.inMilliseconds}');

  picture.dispose();
  return BitmapDescriptor.fromBytes(pngBytes.buffer.asUint8List());
}

again loading them all at the beginning and storing all the resulting BitmapDescriptor in a Map.

But after doing that, the performance took a big hit, markers now take longer to render on the map and the whole thing is not fluid as it used to be when they were loaded from image assets.

What I don't understand is that after the initial loading, the generated Map<int, BitmapDescriptor> should contain exactly the same thing (as the generated markers are exported with the same image size as the image assets), so why is performance worst?

What really is the difference between this:
Screen Shot 2019-10-01 at 8 13 47 pm

and this:

Screen Shot 2019-10-01 at 8 12 11 pm

Am I missing something here? What else can I do to improve marker loading performance?

Cheers!

Theo

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work lista: imagesLoading, displaying, rendering imagesc: performanceRelates to speed or footprint issues (see "perf:" labels)found in release: 2.2Found to occur in 2.2found in release: 2.4Found to occur in 2.4has reproducible stepsThe issue has been confirmed reproducible and is ready to work onp: mapsGoogle Maps pluginpackageflutter/packages repository. See also p: labels.team-ecosystemOwned by Ecosystem teamtriaged-ecosystemTriaged by Ecosystem team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions