openlayers 网络应用程序在移动设备上运行速度非常慢 (Android Chrome)
openlayers web application runs very slow from mobile (Android Chrome)
我知道这听起来像是一个典型的问题,应该关闭,但我碰壁了,不知道去哪里寻找解决方案,所以希望我能提供足够的细节来解决这个问题SO 可接受的问题。
我正在开发一个可以访问的 OpenLayers Web 应用程序 here。
它的源代码在this github repo.
如果你在电脑上试用该应用程序,用户体验应该没问题(至少,这是我个人的体验)。
但是,当我从我的移动浏览器(Chrome,我的 phone 是 Google Pixel 2)尝试时,速度非常慢。
特别是,每次我尝试通过触摸屏幕与应用程序交互(例如)导航地图时,我触摸屏幕的时间与应用程序的响应之间存在相当大的滞后。
我什至尝试使用 ChromeDevTools 控制台来检查我的 phone 使用 USB 电缆插入的网络控制台,但无法理解这种缓慢的原因。
一些细节:
- 我使用的是 OpenLayers 版本 6.2.1
- 我正在使用 TypeScript 开发此应用程序
- 我正在使用包裹打包器将其打包到 dist 文件夹中
- 我将构建的文件复制到我的服务器以提供应用程序
我唯一注意到的是构建的文件有奇怪的名字,比如 src.9f4704d2.css
.
我猜这是由捆绑器(包裹)引起的,当我 运行 命令 npm run build
.
但我真的不知道这是否是个问题。
但是,如果有人能帮助我阐明这一点,我将不胜感激。
此外,如果需要,我可以提供更多详细信息,但我的主要问题是我不知道去哪里寻找解决问题的确切方法。
编辑 1
我正在使用 @import
rules in my CSS, and I read here
@import rules can be nested so the browser must load and parse each file in series.
我不知道这是否是问题所在,但我会尝试使用多个 <link>
标签,看看性能是否会好转...
编辑 2
用多个 <link>
标签替换 @import
没有解决问题。
编辑 3(可能发现问题)
好的,我将问题缩小到我正在创建的图层上。
我实际上正在解析三个 WMS url,从中提取每一层,并为每个层添加一个新的 ImageLayer
和一个 ImageWMS
源到地图。
我为加快应用程序所做的第一件事是使用 TileImage
和 TileWMS
而不是 ImageLayer
和 ImageWMS
。
相关代码如下:
import TileLayer from 'ol/layer/Tile';
import TileWMS from 'ol/source/TileWMS';
export class OperationalLayer{
private operationalLayer: TileLayer;
id: String;
constructor(url: string, name: string, id: string) {
const source = new TileWMS({
params: {'LAYERS': name},
url: url,
});
this.id = id;
this.operationalLayer = new TileLayer({
source: source,
})
}
getLayer() {
return this.operationalLayer;
}
}
仍然,应用程序非常滞后。
然后我尝试只使用一个 url 因此我的地图总共只添加了 3 个图层。
现在 运行 可以接受了。
我认为要点是我需要关注将我的图层添加到地图的最佳策略:是同时拥有一个包含所有 WMS 图层的 ImageWMS,还是每层一个 ImageWMS。
后者(我正在做的),让我有可能轻松地转动 on/off 每一层;我猜前者会更快。
或者有没有我没有考虑过的替代方案?
您应该在您的页面上使用 viewport 元数据。
类似于:
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
这将固定页面大小并防止调整整个页面的大小。
这也将减少页面大小和视口中处理的像素。
您还可以查看 meta for mobile webapp 来增强您的应用,例如 web-app-capable
标签。
尝试为您的地图和菜单栏(以及可能覆盖地图的所有页面)使用固定位置以增强渲染效果。
使用 TileWMS:切片将被缓存并且不会在每次移动时请求(仅请求新切片)。层定义中还有一个 hdpi
选项,可以使图像更精细但会放大 canvas 尺寸(和绘图操作),尝试将其设置为 false 并查看结果以做出选择。
我知道这听起来像是一个典型的问题,应该关闭,但我碰壁了,不知道去哪里寻找解决方案,所以希望我能提供足够的细节来解决这个问题SO 可接受的问题。
我正在开发一个可以访问的 OpenLayers Web 应用程序 here。
它的源代码在this github repo.
如果你在电脑上试用该应用程序,用户体验应该没问题(至少,这是我个人的体验)。
但是,当我从我的移动浏览器(Chrome,我的 phone 是 Google Pixel 2)尝试时,速度非常慢。
特别是,每次我尝试通过触摸屏幕与应用程序交互(例如)导航地图时,我触摸屏幕的时间与应用程序的响应之间存在相当大的滞后。
我什至尝试使用 ChromeDevTools 控制台来检查我的 phone 使用 USB 电缆插入的网络控制台,但无法理解这种缓慢的原因。
一些细节:
- 我使用的是 OpenLayers 版本 6.2.1
- 我正在使用 TypeScript 开发此应用程序
- 我正在使用包裹打包器将其打包到 dist 文件夹中
- 我将构建的文件复制到我的服务器以提供应用程序
我唯一注意到的是构建的文件有奇怪的名字,比如 src.9f4704d2.css
.
我猜这是由捆绑器(包裹)引起的,当我 运行 命令 npm run build
.
但我真的不知道这是否是个问题。
但是,如果有人能帮助我阐明这一点,我将不胜感激。 此外,如果需要,我可以提供更多详细信息,但我的主要问题是我不知道去哪里寻找解决问题的确切方法。
编辑 1
我正在使用 @import
rules in my CSS, and I read here
@import rules can be nested so the browser must load and parse each file in series.
我不知道这是否是问题所在,但我会尝试使用多个 <link>
标签,看看性能是否会好转...
编辑 2
用多个 <link>
标签替换 @import
没有解决问题。
编辑 3(可能发现问题)
好的,我将问题缩小到我正在创建的图层上。
我实际上正在解析三个 WMS url,从中提取每一层,并为每个层添加一个新的 ImageLayer
和一个 ImageWMS
源到地图。
我为加快应用程序所做的第一件事是使用 TileImage
和 TileWMS
而不是 ImageLayer
和 ImageWMS
。
相关代码如下:
import TileLayer from 'ol/layer/Tile';
import TileWMS from 'ol/source/TileWMS';
export class OperationalLayer{
private operationalLayer: TileLayer;
id: String;
constructor(url: string, name: string, id: string) {
const source = new TileWMS({
params: {'LAYERS': name},
url: url,
});
this.id = id;
this.operationalLayer = new TileLayer({
source: source,
})
}
getLayer() {
return this.operationalLayer;
}
}
仍然,应用程序非常滞后。
然后我尝试只使用一个 url 因此我的地图总共只添加了 3 个图层。
现在 运行 可以接受了。
我认为要点是我需要关注将我的图层添加到地图的最佳策略:是同时拥有一个包含所有 WMS 图层的 ImageWMS,还是每层一个 ImageWMS。
后者(我正在做的),让我有可能轻松地转动 on/off 每一层;我猜前者会更快。
或者有没有我没有考虑过的替代方案?
您应该在您的页面上使用 viewport 元数据。
类似于:
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
这将固定页面大小并防止调整整个页面的大小。 这也将减少页面大小和视口中处理的像素。
您还可以查看 meta for mobile webapp 来增强您的应用,例如 web-app-capable
标签。
尝试为您的地图和菜单栏(以及可能覆盖地图的所有页面)使用固定位置以增强渲染效果。
使用 TileWMS:切片将被缓存并且不会在每次移动时请求(仅请求新切片)。层定义中还有一个 hdpi
选项,可以使图像更精细但会放大 canvas 尺寸(和绘图操作),尝试将其设置为 false 并查看结果以做出选择。