用免费地图给卡帕多奇亚民宿做预订页,被瓦片加载拖垮了
卡帕多奇亚的民宿老板想要个预订页,能拖动地图看位置,这个需求很合理。我接了这个外包单,用 Leaflet + OpenStreetMap 瓦片,本地开发时地图加载很快,拖动也流畅。但部署到线上后,用手机 4G 打开,瓦片加载慢得像挤牙膏,整张地图空白了三四秒,用户早滑走了。
我的做法是用 Leaflet 的 tileLayer 加缓存和预加载。先设置 updateWhenIdle: true,让拖动时不在每一帧都请求瓦片,减少请求数量。然后加 keepBuffer: 4,预加载可视区域外 4 个瓦片,这样拖动时不会出现大片空白。关键代码片段:
const map = L.map('map', {
center: [38.6431, 34.8289],
zoom: 13,
updateWhenIdle: true,
keepBuffer: 4
});
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© OpenStreetMap'
}).addTo(map);
另外,我用了 L.tileLayer 的 crossOrigin: true 配合 Service Worker 缓存瓦片,但 Service Worker 的缓存策略要谨慎,不然瓦片更新不了。最后我选择用 Workbox 的 StaleWhileRevalidate,先返回缓存,后台更新。这样二次访问时,瓦片基本秒开。
为什么这样做?updateWhenIdle 让 Leaflet 等到拖动结束再加载瓦片,牺牲了一点实时性,但大幅减少请求数;keepBuffer 用内存换流畅度,代价是初次加载多请求一些瓦片,但用户拖动时不会看到空白。Service Worker 缓存是双刃剑,如果瓦片更新频繁,用户可能看到旧地图,但对民宿位置展示来说,地图变化不大,可以接受。
哪里会失效?如果用户在弱网环境下首次访问,Service Worker 还没缓存,瓦片依然会慢,这时需要加个 loading 骨架屏,别让用户盯着空白。还有,OpenStreetMap 的瓦片服务器有使用政策,大量请求可能被限流,尤其是做商业项目时,最好换成 Mapbox 或自建瓦片。我踩过的坑是:一开始没设 maxZoom,用户放大到 20 级,瓦片 404,地图一片灰,被老板吐槽“你们这地图怎么是破的”。
结尾问一句:你们在做地图类页面时,是怎么平衡首次加载速度和拖动流畅度的?有没有更轻量的方案?
0 条评论
还没有评论,写下第一条。