Skip to content

Significant performance decrease on web when adding polyline sublayer #1081

@liranzairi

Description

@liranzairi

When adding MapPolylineLayer as a sublayer to MapShapeLayer on Flutter web, the performance decreases significantly down to a point where the whole app is practically stuck. This happens only on web, we haven't noticed it on mobile. Here is a sample app to reproduce the problem (tested with Flutter 3.7.1):

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:syncfusion_flutter_maps/maps.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: MyHomePage(),
      debugShowCheckedModeBanner: false,
    );
  }
}

class Shape {
  final String name;

  const Shape(this.name);
}

const _shapes = [
  Shape('shape1'),
  Shape('shape2'),
  Shape('shape3'),
  Shape('shape4'),
  Shape('shape5'),
  Shape('shape6'),
  Shape('shape7'),
  Shape('shape8'),
  Shape('shape9'),
  Shape('shape10'),
  Shape('shape11'),
  Shape('shape12'),
  Shape('shape13'),
  Shape('shape14'),
  Shape('shape15'),
];

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  late final MapShapeSource _mapSource;
  late final Future<Set<MapPolyline>> _polylinesFuture;
  var _showPolylines = false;

  @override
  void initState() {
    super.initState();

    _mapSource = MapShapeSource.asset(
      'assets/test.geojson',
      shapeDataField: 'name',
      dataCount: _shapes.length,
      primaryValueMapper: (int index) => _shapes[index].name,
      dataLabelMapper: (int index) => _shapes[index].name,
    );
    _polylinesFuture = _getPolylinesFromJson();
  }

  Future<Set<MapPolyline>> _getPolylinesFromJson() async {
    final json = await rootBundle.loadStructuredData(
      'assets/lines.json',
      (value) async => jsonDecode(value) as List,
    );
    final polylines = json.map((element) {
      final points = element as List;
      return MapPolyline(
        points: points.map((e) => MapLatLng(e[1], e[0])).toList(),
      );
    }).toSet();
    return polylines;
  }

  Widget _buildToggleLinesButton() {
    return TextButton(
      child: const Text('Show/Hide Polylines'),
      onPressed: () {
        setState(() {
          _showPolylines = !_showPolylines;
        });
      },
    );
  }

  Widget _buildTooltip() {
    return Container(
      color: Colors.red,
      width: 100,
      height: 50,
    );
  }

  Widget _buildMap(Set<MapPolyline> polylines) {
    return SfMaps(
      layers: [
        MapShapeLayer(
          source: _mapSource,
          showDataLabels: true,
          shapeTooltipBuilder: (context, index) => _buildTooltip(),
          sublayers:
              _showPolylines ? [MapPolylineLayer(polylines: polylines)] : null,
        ),
      ],
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Padding(
        padding: const EdgeInsets.all(20),
        child: FutureBuilder<Set<MapPolyline>>(
          future: _polylinesFuture,
          builder: (context, snapshot) {
            final polylines = snapshot.data;
            if (polylines == null) return Container();
            return Stack(
              children: [
                _buildToggleLinesButton(),
                _buildMap(polylines),
              ],
            );
          },
        ),
      ),
    );
  }
}

And attached is a zip with the two json files to put in the "assets" folder. When running the app, it will start by not showing the lines sublayer. At this point everything works fine. When clicking the button "Show/Hide Polylines", the lines will appear but the whole app will stop responding to touches and mouse hovers and the CPU will show a very high consumption.

files.zip

Activity

Shailevy

Shailevy commented on Feb 16, 2023

@Shailevy

The problem originates from the number of lines in the Geojson (the higher it the fast things freeze) and to the mouse handler (when disconnecting the mouse and using only a touch screen everything works fine)

This really prevents us from deploying our app.

Yuvaraj-Gajaraj

Yuvaraj-Gajaraj commented on Feb 17, 2023

@Yuvaraj-Gajaraj
Contributor

We have validated the provided code snippet and data points. You have created 5100 polylines, each with a large number of points. While hovering over the polylines, we checked each one to see if it contained the corresponding polyline using the hitTestSelf method. This process decreased performance when hovering over the map area. Currently, there is no option to disable the hovering feature on web platforms, but we will provide this option in our upcoming release.

