在我们的项目中,我们有成千上万的单元测试,并且它们变得越来越慢。我进行了调试,发现CPU时间主要花费在渲染上。
经过更多调试后,我发现在Jasmine测试页DOM中,有成千上万个<style>
标签,这似乎是性能问题的核心。
我已经在空的ng new
项目上尝试过。我所做的只是为AppComponent
添加了一些样式:
app.component.css :
.test {
color: red;
}
当我使用ng test
运行默认的单元测试(有3个预定义的单元测试)并在Jasmine测试页面上打开chrome控制台时,结果如下-样式是其中的三遍!:
在运行数千个测试时,由于成千上万个<style>
标签,因此性能受到很大影响。
有人知道每次测试后如何进行业力/角度清理吗?
我正在使用angular 6.1.1和angular / cli 6.0.1
答案 0 :(得分:3)
我认为您遇到了以下错误:https://github.com/angular/angular/issues/31834
将以下行添加到全局afterEach确实加速了测试套件的执行:
window.document.querySelectorAll("style").forEach((style: HTMLStyleElement) => style.remove());
答案 1 :(得分:0)
该组件被配置为使用ViewEncapsulation.Emulated
,这意味着app.component.css
文件应仅包含:host
样式和其他主机选择器。
Angular将为组件注入<style>
标签,并在运行时将其绑定到主机视图。销毁组件后,会删除 host 样式,但是您已经在 host 范围之外添加了其他选择器。因此,浏览器将其保留不变,因为它们未绑定到主机。
应该通过为项目定义的style.css
文件包括 global 的所有 extra 样式。
另一种选择是使用ViewEncapsulation.None
而不使用:host
选择器。
更新:
Angular 6已添加ViewEncapsulation.ShadowDom
设置。
https://w3c.github.io/webcomponents/spec/shadow/
该规范描述了一种将多个DOM树组合到一个层次结构中的方法,以及这些树如何在文档中彼此交互,从而使DOM更好地构成。
Angular文档提供了以下示例:
styles: [`
:host {
display: block;
border: 1px solid black;
}
h1 {
color: blue;
}
.red {
background-color: red;
}
`],
尝试改用这种封装模式。看起来它可以解决您遇到的问题。
答案 2 :(得分:0)
好的,我尝试了更野蛮的方式,看来它正在起作用。我创建了一个具有1400个相同测试的示例应用程序(它仅呈现@angular/material
按钮并对其进行检查)。
运行此测试套件需要14分钟。
添加以下行之后:
afterEach(() => {
const head = document.getElementsByTagName('head')[0];
const styles = document.getElementsByTagName('style');
for (let i = 0; i < styles.length; i++) {
head.removeChild(styles[i]);
}
});
运行它需要80秒。
在我看来,因果报应应该以某种方式处理此问题,因为我敢打赌这是很普遍的问题
答案 3 :(得分:0)
为此,我制作了一个可以使用的函数trimLeftoverStyles
,可以从我的开源库s-ng-dev-utils
中获得该函数。它只会删除您的组件添加的样式。如果您添加了测试套件中使用的全局样式,则将使它们孤独。如果按照建议在beforeEach
中调用它,它还将使您的组件在测试结束时样式正确,以便可以正确查看它进行调试。