uni-app H5定位为什么慢,看看源码 讨论讨论

1,173 阅读3分钟

这篇文章可以得到什么

  1. uniapp H5的定位源码 思路
  2. H5 定位为什慢
  3. H5定位的使用场景讨论& 不同场景的解决思路

起因,h5定位 为什么定位那么慢? 为什么时好时坏?

  1. 最近在用uniapp搞一款ToC产品(H5+微信小程序),就是上面的截图;项目起初看到uni.getLocation()很开心,不用care不同端的行为。
  2. 起初定位不是必要&核心业务环节,并没有care 定位的快慢与否;随着业务迭代 定位环节慢慢转变为主要&关键流程,因为慢 影响了后续流程,决定仔细调研一下

QA1: uniapp H5的定位源码 思路

image.png

gitee 源码地址自取

关键节点如下: step1,step2, step3


export function getLocation({type, altitude, isHightAccuracy,highAccuracyExpireTime}, callbackId) {
  const mapInfo = 读取manifest.json 文件中h5相关配置
  
  new Promise((resolve, reject) => {
      if (navigator.geolocation) {
        // step1. 使用navigator的定位功能
        navigator.geolocation.getCurrentPosition(
          res => resolve(res.coords), // 成功回调
          reject, // 失败回调
          {
            enableHighAccuracy: isHighAccuracy || altitude, // 是否开启最高精度
            timeout: highAccuracyExpireTime || 1000 * 100 // 多长时间内 设备必须返回一个位置
          }
         );
      } else {
        // step1. 如果当前场景不支持H5的navigator.geolocation 则通过reject抛出
        reject(new Error('device nonsupport geolocation'))
      }
  }).catch (()=> {
       // stpe2,如果原生定位失败、或不支持定位,则通过reject 到catch中,使用腾讯api定位
     return new Promise((resolve, rejct) => {
       if (mapInfo.type == QQ地图) {
         getJSONP('腾讯api')
           成功,则resolve 经纬度
           失败,则reject 网络错误
       }
       else if (mapInfo.type == 谷歌地图) {
         post 谷歌api
           成功,则resolve 经纬度
           失败,则reject errorMessage
       }
       else reject 网络错误
     })
  })
  .then((coords, skip) => {
    step3,进行经纬度转关  WGS84 国勘测gcj02
    resolve  调用腾讯api的结果
  })
  .then (corrds => {
    UniServiceJSBridge.invokeCallbackHandler({经纬度、message})
  })
  .catch (error => UniServiceJSBridge.invokeCallbackHandler({error.message})
}

tips: 现实版Promsie嵌套 [斜眼笑]

QA2: uniapp H5的定位源码 为什么慢 todo

  1. 默认的geolocation的timeout 是1000* 100
// MDN https://developer.mozilla.org/zh-CN/docs/Web/API/Geolocation/getCurrentPosition
// 最关键的在options配置 https://developer.mozilla.org/zh-CN/docs/conflicting/Web/API/Geolocation/getCurrentPosition
navigator.geolocation.getCurrentPosition(
  res => resolve(res.coords), // 
  reject,
  {
    enableHighAccuracy: isHighAccuracy || altitude, // 是否开启最高精度
    timeout: highAccuracyExpireTime || 1000 * 100 // 多长时间内 设备必须返回一个位置!!!!
  }
 );
 

&且 官方给出的实例 直接没有timeout配置,直接就1000 * 100了

image.png

  1. 各端实现不同,不知道为什么?edge chrome 不记得在哪里看到过chromium的源码,记得会调用google的接口。俺不懂源码。 如果使用edege 或者 chrome 打开梯子定位的响应很快;如果不翻,看命运了。

QA3: H5定位的使用场景讨论& 不同场景的解决思路

  1. 场景:粗估定位(IP)
    例如获取某某城市,建议直接用 百度地图 腾讯地图 高德地图提供的api,比获取经纬度要高效(项目最终:H5 WX小程序 都使用了IP定位)
  2. 场景:精确定位 (IP)
    我发现,PC端的Web版百度地图 在不使用GPS定位的情况下 也能精确定位,看看network 发现也是根据IP定位的。查了查一些博客,发现百度地图确实存在ip精准定位的api,但官网已经没有对应的api内容。于是找到百度地图售后咨询了一下,因涉及隐私问题,响应GV的政策,不对外销售了。
  3. 场景:精确定位(GPS宿主)
    如果是微信小程序,自身具备很好的宿主,直接调用wx的api即可;
    如果是内嵌自家APP,让app提供经纬度是极好的

踩过的坑

坑1. uniapp官网 说了有百度,一顿尝试,发现还是走腾讯的api; 原来是源码写死的

坑2. uniapp 官网默认,没有时间配置,导致我懒,没留意时间配置 image.png