Cómo dibujamos varios miles de objetos interactivos en el mapa sin dañar el rendimiento

Hola, mi nombre es Daria y soy la desarrolladora Frontend de la unidad Geo en Avito. Quiero compartir mi experiencia de cómo hicimos una nueva búsqueda de mapas en la web, reemplazando los clústeres con una solución más conveniente y eliminando la limitación en la cantidad de objetos mostrados.



En este artículo te contaré cuál fue nuestra tarea y cómo manejamos los problemas en el proceso de implementación.





 



    ,  — .  —     ,  .  —    .



    . -,      ,       . -,  — .    , .



:







,  , , ,     . ,    — .



 ,   .   , ,   .



      , , , .  —  .     , , . ,    , , . :



limit=viewPort.width×viewPort.height/(pinDiameter2×9)



, , .



   , .   , .   :



  •   ( );
  •   ( , );
  • ,   ,   (  ).


    :





  — . ,  —





,  —





, , —



,     , , .





  ,   1000 .     , , . , :





 



-, API . ,   ObjectManager,  ,   1000.   , , 3000 ,    .



,    .   API - — ,   Layer.



API  ,   (  png svg ) , X, Y Z. ,   -     . , API   ,     ( ), - .





 .   .  —



  ,     .    .



,       :



func (*Tile) Deg2num(t *Tile) (x int, y int) {
    x = int(math.Floor((t.Long + 180.0) / 360.0 * (math.Exp2(float64(t.Z)))))
    y = int(math.Floor((1.0 - math.Log(math.Tan(t.Lat*math.Pi/180.0)+1.0/math.Cos(t.Lat*math.Pi/180.0))/math.Pi) / 2.0 * (math.Exp2(float64(t.Z)))))
    return
}

func (*Tile) Num2deg(t *Tile) (lat float64, long float64) {
    n := math.Pi - 2.0*math.Pi*float64(t.Y)/math.Exp2(float64(t.Z))
    lat = 180.0 / math.Pi * math.Atan(0.5*(math.Exp(n)-math.Exp(-n)))
    long = float64(t.X)/math.Exp2(float64(t.Z))*360.0 - 180.0
    return lat, long
}


 Go,      .



svg  , :





   ,  GET-  .     :



const createTilesUrl = (tileNumber, tileZoom) => {
// params -      ,     GET-
return `/web/1/map/tiles?${params}&z=${tileZoom}&x=${tileNumber[0]}&y=${tileNumber[1]}`;
};
const tilesLayer = new window.ymaps.Layer(createTilesUrl, { tileTransparent: true });
ymap.layers.add(tilesLayer);


 ,    Layer, :







,   15-30    ,       5000 rps.        ,   . ,     .



  ,     , . .     . ,  , , 4, 25.



.    ,     .





     Redis  -,   , .   ,     , ,  . ,      .



, ,  ,   .   , .



 Redis .   , ,    , ,     .  Redis  in-memory.    Redis.



  , ,     .  in-memory cache ,   . -.   :





 99  ~140 ms. 99% .  :     ~230 ms   .



:    , , .   ,   svg.   ,   .





,    .  .



,



.   ,  .    —    , ,       50 . , .    ,   , ,   .  —   ,  . ,   ,  —  ,  .



,  .  ,    .  ,  ,   .    —   . ,    . , , . ,   , —     , , id   . ,     .





.    —     ,   -  , . ,  .    10   forEach .





.    .  localStorage  1000 id . Ids , .   , ,    localStorage.



,  .  ,  — ,  — .   .



    ,    -.  /, , , .   .



    svg  .  - .





-





-





,       —   .




All Articles