The use of ngx-pica Image resizer in Angular 5 can cause the user interface to become

I am currently working on implementing an image upload feature for my angular 5 website. I have integrated ngx-Pica for client-side image resizing, but I am facing challenges with the UI freezing during the resize process. I would greatly appreciate any suggestions or ideas on how to prevent this freeze.

The sizes of the images being uploaded are as follows: (all added simultaneously)

  • 2.6mb
  • 1.7mb
  • 3.46mb

I'm puzzled about what is causing this issue and I welcome any assistance in resolving it.

Approaches I've experimented with

I attempted removing

changeDetectorRef.detectChanges()
to determine if it would eliminate the freezing, but unfortunately, it did not

The freezing problem disappears when uploading images without resizing them (by excluding the call to this._ngxPicaService.resizeImage)

I went through the source code thoroughly but couldn't find any glaringly obvious issues

I aim to provide users with the option to upload images of any size without restrictions, but a frozen UI is unacceptable

import { Component, ViewEncapsulation, ChangeDetectorRef } from '@angular/core';

import { NgxPicaService, NgxPicaErrorInterface, NgxPicaResizeOptionsInterface, NgxPicaImageService } from 'ngx-pica';
import { AspectRatioOptions } from 'ngx-pica/src/ngx-pica-resize-options.interface';

@Component({
  selector: 'az-multiple-image-uploader',
  encapsulation: ViewEncapsulation.None,
  templateUrl: './multiple-image-uploader.component.html',
  styleUrls: ['./multiple-image-uploader.component.scss']
})
export class MultipleImageUploaderComponent { 
    public images: File[] = [];

    constructor(
        private _changeDetectorRef: ChangeDetectorRef, 
        private _ngxPicaService: NgxPicaService, 
        private _ngxPicaImageService: NgxPicaImageService 
    ) { }    

    fileChange(input){
        this.handleFiles(input.files);
    }

    private addLoadingAnimations(numberToAdd: number): void {
        var spinner = require("assets/img/Spinner.svg");

        for(var i =0; i < numberToAdd; i++)
        {
            this.images.push(spinner);
        }
    }

    public handleFiles(files: any) {
        var listLength = this.images.length;
        this.addLoadingAnimations(files.length);

        var width = 1024;
        var height = 683;

        for(var index = 0; index < files.length; index++){
            this._ngxPicaService.resizeImage(files[index], width, height, new ImageResizeOptions())
                .subscribe((imageResized: File) => {
                    let reader: FileReader = new FileReader();

                    reader.addEventListener('load', (event: any) => {
                        this.images.splice(listLength, 1);
                        this.images[listLength] = event.target.result;
                        listLength += 1;
                        this._changeDetectorRef.detectChanges();
                    }, false);

                    reader.readAsDataURL(imageResized);

            }, (err: NgxPicaErrorInterface) => {
                throw err.err;
            });
        }
    }

    removeImage(index):void{
        this.images.splice(index, 1);
    }
}

export class ImageResizeOptions implements NgxPicaResizeOptionsInterface
{
  aspectRatio = new ImageAspectRatioOptions(true);
}

export class ImageAspectRatioOptions implements AspectRatioOptions {
  keepAspectRatio: boolean;
  forceMinDimensions?: boolean;

  constructor(keepAspectRatio: boolean, forceMinDimensions?: boolean) {
    this.keepAspectRatio = keepAspectRatio;
    this.forceMinDimensions = forceMinDimensions;
  }
}


<div class="col-8 mx-auto">
    <input type="file" multiple (change)="fileChange(input)" #input class="m-img-upload-btn"/>
    <button class="btn btn-success btn-block" type="button">
        <i class="fa fa-upload"></i> Images...
    </button>
</div>

<div class="card images-container">
    <div *ngFor="let image of images; let i=index;" class="m-image-wrapper">
        <i class="fa fa-times m-delete-img" (click)="removeImage(i)"></i>
        <img [src]="image"> 
    </div> 
</div>

Answer №1

To prevent a user interface from freezing, the solution lies in utilizing Web workers.

I encountered a situation where a specific task was time-consuming and any prolonged computation would result in the UI becoming unresponsive.

For developers working with Angular, there is a convenient tool known as

https://www.npmjs.com/package/angular2-web-worker
that facilitates the implementation of web workers for improved performance.

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

Unexpected actions of mat-select within an Angular application

I have encountered a perplexing issue while incorporating mat-select into my Angular project. Here is the code snippet that I am using: <div class="col-md-6"> <mat-form-field> <mat-select placeholder="Select Location" name="locati ...

Best practices for securely storing access tokens in React's memory

I'm on a quest to find a secure and efficient way to store my access token in a React application. First and foremost, I have ruled out using local storage. I don't see the need to persist the access token since I can easily refresh it when nece ...

The element 'x' is implicitly bound with a type of 'any'

