diff --git a/plugin-designs/pplr-data-maps/src/utils/pplrData.js b/plugin-designs/pplr-data-maps/src/utils/pplrData.js
index c65c9a130..862cfdd39 100644
--- a/plugin-designs/pplr-data-maps/src/utils/pplrData.js
+++ b/plugin-designs/pplr-data-maps/src/utils/pplrData.js
@@ -104,8 +104,10 @@ export function setProjectionFor(map, name) {
// Verification handle (the gospel-resources __grState contract): what the ACTIVE view's map
// actually did, so a check can assert "loaded" rather than inferring it from missing requests.
// window.__pplrMap() -> { engine, loaded, styleLayers, pplrLayers }
+let _exposedMap = null // whose hook is on window, so releaseMap only clears its own
export function exposeMap(map) {
if (typeof window === 'undefined' || !map) return
+ _exposedMap = map
let loaded = false
map.once('load', () => { loaded = true })
window.__pplrMap = () => {
@@ -123,3 +125,11 @@ export function exposeMap(map) {
}
}
}
+
+// Release the hook on unmount (a closure on window pins the whole app after the view is gone; rega
+// measured ~10 MB per mount). Only if it is still THIS map's: another view may have exposed its own since.
+export function releaseMap(map) {
+ if (typeof window === 'undefined' || !map || _exposedMap !== map) return
+ delete window.__pplrMap
+ _exposedMap = null
+}
diff --git a/plugin-designs/pplr-data-maps/src/views/pplr-coverage.vue b/plugin-designs/pplr-data-maps/src/views/pplr-coverage.vue
index 6936aa2f2..7bea016a9 100644
--- a/plugin-designs/pplr-data-maps/src/views/pplr-coverage.vue
+++ b/plugin-designs/pplr-data-maps/src/views/pplr-coverage.vue
@@ -1,5 +1,5 @@
diff --git a/plugin-designs/pplr-data-maps/src/views/pplr-religion.vue b/plugin-designs/pplr-data-maps/src/views/pplr-religion.vue
index e9a6a4959..99582fc27 100644
--- a/plugin-designs/pplr-data-maps/src/views/pplr-religion.vue
+++ b/plugin-designs/pplr-data-maps/src/views/pplr-religion.vue
@@ -1,5 +1,5 @@