google maps api v3没有顺利拖动

时间:2013-05-20 08:49:57

标签: google-maps-api-3 lag

我开始使用maps api v3实现我的软件。不幸的是,我发现v3 API有一些严重的问题,这些问题让我从商业许可证中退回。

我的客户使用高清分辨率为1920x1080的显示器,地图占用屏幕空间的90%。不幸的是,我在谈论这个问题。当我在地图上用鼠标点击并开始拖动它时,不是很平滑,这真的很烦人。所有的乐趣消失了。

我使用 Windows XP,Windows 7和Windows 8尝试了一些不同的风格。我正在使用的浏览器是最新版本的Firefox,Chrome和IE 。 以下是我尝试拖动地图时的结果:

  1. 小屏幕分辨率320x240:Firefox,Chrome和IE处理得非常好。不可能注意到拖动不顺畅。
  2. 小屏幕分辨率320x240,地图上有10条折线:Chrome和IE处理得很好但是如果您有使用v2 API的经验,您会发现有所不同。 Firefox - 噩梦,拖动并不顺利。
  3. 中等屏幕分辨率1024x768。 Firefox - 有一些不确定的滞后。 Chrome和IE浏览器 - 平滑拖动,但如果你快速移动鼠标,事情会变得更糟。
  4. 中等屏幕分辨率1024x768,地图上有10条折线。 Firefox - 噩梦。 Chrome和IE浏览器 - 您开始注意到有一些延迟,但同时它看起来很顺利。
  5. 高分辨率1920x1080。 Firefox - 巨大的滞后。 Chrome和IE浏览器 - 好一点但仍有明显的滞后。 6)高屏幕分辨率1920x1080,地图上有折线:Firefox,Chrome广告IE - NIGHTMARE。拖动地图几乎是不可能的。
  6. 有趣的事实:

    1. 谷歌地图的v2 API不存在上述问题。
    2. 当鼠标移动小于每秒50-60像素时,上述问题不存在。拖动非常顺利。当鼠标快速移动时,会出现滞后现象。
    3. On http://maps.google.com问题根本不存在但是当我在开发人员上打开一些代码示例时指出问题就在那里。以下是一个示例:https://google-developers.appspot.com/maps/documentation/javascript/examples/full/circle-simple
    4. 我认为我尽可能深地描述了这个问题,无论我多么努力地绕过它,我找不到任何解决方案。

      如果有人就这个问题发表意见,我会很高兴。

      P.S。不幸的是我没有v2的密钥所以我不能创建一个例子,你可以在我的localhost之外查看地图,但我找到了一个网站,其中有一个并排的比较(v2和v3)。尝试拖动地图以查看非常不同的信息。

      http://www.wolfpil.de/v2-v3-sidebyside.html

      地图的分辨率非常小,很可能没有经验的用户可能看不到差异所以我也会给你单独的地图链接,你只需要使用firebug或类似的debuger来使画布分辨率更大。然后你会看到我在说什么。

4 个答案:

答案 0 :(得分:5)

同样在这里。我注意到的是v3在平移地图时会发生很多事件,而浏览器往往会窒息(特别是FF)。我这样说是因为我还使用了Bing Maps API,viewchange(相当于Google中的center_changed)的每秒事件数量要小得多。他们还提供了方法addThrottledHandler(),您可以使用该方法减少生成的事件数。

据我所知,Google地图似乎会针对每个center_changed事件触发一个mousemove事件,并且会在地图视图更新之前触发。所以你得到了很多生成的事件,但没有一个被复制到屏幕上;地图视图更新中的浏览器阻塞,或者可能是地图等待,直到没有更多更改,然后才更新视图。

修改:如果我们阻止某些mousemove事件到达Google地图,则浏览器不会阻止mousemove个事件以及Google地图从此事件生成的所有其他事件,例如center_changed,地图将顺利播出。

为此,我们向#map div添加一个事件监听器(我们也可以将其添加到body标签)。我们为捕获阶段添加事件。当鼠标在屏幕上移动时,首先body标记接收事件,然后是我们的#map div,然后是Google Maps元素(div,tiles)。这是捕获阶段。之后是泡沫阶段,其中事件从Google地图元素返回到#map div,然后再转移到body标记。通常事件处理程序在冒泡阶段注册,因此如果我们为捕获阶段注册处理程序,我们可以取消事件,因此此事件不会有冒泡阶段。这也意味着Google地图不会收到该活动。