I've been exploring the world of Nextjs and TypeScript in an attempt to create a Navbar based on a tutorial I found (). Although I've managed to get the menu items working locally and have implemented the underline animation that follows the mou ...

Enhanced hierarchical organization of trees

I came across this code snippet: class Category { constructor( readonly _title: string, ) { } get title() { return this._title } } const categories = { get pets() { const pets = new Category('Pets') return { ge ...

Adding a record to a multi-dimensional array in TypeScript, for example with an Array of numbers, pairs of numbers, and pairs of strings and numbers

In my angular component file, I am utilizing 'angular-highcharts' to create a high chart for the HTML view page. To do this, I have defined an array as shown below in the component.ts file to store and organize the data. public myData : Array< ...

Preventing special characters in an input field using Angular

I am trying to ensure that an input field is not left blank and does not include any special characters. My current validation method looks like this: if (value === '' || !value.trim()) { this.invalidNameFeedback = 'This field cannot ...

Passing variables between parent and child components in Angular 6

I'm struggling to find a clear example of a variable that can serve as both an "input" and "output". Currently, I have multiple children receiving input from the parent, but I need a way to modify these values and have the changes reflected back in t ...

Error in Angular Material: SassError - The CSS after "@include mat" is invalid. Expected 1 selector or at-rule, but found ".core();"

My Angular 11 project was running smoothly with Angular Material version 11 until I decided to update everything to Angular 12, including Material. However, after the update, the styles.scss file that comes with Material started throwing errors. The comple ...

The data type 'unknown' cannot be assigned to the type 'any[]', 'Iterable<any>', or (Iterable<any> & any[])

I have been working on creating a custom search filter in my Angular project, and it was functioning properly. However, I encountered an error in my Visual Studio Code. In my previous project, everything was working fine until I updated my CLI, which resul ...

Utilize Angular 2 to associate form context with ngTemplateOutlet

Currently, I am working on defining a Component that consists of a dynamic Form using ReactiveForms. The goal is to allow users to add or delete Controls within the form. These Controls can vary in structure and need to be defined externally to the Compone ...

Received Angular Error: Attempting to differentiate '[object Object]'. Permissible are only arrays and iterables

I've encountered an error while working on my front-end in Angular with Node.js as the backend. I'm struggling to identify the cause of this issue. Here is a snippet of my code. country.ts export class Country { id?: string; name?: string; ...

Troubleshooting: Issues with Angular 2's default routing system

My Angular 4 app's default route isn't functioning properly. Could it be conflicting with my express routes? Interestingly, the wildcard route seems to be working fine. I'm puzzled as to what the issue might be. Here are my Angular routes: ...

Failure to Generate stats.json File When Building Angular 6 with --stats-json Flag

Currently, I am facing an issue with generating the stats.json file for my Angular 6 application. Despite trying a few different methods, the file is simply not being created. It seems that my system specifically requires "npm run" before every Angular CLI ...

Troubleshooting Karma: Strategies for resolving a RangeError related to exceeding the maximum call stack size

I am currently working on an Angular application and utilizing Jasmine with Karma for my unit testing. During testing one of my component specs, I encountered the following error: Uncaught RangeError: Maximum call stack size exceeded. I am struggling to i ...

Generate incorrect JSON for a negative test in TypeScript

Struggling with navigating TS (amazing) static typing to generate invalid data for a negative test scenario. I am currently working on resolving an issue where the client may pass invalid JSON (double quotes within the value). I believe I have fixed the i ...

Problem with setting up and using libraries in Angular 10 installation

Currently, my Angular App is at version 10.4 and I am facing issues when trying to integrate libraries like ngx-dropzone, ngx-file-drag-drop, ng2pdf viewer, or any other library. These integrations are throwing errors during compilation. Below are the spe ...

What is the best way to observe a function and provide a simulated result from within a different function using jasmine?

Query: How can I access the reference of getWindowSize within getBreakpoint() to perform spying on it? Additionally, how can I use callFake to return mock data? media-query.ts export const widthBasedBreakpoints: Array<number> = [ 576, 768, 99 ...

Can an Angular 2 module export an interface?

While attempting to export an interface in a NgModule-declaration, I encountered an error message in my editor (Visual Studio Code) stating: [ts] 'MyInterface' only refers to a type, but is being used as a value here. Below is the code snippet c ...

Receiving an error response from the server upon subscribing to an Angular service (2/4/5/6)

I'm currently facing an issue with verifying my OTP. Depending on the response received from the server (whether it's due to OTP mismatch or OTP expiration), I need to display the appropriate error message. However, I am struggling to figure out ...

Error in Ionic 3 Framework: Typescript Error - The function was expecting anywhere between 0 to 2 arguments, but received 3 instead

I am currently working on an http request using the Ionic Native HTTP plugin, but I encountered the following error: Error [ts] Expected 0-2 arguments, but got 3. Here is the specific Http call that I am trying to make: getAcknowledgmentRequest(ssoId, ...