Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

291
Views
MapBoxGL, multiple layers performance issue

Premise: I have a set of data (stops on the map)loaded via geoJSON in a clustered source, each of these stop locations can have a different icon.

I have over 140 variations of icons. I am iterating through all of them and I generate a "symbol" type layer for each one.
Also, I am loading each stop icon image(png format) via map.loadImage().

Problem: The issue that I am facing is that the loading time is very high and the map isn't smooth until all the layers are loaded and displayed.

Can you please help me with a suggestion on how to reduce the loading time and increase the performance?

TheLayer.tsx

export default React.memo(function MyStopsLayers(props: Props) {
  return (
    <>
      {ICONS.map(icon =>
        props.isEditMode ? (
          <EditStopLayer key={icon.id} icon={icon} {...props} />
        ) : (
          <StopLayer key={icon.id} iconType={icon} {...props} />
        ),
      )}
    </>
  );
});

StopLayer.tsx

const StopLayer: React.FC<Props & { icon: Icon }> = ({ icon, showOrderNumber }) => {
  return (
    <>
      <Layer
        key={icon.id}
        id={icon.id}
        type="symbol"
        source={MAP_CLUSTERS_SOURCE}
        filter={['all', ['!', ['has', 'point_count']], ['==', ['get', 'icon'], icon.id]]}
        paint={{}}
        layout={{
          'symbol-z-order': 'source',
          'symbol-sort-key': 1,
          'icon-image': icon.id,
          'icon-size': 0.5,
          'icon-allow-overlap': true,
        }}
      />
      {showOrderNumbers && (
        <Layer
          key={icon.id + 'orderNumber'}
          id={icon.id + 'orderNumber'}
          type="symbol"
          minzoom={15}
          source={MAP_CLUSTERS_SOURCE}
          filter={[
            'all',
            ['!', ['has', 'point_count']],
            ['==', ['get', 'icon'], iconType.id],
          ]}
          paint={{ 'text-halo-color': '#fff', 'text-halo-width': 15 }}
          layout={{
            'symbol-z-order': 'source',
            'text-field': showOrderNumber ? ['get', 'orderNo'] : '',
            'text-offset': [0, 1.25],
            'text-size': 15,
          }}
        />
      )}
    </>
  );
};
about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

You can and should have only one layer for all your stop locations. The way you set a different icon for each one is by using data-driven styling, see this for example.

First you load the images:

 map.addImage("someIcon1", iconResource1)
 map.addImage("someIcon2", iconResource2)

Then, in the source you add the icon id to an "icon" property for each stop location:

const feature = {
            id: data.id,
            type: 'Feature',
            properties: {
                id: data.id,
                icon: "someIcon1" // use the icon id here
            },
            geometry: {
                //...
            }
        };

And then, in the layer layout property you would get the icon from the source:

 layout: {
        'icon-image': ['get', 'icon']
    },
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!