您可以增加periodspace参数以杀死更多事件。杀死太多事件意味着地图将开始从一个位置跳到下一个位置。杀死太少意味着所有活动都将到达谷歌地图,浏览器将扼杀谷歌地图中新生成的事件,因此地图将从一个位置跳到下一个位置。一些中间地带效果最好。

现在完成所有这些后,Google地图将不如Bing地图那么顺畅。这是因为Bing Maps使用惯性:当您猛烈地移动地图时,地图将慢慢开始跟随鼠标然后越来越快。这确实创造了一个非常平滑的平底锅。

我发现一个有趣的事实是,即使鼠标不移动,Google Chrome和Opera / Chrommium也会每秒产生大约一mousemove个事件!此代码也将终止这些事件(因为distance对于这些事件为零)。

http://jsfiddle.net/uNm57/(在Firefox中检查js控制台;您应该看到一些已停止的事件,然后是一个允许的事件)

<html>
  <head>
    <style type='text/css'>
      #map {
          position: absolute;
          width: 100%;
          height: 100%;
          margin: 20px;
      }
    </style>

    <script type='text/javascript'>
      var last = {time : new Date(),    // last time we let an event pass.
                  x    : -100,          // last x position af the event that passed.
                  y    : -100};         // last y position af the event that passed.
      var period = 100; // ms - don't let pass more than one event every 100ms.
      var space  = 2;   // px - let event pass if distance between the last and
                        //      current position is greater than 2 px.

      function init_map() {
          map_div = document.getElementById("map")
          // map
          var map_options = {
              center: new google.maps.LatLng(45.836454, 23.372497),
              zoom: 8
          };
          map = new google.maps.Map(document.getElementById("map"), map_options);

          // register event handler that will throttle the events.
          // "true" means we capture the event and so we get the event
          // before Google Maps gets it. So if we cancel the event,
          // Google Maps will never receive it.
          map_div.addEventListener("mousemove", throttle_events, true);
      };

      function throttle_events(event) {
          var now = new Date();
          var distance = Math.sqrt(Math.pow(event.clientX - last.x, 2) + Math.pow(event.clientY - last.y, 2));
          var time = now.getTime() - last.time.getTime();
          if (distance * time < space * period) {    //event arrived too soon or mouse moved too little or both
              console.log("event stopped");
              if (event.stopPropagation) { // W3C/addEventListener()
                  event.stopPropagation();
              } else { // Older IE.
                  event.cancelBubble = true;
              };
          } else {
              console.log("event allowed: " + now.getTime());
              last.time = now;
              last.x    = event.clientX;
              last.y    = event.clientY;
          };
      };
    </script>
</head>
<body onload = "init_map()">
    <div id="map"></div>
</body>
</html>

答案 1 :(得分:3)

我们遇到了将CSS3过渡添加到所有元素的问题。

因此删除过渡,效果很好。

查看示例:

#map * {
  -moz-transition: none;
  -webkit-transition: none;
  -o-transition: all 0s ease;
  transition: none;
}

答案 2 :(得分:0)

我仅在移动浏览器中遇到此问题。在桌面浏览器中,拖动/平移很流畅,但在移动设备上,用户拖动地图时会出现延迟。我花了大约3个小时在此上,最后才意识到原因是缺少meta标签。

基本上,如果您不包含此元标记

<meta name="viewport" content="width=device-width, initial-scale=1">

问题来了。 3小时后才意识到这一点,或者不首先添加meta标签,我感到非常愚蠢。但是无论如何,如果其他人也犯了这个错误,我希望我节省了一些时间。

答案 3 :(得分:0)

我遇到了同样的问题,浪费了很多时间来解决,最后我想出了如何简单地解决这个问题。 @Arturs Smirnovs 的回答非常有帮助。 就我而言,css 中有一个过渡,由于 google 地图工作不顺利,我添加了 css 以禁用到地图的过渡,以便地图按预期工作。 希望这可以帮助任何人。

.google-map * {
    transition: none !important;
}