Skip to content

Commit 8708a34

Browse files
authored
reduce OpenLayers API calls (#364)
* avoid calling OpenLayers when possible * add more debug * ignore the size warnings
1 parent c227e35 commit 8708a34

File tree

6 files changed

+48
-13
lines changed

6 files changed

+48
-13
lines changed

examples/Spinner.tsx

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,19 @@ import spinnerIcon from './svg/pacman.svg';
55
import 'ol/ol.css';
66

77
export default function Layers(): JSX.Element {
8-
const [loading, setLoading] = React.useState(0);
8+
const [loading, setLoading] = React.useState(true);
9+
const showSpinner = React.useCallback(() => setLoading(true), [setLoading]);
10+
const hideSpinner = React.useCallback(() => setLoading(false), [setLoading]);
11+
const origin = React.useMemo(() => ({center: fromLonLat([2.364, 48.82]), zoom: 4}), []);
912
return (
10-
<React.Fragment>
11-
<RMap className='example-map' initial={{center: fromLonLat([2.364, 48.82]), zoom: 4}}>
13+
<>
14+
<RMap
15+
className='example-map'
16+
initial={origin}
17+
//onLoadStart={showSpinner}
18+
onLoadEnd={hideSpinner}
19+
>
1220
<RLayerTile
13-
onTileLoadStart={() => setLoading((loading) => loading + 1)}
14-
onTileLoadEnd={() => setLoading((loading) => loading - 1)}
1521
url='https://{a-c}.tile.opentopomap.org/{z}/{x}/{y}.png'
1622
attributions='Kartendaten: © OpenStreetMap-Mitwirkende, SRTM | Kartendarstellung: © OpenTopoMap (CC-BY-SA)'
1723
/>
@@ -20,6 +26,6 @@ export default function Layers(): JSX.Element {
2026
<img src={spinnerIcon} alt='spinner' />
2127
<strong>{loading} Loading...</strong>
2228
</div>
23-
</React.Fragment>
29+
</>
2430
);
2531
}

src/REvent.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,10 @@ export class RlayersBase<P, S> extends React.PureComponent<P, S> {
7171
debug('installing handler', this, p, newEvents[p]);
7272
const prop = this.getHandlerProp(p);
7373
if (!prop) throw new Error('Internal error');
74-
handlers[p] = (e: unknown) => this.props[prop].call(this, e);
74+
handlers[p] = (e: unknown) => {
75+
debug('handling event', e, this, this.props[prop]);
76+
return this.props[prop].call(this, e);
77+
};
7578
for (const source of eventSources) source.on(p as OLEvent, handlers[p]);
7679
this.incrementHandlers(p);
7780
}

src/RMap.tsx

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {ProjectionLike} from 'ol/proj';
88

99
import {RContext} from './context';
1010
import {RlayersBase} from './REvent';
11+
import debug from './debug';
1112

1213
/** Center and zoom level */
1314
export type RView = {
@@ -78,6 +79,12 @@ export interface RMapProps extends PropsWithChildren<unknown> {
7879
onRenderComplete?: (this: RMap, e: RenderEvent) => boolean | void;
7980
/** Called on every change */
8081
onChange?: (this: RMap, e: BaseEvent) => void;
82+
/** Called when the map starts loading */
83+
onLoadStart?: (this: RMap, e: MapEvent) => void;
84+
/** Called when the map has completely loaded */
85+
onLoadEnd?: (this: RMap, e: MapEvent) => void;
86+
/** Generic error handled */
87+
onError?: (this: RMap, e: BaseEvent) => void;
8188
/** A set of properties that can be accessed later by .get()/.getProperties() */
8289
properties?: Record<string, unknown>;
8390
/** Extent of the map, cannot be dynamically modified
@@ -151,7 +158,10 @@ export default class RMap extends RlayersBase<RMapProps, Record<string, never>>
151158

152159
componentDidMount(): void {
153160
super.componentDidMount();
154-
this.ol.setTarget(this.target.current);
161+
if (this.ol.getTarget() !== this.target.current) {
162+
debug('Setting target', this, this.target.current);
163+
this.ol.setTarget(this.target.current);
164+
}
155165
}
156166

157167
private updateView = (e: MapEvent): void => {
@@ -169,9 +179,13 @@ export default class RMap extends RlayersBase<RMapProps, Record<string, never>>
169179
const view = this.ol.getView();
170180
for (const p of ['minZoom', 'maxZoom', 'constrainResolution']) {
171181
const m = p.charAt(0).toUpperCase() + p.substring(1);
172-
if (!prevProps || this.props[p] !== prevProps[p]) view['set' + m](this.props[p]);
182+
if (this.props?.[p] !== prevProps?.[p]) {
183+
debug('Setting', this, m, this.props[p]);
184+
view['set' + m](this.props[p]);
185+
}
173186
}
174187
if (this.props.view) {
188+
debug('Setting view', this, this.props.view);
175189
view.setCenter(this.props.view[0].center);
176190

177191
if (this.props.view[0].resolution === undefined) view.setZoom(this.props.view[0].zoom);

src/layer/RLayer.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,15 @@ export default class RLayer<P extends RLayerProps> extends RlayersBase<P, Record
6666
'maxZoom'
6767
]) {
6868
const m = p.charAt(0).toUpperCase() + p.substring(1);
69-
if (this.props[p] !== (prevProps && prevProps[p])) this.ol['set' + m](this.props[p]);
69+
if (this.props?.[p] !== prevProps?.[p]) {
70+
debug('Setting', this, m, this.props[p]);
71+
this.ol['set' + m](this.props[p]);
72+
}
7073
}
71-
if (this.source && this.props.attributions)
74+
if (this.source && this.props.attributions !== prevProps?.attributions) {
75+
debug('Setting attributions', this);
7276
this.source.setAttributions(this.props.attributions);
77+
}
7378
if (this.props.properties) this.ol.setProperties(this.props.properties);
7479
}
7580

src/layer/RLayerTile.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {XYZ} from 'ol/source';
55
import TileGrid from 'ol/tilegrid/TileGrid';
66

77
import {default as RLayerRaster, RLayerRasterProps} from './RLayerRaster';
8+
import debug from '../debug';
89

910
/**
1011
* @propsfor RLayerTile
@@ -63,6 +64,7 @@ export default class RLayerTile extends RLayerRaster<RLayerTileProps> {
6364
protected refresh(prevProps?: RLayerTileProps): void {
6465
super.refresh(prevProps);
6566
if (prevProps?.tileGrid !== this.props.tileGrid || prevProps?.url !== this.props.url) {
67+
debug('replacing source', this);
6668
this.createSource();
6769
this.ol.setSource(this.source);
6870
this.attachOldEventHandlers(this.source);

webpack.config.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,13 @@ const webpackConfig = (env): webpack.Configuration => {
2323
path: path.join(__dirname, '/docs'),
2424
filename: 'bundle.js'
2525
},
26-
// https://github.com/TypeStrong/ts-loader/issues/751
27-
ignoreWarnings: [{message: /export .* was not found in/}],
26+
ignoreWarnings: [
27+
// https://github.com/TypeStrong/ts-loader/issues/751
28+
{message: /export .* was not found in/},
29+
// OpenLayers + React + rlayers is simply big
30+
{message: /asset size exceeds/},
31+
{message: /recommended size limit/}
32+
],
2833
module: {
2934
rules: [
3035
{

0 commit comments

Comments
 (0)