From 8b95ade0be3162ca4232f598ab48967cc6a01d4b Mon Sep 17 00:00:00 2001 From: ReiMerc Date: Thu, 9 Feb 2023 15:02:26 +0100 Subject: [PATCH] Optimize amount of API calls --- frontend/src/Throttler.ts | 20 ++++++++----- frontend/src/main.ts | 63 +++++++++++++++++++++------------------ frontend/style.css | 1 + 3 files changed, 48 insertions(+), 36 deletions(-) diff --git a/frontend/src/Throttler.ts b/frontend/src/Throttler.ts index c55e284..d168c7b 100644 --- a/frontend/src/Throttler.ts +++ b/frontend/src/Throttler.ts @@ -1,17 +1,23 @@ export class Throttler { private hasBeenCalledWithinTime = false; - private lastCallFunc: (() => any) | null = null; + private lastCallFunc: (() => Promise) | null = null; + private timeout: int | null = null; public constructor(private minimumTimeBetweenCall: number) {} - public call(func: () => any) { + public async call(func: () => any) { this.lastCallFunc = func; - if (this.hasBeenCalledWithinTime) return; - this.hasBeenCalledWithinTime = true; - func(); - setTimeout(() => { - this.hasBeenCalledWithinTime = false; + + if (this.timeout) clearTimeout(this.timeout); + this.timeout = setTimeout(() => { if (this.lastCallFunc) this.lastCallFunc(); }, this.minimumTimeBetweenCall); + + if (this.hasBeenCalledWithinTime) return; + + this.hasBeenCalledWithinTime = true; + await func(); + + setTimeout(() => this.hasBeenCalledWithinTime = false, this.minimumTimeBetweenCall); } } diff --git a/frontend/src/main.ts b/frontend/src/main.ts index bbcd96e..51764f4 100644 --- a/frontend/src/main.ts +++ b/frontend/src/main.ts @@ -38,6 +38,28 @@ async function fetchZipCode({ .catch(() => null as never); } +let currentBoundary; +async function fetchAndDisplayZipCode(coords: Coordinate) { + if (currentBoundary && + coords.longitude > currentBoundary[0] && + coords.latitude > currentBoundary[1] && + coords.longitude < currentBoundary[2] && + coords.latitude < currentBoundary[3] + ) return; + + const response = await fetchZipCode(coords); + + currentBoundary = response.bbox; + + displayZipCode( + document.getElementById("zip-code")!, + response.nr, + response.navn, + response.visueltcenter ? { longitude: response.visueltcenter[0], latitude: response.visueltcenter[1] } : null, + response.bbox ? { x1: response.bbox[0], y1: response.bbox[1], x2: response.bbox[2], y2: response.bbox[3] } : null, + ); +} + function displayMousePosition(element: HTMLParagraphElement, mouse: Position) { element.innerHTML = `Mouse position: (${mouse.x}px, ${mouse.y}px)`; } @@ -63,9 +85,11 @@ function displayZipCode( tooltip.setText(zipCode ? `${zipCode} ${name}` : ""); const dot = document.getElementById("dot")!; + const boundaryElem = document.getElementById("boundary")!; - if (!center) { + if (!center || !boundary) { dot.style.display = "none"; + boundaryElem.style.display = "none"; return; } @@ -83,12 +107,10 @@ function displayZipCode( dot.style.top = position.y + rect.top + document.documentElement.scrollTop + "px"; // Draw boundary - if (!boundary) return; - const bottomleft = convertCoordinateToPixels({ longitude: boundary.x1, latitude: boundary.y1 }, mapSize); const topright = convertCoordinateToPixels({ longitude: boundary.x2, latitude: boundary.y2 }, mapSize); - const boundaryElem = document.getElementById("boundary")!; + boundaryElem.style.display = "block"; boundaryElem.style.left = bottomleft.x + rect.left + "px"; boundaryElem.style.top = topright.y + rect.top + document.documentElement.scrollTop + "px"; boundaryElem.style.width = topright.x - bottomleft.x + "px"; @@ -106,52 +128,35 @@ function setupMap( mapImg.onmousemove = async (event: MouseEvent) => { const mousePosition: Position = { x: event.offsetX, y: event.offsetY }; displayMousePosition(mousePositionElement, mousePosition); + const mapSize: Size = { width: mapImg.clientWidth, height: mapImg.clientHeight, }; + const coords = convertPixelsToCoordinate(mousePosition, mapSize); displayCoords(coordsElement, coords); - fetcher.call(async () => { - const response = await fetchZipCode(coords); - displayZipCode( - zipCodeElement, - response.nr, - response.navn, - response.visueltcenter ? { longitude: response.visueltcenter[0], latitude: response.visueltcenter[1] } : null, - response.bbox ? { x1: response.bbox[0], y1: response.bbox[1], x2: response.bbox[2], y2: response.bbox[3] } : null, - ); - }); + + fetcher.call(async () => await fetchAndDisplayZipCode(coords)); }; mapImg.onmouseup = async (event: MouseEvent) => { const mousePosition: Position = { x: event.offsetX, y: event.offsetY }; displayMousePosition(mousePositionElement, mousePosition); + const mapSize: Size = { width: mapImg.clientWidth, height: mapImg.clientHeight, }; + const coords = convertPixelsToCoordinate(mousePosition, mapSize); displayCoords(coordsElement, coords); - fetcher.call(async () => { - const response = await fetchZipCode(coords); - displayZipCode( - zipCodeElement, - response.nr, - response.navn, - response.visueltcenter ? { longitude: response.visueltcenter[0], latitude: response.visueltcenter[1] } : null, - response.bbox ? { x1: response.bbox[0], y1: response.bbox[1], x2: response.bbox[2], y2: response.bbox[3] } : null, - ); - }); + fetcher.call(async () => await fetchAndDisplayZipCode(coords)); } mapImg.onmouseleave = (_event: MouseEvent) => { - document.getElementById("dot")!.style.display = "none"; - [mousePositionElement, coordsElement].forEach( - (e) => (e.innerHTML = ""), - ); - zipCodeElement.innerHTML = "Postnummer ikke fundet"; + displayZipCode(zipCodeElement, null, null, null, null); }; } diff --git a/frontend/style.css b/frontend/style.css index 03573b3..b1e2775 100644 --- a/frontend/style.css +++ b/frontend/style.css @@ -194,6 +194,7 @@ code { position: absolute; display: none; z-index: 2; + pointer-events: none; } #tooltip {