Reputation: 918
I'm using this component to crop images as part of an ionic/angular8 project, but I'm getting serious performance issues making the app irresponsive at some times, this is only manifesting when running from mobile, the desktop version doesn't show any issues, the crop works just fine.
Doing a performance review in some cases I see these garbage collections; I came from a java world, and GC is always a performance issue, but haven't found much about it, but I don't think its the root of the problem:
Here is another sample, seems to be a delay between the user interacting with the screen, and my inner method getting called, as you can see there's a FunctionCall, but which function.
My general code is almost the same as in the site but I'll share it here:
Html:
<div class="popup-form-container ion-text-center ion-padding">
<image-cropper
[imageChangedEvent]="imageChangedEvent"
[maintainAspectRatio]="true"
[aspectRatio]="4 / 4"
format="png"
(imageCropped)="imageCropped($event)"
(imageLoaded)="imageLoaded()"
(cropperReady)="cropperReady()"
(loadImageFailed)="loadImageFailed()"
></image-cropper>
<ion-button fill="clear" color="danger" (click)="close()">Cancelar</ion-button>
<ion-button color="green" (click)="save()">Guardar</ion-button>
</div>
And here you can see my class, I added a bunch of console logs in the process of finding the issue, and something I've seen is that when the app freezes and stays in the long call, there's no outpu, then out of the souden, lots in a row:
@Component({
selector: 'app-crop-image-popover',
templateUrl: './crop-image-popover.component.html',
styleUrls: ['./crop-image-popover.component.scss',
'../../text-area/text-edit-popover/text-edit-popover.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class CropImagePopoverComponent implements OnInit {
@Input()
imageChangedEvent: any;
private croppedImage: any = '';
private uploader: FileUploader;
private imageUrl: any;
private errors: any;
constructor(private modalCtrl: ModalController,
private commonSrv: CommonService,
protected cloudinary: Cloudinary,
private alertCtrl: AlertController,
private sysParamsSrv: SystemParamsService,
private base64: Base64,
private domSanitizer: DomSanitizer,
private imageCompress: NgxImageCompressService,
private changeDetector: ChangeDetectorRef) {
// Inicializamos el compoente de carga de archivos
}
ngOnInit() {}
imageCropped(event: ImageCroppedEvent) {
console.log('cropped');
this.croppedImage = event.base64;
}
imageLoaded() {
console.log('loaded');
// show cropper
// this.commonSrv.hideSpinner();
}
cropperReady() {
// cropper ready
console.log('ready');
this.commonSrv.hideSpinner();
}
loadImageFailed() {
// show message
console.log('failed');
}
close() {
this.modalCtrl.dismiss();
}
}
I've already tried updating the changeDetection strategy, removed some function calls I had in other pages, and most of the performance recommendations, but I don't seem to find the reason for my current problem
Upvotes: 3
Views: 1574
Reputation: 2046
ngx-image-cropper
, when you change the crop size/position it actually crops the image and is very resource intensive. If you can get away with it, you can only do the crop once by setting autoCrop
to false like so:
<image-cropper
[imageChangedEvent]="imageChangedEvent"
[maintainAspectRatio]="true"
[aspectRatio]="1"
[autoCrop]="false"
format="png"
(imageLoaded)="imageLoaded()"
(cropperReady)="cropperReady()"
(loadImageFailed)="loadImageFailed()"
></image-cropper>
<ion-button fill="clear" color="danger" (click)="close()">Cancelar</ion-button>
<ion-button color="green" (click)="save()">Guardar</ion-button>
Then use the @ViewChild
to get access to the cropper and thus the cropping methods. Here is what that looks like within the typescript file:
@ViewChild(ImageCropperComponent) imageCropper: ImageCropperComponent;
Then, when the user selects to keep the crop, you will need to do something like this:
function save(): void {
const event = this.imageCropper.crop();
this.croppedImage = event.base64;
}
This will fix some performance issues. But do note that it appears that iDevices struggle with handling cropping in the way that ngx-image-cropper
does it. Specifically, if the user uses the camera while uploading an image, the image may require too much memory to convert to a base64 string in the Safari thread - as a result, iDevices can freeze when used normally. Here is one place where this is discussed: https://github.com/Mawi137/ngx-image-cropper/issues/481
Upvotes: 1