如何在不降低性能的情况下使用 Angular 实现 UI 主题?
How to implement UI theming with Angular without performance reduction?
背景
我有一个 Angular 网络应用程序,其复杂性与 Facebook 非常相似。主要功能之一是视觉定制,这意味着用户可以在 运行 时间更改网站上的每种颜色,并将颜色配置保存到他的个人资料中。
我设法通过使用 NgRx Store 实现了这样的行为,所有颜色都存储在整个应用程序中并在其中复制。颜色通过 Angular [style.property]
符号分配给每个模板元素。
问题
我注意到在包含许多项目(大约 500)的列表的页面上,CPU 使用率很高,UI 开始变慢。
我认为这是因为发出了许多事件,我需要创建这些事件 css 悬停效果:
(mouseenter)="$event.target.style.backgroundColor = COLOR_2"
(mouseleave)="$event.target.style.backgroundColor = COLOR_1">
问题
有没有办法消除性能下降或使用另一种不会损害性能的主题化方法?
您可以创建一个主题指令,而不是将颜色添加到每个组件,该指令将在包含 theme
class 的文档头部创建一个样式元素。然后,您可以使用此 class 为所有元素正确着色。
import { Directive, Input } from '@angular/core';
@Directive({
selector: '[appTheme]'
})
export class ThemeDirective {
@Input()
set appTheme(val: string) {
this.setColor(val);
}
private themeElement: HTMLStyleElement;
private setColor(color: string) {
if(!this.themeElement) {
this.themeElement = document.createElement('style');
this.themeElement.type = 'text/css';
document.getElementsByTagName('head')[0].appendChild(this.themeElement);
document.body.className = 'theme';
}
this.themeElement.innerHTML = `.theme { background-color: ${color}; }`;
}
}
背景
我有一个 Angular 网络应用程序,其复杂性与 Facebook 非常相似。主要功能之一是视觉定制,这意味着用户可以在 运行 时间更改网站上的每种颜色,并将颜色配置保存到他的个人资料中。
我设法通过使用 NgRx Store 实现了这样的行为,所有颜色都存储在整个应用程序中并在其中复制。颜色通过 Angular [style.property]
符号分配给每个模板元素。
问题
我注意到在包含许多项目(大约 500)的列表的页面上,CPU 使用率很高,UI 开始变慢。
我认为这是因为发出了许多事件,我需要创建这些事件 css 悬停效果:
(mouseenter)="$event.target.style.backgroundColor = COLOR_2"
(mouseleave)="$event.target.style.backgroundColor = COLOR_1">
问题
有没有办法消除性能下降或使用另一种不会损害性能的主题化方法?
您可以创建一个主题指令,而不是将颜色添加到每个组件,该指令将在包含 theme
class 的文档头部创建一个样式元素。然后,您可以使用此 class 为所有元素正确着色。
import { Directive, Input } from '@angular/core';
@Directive({
selector: '[appTheme]'
})
export class ThemeDirective {
@Input()
set appTheme(val: string) {
this.setColor(val);
}
private themeElement: HTMLStyleElement;
private setColor(color: string) {
if(!this.themeElement) {
this.themeElement = document.createElement('style');
this.themeElement.type = 'text/css';
document.getElementsByTagName('head')[0].appendChild(this.themeElement);
document.body.className = 'theme';
}
this.themeElement.innerHTML = `.theme { background-color: ${color}; }`;
}
}