typescript - Angular ytelsesproblemer når du beskjærer bilde


Jeg bruker denne komponenten for å beskjære bilder som en del av et ionic/angular8-prosjekt, men jeg får alvorlige ytelsesproblemer som gjør at appen blir uresponsiv noen ganger. Dette viser seg kun når den kjøres fra mobil; desktop-versjonen viser ingen problemer, beskjæringen fungerer helt fint.

Når jeg gjør en ytelsesvurdering, ser jeg i noen tilfeller disse søppelsamlingene; jeg kommer fra en Java-verden, og GC er alltid et ytelsesproblem, men jeg har ikke funnet mye om det, men jeg tror ikke det er roten til problemet:

Her er et annet eksempel, det ser ut til å være en forsinkelse mellom at brukeren interagerer med skjermen, og at min interne metode blir kalt, som du kan se er det en FunksjonsKall, men hvilken funksjon.

Min generelle kode er nesten den samme som på nettstedet, men jeg vil dele den her:

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>

Og her kan du se klassen min, jeg la til en haug med console-logger i prosessen med å finne problemet, og noe jeg har sett er at når appen fryser og blir i den lange kallet, er det ingen output, så plutselig, masse på rad:

    @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();
  }
}

Jeg har allerede prøvd å oppdatere changeDetection-strategien, fjernet noen funksjonskall jeg hadde på andre sider, og de fleste av ytelsesanbefalingene, men jeg ser ikke ut til å finne årsaken til mitt nåværende problem

Svar #1

ngx-image-cropper, når du endrer beskjæringsstørrelse/posisjon, beskjærer den faktisk bildet og er svært ressurskrevende. Hvis du kan slippe unna med det, kan du beskjære bare én gang ved å sette autoCrop til false slik:

<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>

Da bruker du @ViewChild for å få tilgang til cropperen og dermed beskjæringsmetodene. Slik ser det ut i TypeScript-filen:

@ViewChild(ImageCropperComponent) imageCropper: ImageCropperComponent;

Deretter, når brukeren velger å beholde beskjæringen, må du gjøre noe som dette:

function save(): void {
  const event = this.imageCropper.crop();
  this.croppedImage = event.base64;
}

Dette vil fikse noen ytelsesproblemer. Men vær oppmerksom på at det ser ut til at iDevices sliter med å håndtere beskjæring på den måten som ngx-image-cropper gjør det. Spesielt, hvis brukeren bruker kameraet mens de laster opp et bilde, kan bildet kreve for mye minne for å konverteres til en base64-streng i Safari-tråden - som et resultat kan iDevices fryse når de brukes normalt. Her er ett sted hvor dette blir diskutert: https://github.com/Mawi137/ngx-image-cropper/issues/481