Utilizing Web Worker threads to enhance performance in Google Maps

Currently, I am experimenting with web worker threads to retrieve directions between various pairs of locations simultaneously and save the data in a file at the end. The process worked smoothly when attempted sequentially. I am using npm live-server to showcase the webpage. However, the browser abruptly closes the page right after loading, and I am unable to view the rendered content or check the console for any potential errors. When I include 'async defer' in the script tag with the Google API in index.html, it throws an error stating "UncaughtReferenceError: google is not defined." I appreciate any help or insights on this matter!

Let me share my index.html with you:

<!DOCTYPE html>
<html>
<head>
   <title>Simple Map</title>
   <meta name="viewport" content="initial-scale=1.0">
   <meta charset="utf-8">
   <style>
       #map {
           height: 100%;
           width: 100%;
       }
       html, body {
           height: 100%;
           margin: 0;
           padding: 0;
       }
       panel {
           display: block;
       }
   </style>
   </head>
   <body>
       <panel></panel>
       <div id="map"></div>
       <script src=locations.js></script>
       <script src='main.js'></script>
       <script src='worker.js'></script>
       <script src="https://maps.googleapis.com/maps/api/js?key=<API-KEY>&callback=initMap"></script>
   </body>
</html>

Now, let's take a look at my main.js:

let worker = new Worker('worker.js');
worker.onmessage = function(info) {
    output += info.data;
};

const container = document.querySelector('panel');
let output = ""

function initMap() {
    locations.forEach( spot => {
        worker.postMessage(spot);
    });

    download("data.txt", output, 'text/plain');
    console.log("Output: " + output);
}

function download(name, text, type) {
    const file = new Blob([text], {type: type});
    const atag = '<a href="' + URL.createObjectURL(file) + '" download="' + name + '">Download</a>';
    container.insertAdjacentHTML('afterbegin', atag);
}

Finally, let's go through the worker.js:

let directionsService;
let directionsDisplay;
let map;
self.addEventListener('message', (e) => {
    directionsService = new google.maps.DirectionsService();
    directionsDisplay = new google.maps.DirectionsRenderer();
    const mapOptions = {
        center: {lat: 30, lng: -90},
        zoom: 6
    }
    map = new google.maps.Map(document.getElementById('map'), mapOptions);
    directionsDisplay.setMap(map);
    let request = {
        origin: 'New Orleans, LA',
        destination: e.data,
        travelMode: 'DRIVING',
        provideRouteAlternatives: false,
        drivingOptions: {
            departureTime: new Date('September 7, 2018 15:00:00'),
            trafficModel: 'pessimistic'
        },
        unitSystem: google.maps.UnitSystem.IMPERIAL
    };

    directionsService.route(request, (result, status) => {
        if (status == 'OVER_QUERY_LIMIT') {
            console.log('over');
        }
        if (status == 'INVALID_REQUEST'){
            console.log('other status')
        }
        if (status == 'OK') {
            var data = result["routes"][0].legs[0];
            postmessage(e.data + ", " + data["distance"].text + ", " + data["duration"].text + "\n");
            directionsDisplay.setDirections(result);
            console.log(result);
        }  
   });
   self.close();
});

Answer №1

When it comes to Javascript, web workers have their own scope. This means that any scripts loaded within the scope of a web page will not be accessible in the scope of a web worker.

Typically, the importScripts method is used to load a script in a web worker. However, this won't work if you also need to access the DOM within the web worker. This is not allowed for various reasons, including the risk of concurrent access to a data structure that is not thread-safe.

Upon reviewing your code, it seems like using a web worker for route calculation may not be necessary. It is likely that the actual routing is handled on Google's servers and would be asynchronous, meaning it wouldn't block the UI of your web page.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Comparing two inherited classes in Typescript: A step-by-step guide

Let's say we have two classes: Animal and Dog. The Dog class is a subclass of the Animal class. I am trying to determine the types of these objects. How can I accomplish this task? class Animal {} class Dog extends Animal {} //The object can be of ...

Utilizing javascript to reverse an array and seamlessly filling in the missing elements

