作者热门文章
- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有一个 Angular 4.3.5 应用程序,它在使用一段时间后(~20 分钟)变慢了。
我的场景是这样的:
发生了什么:
附加信息:
出现问题的组件如下:
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import 'rxjs/add/operator/takeUntil';
import { Subject } from 'rxjs/Subject';
import { SweetAlertService } from 'ng2-cli-sweetalert2';
import { ApiService } from '.././api.service';
import { NFCService } from '.././nfc.service';
@Component({
selector: 'app-menu',
templateUrl: './menu.component.html',
styleUrls: ['./menu.component.scss']
})
export class MenuComponent implements OnInit, OnDestroy {
private ngUnsubscribe: Subject<void> = new Subject<void>();
cardId: string;
userId: string;
userName: string;
is_secure_bar: boolean = false;
requestInProgress = false;
userBalance: number = 0;
step: number = 1;
// showCheckout: boolean = false;
categories = new Array();
subcategories = new Array();
products = new Array();
cartItems = new Array();
countCartItems: number = 0;
totalCartValue: number = 0;
table_scroller;
table_scroller_height;
show_scroller_btns = false;
constructor(
public router: Router,
public route: ActivatedRoute,
private _nfcService: NFCService,
private _apiService: ApiService,
private _swal: SweetAlertService
) { }
ngOnInit() {
var account = localStorage.getItem('account');
if (account) {
// set variable to catch user data
// JSON.parse(
} else {
this.router.navigate(['login']);
}
this.route.params
.takeUntil(this.ngUnsubscribe)
.subscribe(params => {
this.cardId = params.id;
this._apiService.getCardUser(params.id)
.takeUntil(this.ngUnsubscribe)
.subscribe(
response => {
// SUCCESS
this.userId = response.data[0].uuid;
this.userBalance = response.data[0].balance;
this.userName = response.data[0].name;
},
error => {
// ERROR
console.log('Failed ;(', error);
}
);
});
this.getEvents()
.takeUntil(this.ngUnsubscribe)
.subscribe(
response => {
if (response.data[0].options.sales_auth_after_buy_is_required) {
this.is_secure_bar = true;
}
},
error => {
console.log('Erro ao verificar Evento.')
}
);
var categories = localStorage.getItem('cache_categories');
if (categories) {
this.categories = JSON.parse(categories);
} else {
// this.getCategories();
this.getCategoriesP()
}
}
//@felipe_todo
getEvents()
{
return this._apiService.getEvents();
//COMO FAZER LOGOUT ABAIXO
//localStorage.clear();
}
getCategories() {
this._apiService.getProductsCategories()
.takeUntil(this.ngUnsubscribe)
.subscribe(response => {
// SUCCESS
this.categories = response.data;
localStorage.setItem('cache_categories', JSON.stringify(this.categories));
}, error => {
// ERROR
console.log('Failed ;(', error);
});
}
getCategoriesP() {
let categories;
this._apiService.getCategories()
.then(response => categories = response)
.then(() => {
this.categories = categories;
console.log(categories);
});
}
categorySelected(item) {
this.step = 2;
var subcategories = localStorage.getItem('cache_subcategories_' + item.uuid);
if (subcategories) {
this.subcategories = JSON.parse(subcategories);
} else {
// this.getSubcategories(item.uuid);
this.getSubcategoriesP(item.uuid);
}
}
getSubcategories(uuid) {
this._apiService.getProductsSubcategories(uuid)
.takeUntil(this.ngUnsubscribe)
.subscribe(response => {
// SUCCESS
this.subcategories = response.data;
localStorage.setItem('cache_subcategories_' + uuid, JSON.stringify(this.subcategories));
}, error => {
// ERROR
console.log('Failed ;(', error);
});
}
getSubcategoriesP(uuid) {
let subcategories;
this._apiService.getSubcategories(uuid)
.then(response => subcategories = response)
.then(() => {
this.subcategories = subcategories;
console.log(subcategories);
});
}
subCategorySelected(item) {
this.step = 3;
var products = localStorage.getItem('cache_products_' + item.uuid);
if (products) {
this.products = JSON.parse(products);
} else {
// this.getProducts(item.uuid);
this.getProductsP(item.uuid);
}
}
getProducts(uuid) {
this._apiService.getProducts(uuid)
.takeUntil(this.ngUnsubscribe)
.subscribe(response => {
// SUCCESS
this.products = response.data;
localStorage.setItem('cache_products_' + uuid, JSON.stringify(this.products));
}, error => {
// ERROR
console.log('Failed ;(', error);
});
}
getProductsP(uuid) {
let products;
this._apiService.getProductList(uuid)
.then(response => products = response)
.then(() => {
this.products = products;
console.log(products);
});
}
addToCard(product) {
var existentItems = this.cartItems.filter(function(item) {
return item.uuid === product.uuid
});
if (existentItems.length) {
existentItems[0].quantity += 1
} else {
product.quantity = 1;
this.cartItems.unshift(product);
}
let that = this;
this.calculateTotal();
setTimeout(function(){
that.setScroller();
}, 300);
}
removeProduct(index) {
let product = this.cartItems[index]
var existentItems = this.cartItems.filter(function(item) {
return item.uuid === product.uuid
});
if (existentItems.length) {
existentItems[0].quantity -= 1
if (existentItems[0].quantity == 0) {
this.cartItems.splice(index, 1);
}
} else {
product.quantity = 1;
this.cartItems.splice(index, 1);
}
this.calculateTotal();
let that = this;
setTimeout(function(){
if (that.table_scroller.offsetHeight < 270) {
that.show_scroller_btns = false;
}
}, 300);
}
calculateTotal() {
this.countCartItems = 0;
this.totalCartValue = 0;
var that = this;
this.cartItems.forEach(function(item) {
that.countCartItems += item.quantity;
that.totalCartValue += item.value * item.quantity;
});
}
backStep() {
if (this.step == 2) {
this.subcategories = new Array();
} else if (this.step == 3) {
this.products = new Array();
}
this.step--;
}
setScroller() {
if (this.cartItems.length) {
if (!this.table_scroller) {
this.table_scroller = document.querySelector('#table-scroller');
}else {
console.log(this.table_scroller.offsetHeight)
if (this.table_scroller.offsetHeight >= 270) {
this.show_scroller_btns = true;
} else {
this.show_scroller_btns = false;
}
}
}
}
scrollDown() {
(<HTMLElement>this.table_scroller).scrollTop = (<HTMLElement>this.table_scroller).scrollTop+50;
}
scrollUp() {
(<HTMLElement>this.table_scroller).scrollTop = (<HTMLElement>this.table_scroller).scrollTop-50;
}
confirmDebit() {
if (this.requestInProgress) return;
if (this.userBalance < this.totalCartValue) {
this._swal.error({ title: 'Salto Insuficiente', text: 'Este cliente não possui saldo suficiente para essa operação.' });
return;
}
this.requestInProgress = true;
var order = {
card_uuid: this.cardId,
event_uuid: 'c7b5bd69-c2b5-4226-b043-ccbf91be0ba8',
products: this.cartItems
};
let is_secure_bar = this.is_secure_bar;
this._apiService.postOrder(order)
.takeUntil(this.ngUnsubscribe)
.subscribe(response => {
console.log('Success');
// this.router.navigate(['customer', this.userId]);
let that = this;
this._swal.success({
title: 'Debito Efetuado',
text: 'O débito foi efetuado com sucesso',
showCancelButton: false,
confirmButtonText: 'OK',
allowOutsideClick: false,
}).then(function(success) {
console.log("Clicked confirm");
if (is_secure_bar) {
that.logout();
} else {
that.router.navigate(['card']);
}
});
this.requestInProgress = false;
}, error => {
// ERROR
console.log('Request Failed ;(', error);
if (error.status !== 0) {
// TODO: Should display error message if available!
this._swal.error({ title: 'Erro', text: 'Ocorreu um erro inesperado ao conectar-se ao servidor de acesso.' });
} else {
this._swal.error({ title: 'Erro', text: 'Não foi possível conectar-se ao servidor de acesso. Por favor verifique sua conexão.' });
}
this.requestInProgress = false;
}
);
}
logout() {
let that = this;
localStorage.clear();
that.router.navigate(['login']);
}
clearCheckout() {
this.cartItems = new Array();
this.calculateTotal();
this.router.navigate(['card']);
}
ngOnDestroy() {
console.log('uhul')
this.ngUnsubscribe.next();
this.ngUnsubscribe.complete();
}
}
每次访问组件都会出现慢的方法有:
获取类别()获取子类别(uuid)获取产品(uuid)确认扣款()
出于测试目的,我们为这些方法中的每一个都创建了一个新版本,这次使用了 promises:
获取类别P()getSubcategoriesP(uuid)获取产品P(uuid)
不管调用的方法是什么版本,都会出现同样的问题。
最佳答案
如果您将应用程序作为 SPA(单页应用程序)运行,那么随着时间的推移,这可能是导致性能下降的原因之一。
在 SPA 中,每次用户访问新页面时,DOM 都会变重。因此,您必须研究如何保持 DOM 轻量级。
以下是我发现显着提高应用程序性能的主要原因。
检查以下几点:
确认弹出窗口
和消息提醒
等常用组件应定义一次并可全局访问。 服务结束后,对任意对象调用destroy:(下面是调用服务的例子)
import { Subject } from 'rxjs/Subject'
import 'rxjs/add/operator/takeUntil';
ngOnDestroy() {
this.ngUnsubscribe.next(true);
this.ngUnsubscribe.complete();
}
this.frameworkService.ExecuteDataSource().takeUntil(this.ngUnsubscribe).subscribe((data: any) => {
console.log(data);
});
有关详细信息,请参阅以下链接:
https://medium.com/paramsingh-66174/catalysing-your-angular-4-app-performance-9211979075f6
关于随着时间的推移,Angular 4 变得越来越慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45962654/
我是一名优秀的程序员,十分优秀!