The Good Tech Companies - How to Speed up Your Angular App With Web Workers
Episode Date: June 26, 2024This story was originally published on HackerNoon at: https://hackernoon.com/how-to-speed-up-your-angular-app-with-web-workers. Learn how to optimize your angular applic...ation by using Web Workers. See more from MESCIUS today. Check more stories related to programming at: https://hackernoon.com/c/programming. You can also check exclusive content about #web-development, #mobile-app-development, #angular-development, #javascript-development, #javascript-tutorial, #web-workers-api, #devops, #good-company, and more. This story was written by: @mesciusinc. Learn more about this writer by checking @mesciusinc's about page, and for more stories, please visit hackernoon.com. Learn how to add your long-running processes to an Angular Web Worker and reap all the benefits of an app that doesn’t freeze.
Transcript
Discussion (0)
This audio is presented by Hacker Noon, where anyone can learn anything about any technology.
How to speed up your Angular app with WebWorkers by MESCIUS Inc.
Why do you need a WebWorker? A WebWorker is a code component for a web application.
It allows the developer to create a new thread of execution for a JavaScript task so it doesn't
interrupt the execution of the main app. At first glance, it may seem that browsers
inherently support threading and that the
developer shouldn't have to do anything special.
Unfortunately, that's not the case.
WebWorkers solve a real concurrency problem.
WebWorkers are a part of the expected functional standards of web browsers, and the the specifications
for them have been written up at the W3C.
The Angular framework has wrapped up web workers for us,
and we can easily add them to our app using the Angular command line interface, CLI.
In this article, we'll first examine some misconceptions about thread concurrency with
JavaScript in the browser. Then, we'll create a functional example demonstrating how easy it is
to implement web workers with Angular, which enables concurrent threading on a website. Isn't JavaScript inherently concurrent? Some developers believe that JavaScript is
inherently concurrent in the browser because when the browser connects to a website and retrieves
the HTML for a page, it can open multiple connections and pull resources
, linked CSS files, linked JavaScript files, and so on, concurrently. It looks like
the browser executes several threads and numerous tasks simultaneously, via context switching.
To the uninitiated web developer, this seems to indicate that the browser can do concurrent work.
However, when it comes to JavaScript, the browser actually only executes one process at a time.
Most modern websites, single-page apps,
SPA, and the more modern progressive web apps, PWA, depend on JavaScript and typically contain
numerous JavaScript modules. However, at any time the web app is running JavaScript,
the browser is limited to a single thread of activity. None of the JavaScript will run
concurrently under normal circumstances.
That means if we have a long-running or process-intensive task defined in 104 JavaScript
modules, the user may experience the app stuttering or seeming to hang. At the same time,
the browser waits for the process to complete before the user interface, UI, can be updated.
This kind of behavior makes users lose confidence in our web apps or spas,
and none of us want that. A web worker for JavaScript concurrency. We'll create an example
page with two panes to enable our web app to run concurrent JavaScript threads. In one pane,
the UI of our application is represented by a grid with circles, which constantly updates the
picture and reacts to mouse clicks. The second pane will host a long running process,
which normally blocks the UI thread and prevents the UI from doing its job.
To make our UI responsive, we'll run our long process in a webworker,
which will execute it on a separate thread and will not block UI logic execution this way.
We'll use Angular as the framework for building the app
because it makes constructing the webworkers a simple one-command task.
Setting up the Angular app To use the Angular CLI, we need to have Node.js
and NPM installed.
Once we've made sure Node and NPM are installed, open a console window.
Then install the Angular CLI via NPM.
This is a one-time thing. Change the directory
to the target directory where we want to create our new app template. Now, we are ready to create
our app. We use the ing new command to da that. We will name our project ing webworker the project
wizard asks if we want to include routing in our project. We do not need routing for this example,
so type n. It will then ask what type
of stylesheet format we want to use. Angular supports using stylesheet processors such as
sass and less, but in this case, we will use simple CSS, so just press enter for the default.
We will then see some create messages as npm pulls the required packages and the CLI creates
the template project. Finally, when it is complete, we get a blinking cursor again at the command line.
At this point, the Angular CLI has created a project and placed it in the ing-webworker folder.
Change the directory to ing-webworker.
The Angular CLI created everything we needed to work on our Angular project,
including installing the Node HTTP server.
That means all we have to do to get the template app started is the following the Angular CLI compiles your
project and starts the Node HTTP server. Now, you can load the app in your browser by pointing it
at the less than RF equals HTTP colon slash slash localhost port 4 2 0 0 target equals underscore blank greater than url our first
angular app from cli when we load the page we see the basic template with the project name at the
top the benefit of running in serve is that any changes made to the code will automatically cause
the site to refresh in the browser making it much easier to see changes take effect. Most of the code we'll
focus on is under the src app directory. App component html contains html for the one component
currently used to display the main page. The component code is represented in the app component
ts typescript file. We will delete the contents of app, component, HTML and add our own layout.
We will create a split page that displays our long-running process values on the left side
and draw some random circles on the right side. This will allow our browser to run two additional
webworker threads that will work independently so you can see Angular webworkers in action.
All the code for the rest of the article can be obtained from the GitHub repository. Here's what the final page will look like while it draws the random circles,
before the long-running process starts. Replace the code in app. Component. HTML with the following
the code download also includes some ID's and CSS classes and associated styles in styles.
CSS, which are used for the very simple formatting of the UI.
So we have two sections, left and right, and other basic styling. The important thing to
notice here is that we've added an Angular event binding, click, to the button. When the user
clicks the button, the long process is started by calling the long loop method found in the
component TypeScript file, app. Comp file app component ts this runs 10 billion iterations
writing to a member variable of our component long process output because we've bound that member
variable in app component html on the text area element the ui will reflect the update each time
the variable is updated the value we set in the h the HTML is where we bind the member variable. Run it,
we'll see that nothing much happens when we click the button, and the end suddenly,
the text area is updated with a bunch of values. If we open the console, we see the values written
there as the code runs. Add a random circle component using the Angular CLI. Next, we'll add
a circle component to draw random circles.
We can do that using the Angular CLI with the following command.
The command created a new folder named Circle and created four new files.
Circle component HTML Circle component spec TS unit component, TS, TypeScript code, circle, component, CSS, styles that will
only be applied to associated HTML for this component. The HTML is straightforward, we just
need the HTML that will represent our component. In our case, this is the component on the right
side of the page, which will display the light green grid and draw the circles. This drawing ISD1 via
the HTML canvas element, we start and stop the drawing of the circles by adding an angular event
binding to grab the mouse down event. If the user clicks inside the canvas area anywhere,
the circles will begin drawing if the process has not already started. If the process is already
started, then the toggle timer method, found in Circle.
Component, TS, clears the grid and stops the drawing of circles.
Toggle timer simply uses set interval to draw a circle in a random location with a randomly
selected color every 100 milliseconds, 10 circles per second. There's more code in Circle.
Component, TS that sets up the canvas element, initializes member variables,
and does the drawing. When added, your code should look like this don't forget to add the
circle component to the index. HTML file when the page loads, the circles will begin drawing.
When we click the, start long process, button, we will see the drawing pause.
That's because all the work is being done on the same thread.
Let's fix that problem by adding a web worker. Adding an Angular web worker. To add a new web worker using the CLI, we simply go to our project folder and execute the following command that last
parameter app is the name of the component that contains our long running process which we will
want to place into our web worker. Angular will add some
code to the app component TS that looks like the following. What does the new code do? We can see
that this code references the new app worker component that the command also added. At this
point, the code 1 ensures that the browser supports web workers, 2 creates a new worker. 3. Posts a message to the worker, found in app.worker.ts. 4. When the worker receives the
hello message, event listener will fire, shown in the following code snippet.
5. When the event listener fires, in app.worker.ts, it will create a response object and post it back
to the caller. Here's the entire contents of app.
Worker.ts We will see messages in the console as a result of these steps,
which will look like the last line in the following console output. That is the console.
Log that occurs in the event handler that was created on the original worker object that tells us that the app. Component posted a message to the app. Worker and the app. Worker replied with
a message of its own.
We want to use the worker to run our long running process on another thread source circle drawing code isn't interrupted.
First, let's move the code involved with our UI elements to a constructor of our app.
Component class.
This allows us to reference the long process output variable now.
With that, we can access that variable, we have worker. On message,
which adds the basic data to the text area instead of writing to the console just as an initial test.
You can see the highlighted text on the left is the received message. L-O-N-G-L-O-O-P in the web
worker we still need to move our long running loop to the web worker to ensure that, when the loop
runs, it will be running on its own thread.
Here's the bulk of the code that we will have in our final app.
Component, ts we moved the worker variable into the class, which is now a member variable.
That way, we can easily reference it anywhere in our app component class.
Next, let's look more closely at how we have defined a message event handler on the worker object with the code in the constructor that code will run when the web worker class found an app worker ts callspost
message data each time the post message method is called the long process output the model bound to
the text area will be updated with the data plus a carriage return n which is simply so each value
will be written on its own line in the text area element
here's all the code found in the actual web worker app worker ts this event handler is fired when the
user clicks the run long process button all the code found in the web worker app worker ts runs
on a new thread that's the value of the web worker its code runs on a separate thread. That's the value of the web worker. Its code runs on a separate thread.
That's why it no longer affects the main thread of the web app. The web worker code is fired when the user clicks the button because we now have the following code in our long loop method.
When the message is posted to the worker, the event listener fires and runs the code from our
original long loop that we placed there. Wrapping up Angular apps with web workers. When you run the
app, you will find that clicking the start long process button no longer causes the circle drawing
to pause. You will also be able to directly interact with the circle drawing canvas component
so that if you click it while long loop is still running, the canvas will be redrawn immediately.
Previously, the app behaved as if it were frozen if you did this. Now, you can add your
long-running processes to an Angular web worker and repel the benefits of an app that doesn't
freeze. If you want to see an example solved with JavaScript web workers, you can see Iton Plunker.
Are you looking for framework-agnostic UI components? MESCI US has a complete set of
JavaScript UI components, including data grids,
charts, gauges, and input controls. We also offer powerful spreadsheet components,
reporting controls, and enhanced presentation views. We have deep support for Angular,
as well as React and Vue, and are dedicated to extending our components for use in modern
JavaScript frameworks. Thank you for listening to this Hackernoon story, read by Artificial Intelligence.
Visit hackernoon.com to read, write, learn and publish.