Consider an array containing data with increasing percentage values and some missing entries. For instance: { "months": 11, "factor": 1.31, "upperMonths": 10.5, "lowerMonths": 11.49, "limit": 20, "percentage": 8 }, { "mont ...

What methods can be used to reveal the true value of data that has been encrypted?

Is it possible to retrieve the original value of data that has been hashed? Can the hashcode be reversed to reveal the real value of the data? String ida = new String(txtID.getText().toString()); int idb = ida.hashCode(); codeD.setText("result: " + ida) ...

Executing a function with a click, then undoing it with a second click

My goal is to trigger an animation that involves text sliding off the screen only when the burger icon is clicked, rather than loading immediately upon refreshing the page. The desired behavior includes activating the function on the initial click and then ...

Issue: Unable to locate the 'stream/web' module while attempting to execute 'npm start' for a Next.js application, even though the Node version is correct

When I attempted to set up a new application using npm create next-app --typescript, everything seemed to be going smoothly. However, upon trying to start the project with npm start, an error message popped up stating "Error: Cannot find module 'strea ...

Retrieving the previous value using JQuery's onChange event

Is there a way to retrieve the initial quantity value before it is changed with the onChange function in this code snippet? I'm encountering issues with the CSS while using this setup for an input box. You can view the problematic CSS here. Updating ...

How can I display a Bootstrap modal in Ember.js after rendering it in an outlet?

I'm facing a challenge in my Ember.js application where I need to trigger the opening of a Bootstrap modal from my ApplicationRoute upon calling the openModal action. This is what my ApplicationRoute looks like: module.exports = Em.Route.extend({ ...

NPM is currently malfunctioning and displaying the following error message: npm ERR! 404

When running npm update -g, the following error occurs: npm ERR! code E404 npm ERR! 404 Not found : default-html-example npm ERR! 404 npm ERR! 404 'default-html-example' is not in the npm registry. npm ERR! 404 You should bug the author to publi ...

Guide on implementing vuechartkick in a Nuxt.js project

In the directory /plugin/vue-chartkick, I created a vuechartkick plugin. import Vue from 'vue' import Chartkick from 'vue-chartkick' import Chart from 'chart.js' Vue.use(Chartkick.use(Chart)) This is the nuxt template sectio ...

Creating a personalized jQuery AJAX system

Seeking to extract only the ajax functionality from jQuery, I am facing a minor dilemma. Here's the situation: I have incorporated web workers for the ajax call, which necessitates removing the core.js components. In my project, another library is c ...

Difficulty with Angular's Interpolation and incorporating elements

I've encountered an issue with String Interpolation while following an Angular course. In my server.component.ts file, I've implemented the same code as shown by the teacher in the course: import { Component } from "@angular/core"; @Component ( ...

Tips for styling cells in a certain column of an ng-repeat table

I am currently facing an issue with a table I have created where the last column is overflowing off the page. Despite being just one line of text, it extends beyond the right edge of the page without being visible or scrollable. The table is built using th ...

Setting up TextBelt on my personal server

I'm looking to set up TextBelt, the open source cURL SMS API, on my Amazon EC2 web server in order to send text messages. However, I'm facing some challenges with the installation process. After cloning all the files into a directory named /var/ ...

Unable to retrieve options from a particular select box

Utilizing cheerio and nodejs to scrape all the countries listed on a website, I have implemented the following code: const rp = require('request-promise'); const cheerio = require('cheerio'); const options = { uri: 'https://u ...

Tips for referencing a function declared within a prototype

I have been attempting to enhance a web page by adding functionality using a jquery library that lacks documentation. The problem I am encountering is primarily due to my lack of understanding of the jquery plugin model and/or the inner workings of javascr ...

AngularJS - the element of surprise in execution sequence

Encountering a puzzling issue that exclusively affects Internet Explorer (any version) and not Chrome. An "items" array is stored within the "doc" object. Users have the capability to edit items, which essentially deletes the item but retains its content ...

Bringing a module into Vue framework and transferring information

I'm currently working on a Nuxt project that includes a component. The component can be found in components/Boxes.vue: <template> <b-container> <b-row> <b-col v-for="box in boxes" v-bind:key="box"> < ...

Using `await` inside an if block does not change the type of this expression

Within my code, I have an array containing different user names. My goal is to loop through each name, verify if the user exists in the database, and then create the user if necessary. However, my linter keeps flagging a message stating 'await' h ...

Having trouble with AJAX calling an ASP.NET web method

When attempting to call an asp.net web method in my ajax request, the defined web method is structured like this: [WebMethod()] public static int DropDownIndexChanged(string selectedText) { int a = 5; // This is just for testing purposes return a; } ...

What is the reasoning behind AngularJS 2 HTTP Post only allowing string data as input?

Can someone explain to me why the HTTP Post method in AngularJS 2 (2.0.0-beta.13) only accepts string data as body, unlike in AngularJS 1 where it can accept a JavaScript object? AngularJS-1: $http.post(someUrl,someObject) AngularJS-2: http.post(someUr ...