If you do not require user interaction in your map sample, we suggest wrapping the SfMaps control in an IgnorePointer widget. This will ignore user interaction within the map and improve performance.

Shailevy

Shailevy commented on Feb 19, 2023

@Shailevy

Thank you,
You are correct about the large number of polyline but this is an extreme extreme real life example. we notices the problem also on smaller files.
I understand you using the hitTestSelf method but it seems that as the mouse moves too many event just clog the system, I think it's wise if you can wrap in your own wrapper and cancel the call (if possible) as mouse continues to move.
Using the IgnorePointer is a neat idea but it also ignore the tap (click) and we need that, we only want to ignore the hover.

Also, IMHO hover is not the same as "mouse over" , I remember back in the days I was doing UI in various OS'es a hover event was usually trigger after 300-500ms mouse staying in position (to show a tooltip) but that doesn't matter too much, it's just fpr the sake of the discussion

I really think this is something that should be handled better within the SfMaps.. any chance for any kind of fix ?

That being said its also important to mention that other products (not flutter libraries) the use geojson like https://geojson.io/ don't have problems with it.

Yuvaraj-Gajaraj

Yuvaraj-Gajaraj commented on Feb 22, 2023

@Yuvaraj-Gajaraj
Contributor

Currently, we don’t have support for ignoring the mouse hover alone in the SfMaps. However, we have considered your requirement ' improve the user interaction performance while hovering on maps with a large number of polylines' as a new feature and logged a feature request for it in our feedback portal.

We will prioritize the features of every release based on demand and priority. So, this feature will be available in any of our upcoming releases. You can also track the status of the feature with the feedback below.

Feedback, https://www.syncfusion.com/feedback/41437

Shailevy

Shailevy commented on Feb 22, 2023

@Shailevy

Thank ! it would be really helpful.

I guess you can't give me an estimated timeline but if you can please let me know.
I will tack the status in the link you suggested

ghost closed this as completedon May 9, 2023
walsha2

walsha2 commented on May 20, 2025

@walsha2

@Yuvaraj-Gajaraj @LavanyaGowtham2021 @SyncfusionKarthikeyan - I really think this issue should be reopened.

The issue is that the maps widget is responding to way too many mouse events. The issue manifests on web and desktop since the user can have a high polling rate mouse (e.g. +1000 Hz). At 60-100 Hz it is fine (even with 1000s of polylines), but as the polling rate of the mouse starts rising the widget performance degrades a lot.

Having 1000s of polylines is a pretty common use case and Is not particularly straining. Flutter can handle it and so can the widget, it just needs to not respond to every single mouse polling event. I left a comment on the syncfusion thread as well, but I really think this issue should be re-opened. We have run into this problem many times and it is a real issue.

https://www.syncfusion.com/feedback/41437

Mugunthan-Ramalingam

Mugunthan-Ramalingam commented on May 27, 2025

@Mugunthan-Ramalingam
Contributor

Hi @walsha2,

We suspect that the Maps widget will responds to a high number of mouse events when using a high polling rate mouse. We will consider this as an improvement and plan to address it when we work on enhancing user interaction performance with a large number of polylines in SfMaps.

However, we have already logged a feature request for this in our feedback portal and we will consider the reported case while implementing this feature. We prioritize features for each release based on overall demand and importance, so this improvement may be included in one of our upcoming releases. We will notify you here once the update is rolled out. We appreciate your patience and understanding in the meantime.

You can also track the status of this feature using the feedback link provided below:

FR link: Improve the user interaction performance while having a large number of polylines in SfMaps in Flutter | Feedback Portal

Regards,
Mugunthan.

ghost removed on May 27, 2025
ghost added on May 27, 2025
ghost added on May 27, 2025
ghost added on May 27, 2025
locked and limited conversation to collaborators on Jul 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    featureNew featuremapsMaps componentuncertainUncertain feature

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @Shailevy@liranzairi@walsha2@Yuvaraj-Gajaraj@VijayakumarMariappan

        Issue actions

          Significant performance decrease on web when adding polyline sublayer · Issue #1081 · syncfusion/flutter-widgets