Angular 裁剪图像时出现性能问题
Angular performance issues when cropping image
作为 ionic/angular8 项目的一部分,我正在使用 this component 裁剪图像,但我遇到了严重的性能问题,导致应用程序有时无响应,这仅在 运行 从手机上看,桌面版没有任何问题,裁剪效果很好。
在某些情况下进行性能评估时,我看到了这些垃圾回收;我来自 java 世界,GC 一直是性能问题,但没有找到太多,但我不认为它是问题的根源:
这是另一个示例,似乎是用户与屏幕交互和调用我的内部方法之间的延迟,如您所见,有一个 FunctionCall,但是是哪个函数。
我的通用代码与站点中的代码几乎相同,但我将在此处分享:
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>
这里你可以看到我的class,我在发现问题的过程中添加了一堆控制台日志,我看到的是当应用程序冻结并停留在长时间调用中时,没有outpu,然后出souden,连续很多:
@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();
}
}
我已经尝试更新 changeDetection 策略,删除了我在其他页面中的一些函数调用,以及大部分性能建议,但我似乎没有找到我当前问题的原因
ngx-image-cropper
,当您更改裁剪 size/position 时,它实际上会裁剪图像并且非常耗费资源。如果你能逃脱它,你只能通过将 autoCrop
设置为 false 来裁剪一次,如下所示:
<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>
然后使用 @ViewChild
访问裁剪器和裁剪方法。这是打字稿文件中的内容:
@ViewChild(ImageCropperComponent) imageCropper: ImageCropperComponent;
然后,当用户选择保留裁剪时,您将需要执行如下操作:
function save(): void {
const event = this.imageCropper.crop();
this.croppedImage = event.base64;
}
这将解决一些性能问题。但请注意,iDevice 似乎很难像 ngx-image-cropper
那样处理裁剪。具体来说,如果用户在上传图像时使用相机,图像可能需要太多内存才能在 Safari 线程中转换为 base64 字符串——因此,iDevices 在正常使用时可能会冻结。这是一个讨论这个问题的地方:https://github.com/Mawi137/ngx-image-cropper/issues/481
作为 ionic/angular8 项目的一部分,我正在使用 this component 裁剪图像,但我遇到了严重的性能问题,导致应用程序有时无响应,这仅在 运行 从手机上看,桌面版没有任何问题,裁剪效果很好。
在某些情况下进行性能评估时,我看到了这些垃圾回收;我来自 java 世界,GC 一直是性能问题,但没有找到太多,但我不认为它是问题的根源:
这是另一个示例,似乎是用户与屏幕交互和调用我的内部方法之间的延迟,如您所见,有一个 FunctionCall,但是是哪个函数。
我的通用代码与站点中的代码几乎相同,但我将在此处分享:
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>
这里你可以看到我的class,我在发现问题的过程中添加了一堆控制台日志,我看到的是当应用程序冻结并停留在长时间调用中时,没有outpu,然后出souden,连续很多:
@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();
}
}
我已经尝试更新 changeDetection 策略,删除了我在其他页面中的一些函数调用,以及大部分性能建议,但我似乎没有找到我当前问题的原因
ngx-image-cropper
,当您更改裁剪 size/position 时,它实际上会裁剪图像并且非常耗费资源。如果你能逃脱它,你只能通过将 autoCrop
设置为 false 来裁剪一次,如下所示:
<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>
然后使用 @ViewChild
访问裁剪器和裁剪方法。这是打字稿文件中的内容:
@ViewChild(ImageCropperComponent) imageCropper: ImageCropperComponent;
然后,当用户选择保留裁剪时,您将需要执行如下操作:
function save(): void {
const event = this.imageCropper.crop();
this.croppedImage = event.base64;
}
这将解决一些性能问题。但请注意,iDevice 似乎很难像 ngx-image-cropper
那样处理裁剪。具体来说,如果用户在上传图像时使用相机,图像可能需要太多内存才能在 Safari 线程中转换为 base64 字符串——因此,iDevices 在正常使用时可能会冻结。这是一个讨论这个问题的地方:https://github.com/Mawi137/ngx-image-cropper/issues/481