Skip to content

Commit 3a307e8

Browse files
committed
perf: optimize element event distribution and attribute update process
1 parent a5abca7 commit 3a307e8

27 files changed

Lines changed: 1111 additions & 722 deletions

__tests__/demos/perf/attr-update.ts

Lines changed: 45 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
import * as lil from 'lil-gui';
2-
import { Rect, Group, CanvasEvent } from '@antv/g';
3-
import type { Canvas } from '@antv/g';
2+
import {
3+
type Canvas,
4+
Rect,
5+
Group,
6+
CanvasEvent,
7+
ElementEvent,
8+
runtime,
9+
} from '@antv/g';
10+
11+
runtime.enablePerformanceOptimization = false;
412

513
export async function attrUpdate(context: { canvas: Canvas; gui: lil.GUI }) {
614
const { canvas, gui } = context;
@@ -9,9 +17,9 @@ export async function attrUpdate(context: { canvas: Canvas; gui: lil.GUI }) {
917
await canvas.ready;
1018

1119
const { width, height } = canvas.getConfig();
12-
const count = 2e4;
1320
const root = new Group();
14-
const rects = [];
21+
let count = 1e4;
22+
let rects = [];
1523

1624
const perfStore: { [k: string]: { count: number; time: number } } = {
1725
update: { count: 0, time: 0 },
@@ -28,6 +36,7 @@ export async function attrUpdate(context: { canvas: Canvas; gui: lil.GUI }) {
2836
}
2937

3038
function update() {
39+
// console.log('update');
3140
// const startTime = performance.now();
3241
// console.time('update');
3342

@@ -53,6 +62,9 @@ export async function attrUpdate(context: { canvas: Canvas; gui: lil.GUI }) {
5362
}
5463

5564
function render() {
65+
root.destroyChildren();
66+
rects = [];
67+
5668
for (let i = 0; i < count; i++) {
5769
const x = Math.random() * width;
5870
const y = Math.random() * height;
@@ -66,17 +78,28 @@ export async function attrUpdate(context: { canvas: Canvas; gui: lil.GUI }) {
6678
width: size,
6779
height: size,
6880
fill: 'white',
69-
stroke: 'black',
81+
stroke: '#000',
82+
lineWidth: 1,
7083
},
7184
});
7285
root.appendChild(rect);
7386
rects[i] = { x, y, size, speed, el: rect };
87+
88+
// rect.isMutationObserved = true;
89+
rect.addEventListener(ElementEvent.ATTR_MODIFIED, () => {
90+
console.log(ElementEvent.ATTR_MODIFIED);
91+
});
7492
}
7593
}
7694

7795
render();
7896
canvas.addEventListener(CanvasEvent.BEFORE_RENDER, () => update());
7997

98+
// root.isMutationObserved = true;
99+
// canvas.addEventListener(ElementEvent.BOUNDS_CHANGED, () => {
100+
// console.log('first');
101+
// });
102+
80103
canvas.appendChild(root);
81104

82105
canvas.addEventListener(
@@ -88,18 +111,23 @@ export async function attrUpdate(context: { canvas: Canvas; gui: lil.GUI }) {
88111
);
89112

90113
// GUI
114+
// canvas.getConfig().renderer.getConfig().enableCulling = true;
91115
canvas.getConfig().renderer.getConfig().enableRenderingOptimization = true;
116+
const observeConfig = {
117+
objectCount: count,
118+
enableRenderingOptimization: canvas.getConfig().renderer.getConfig()
119+
.enableRenderingOptimization,
120+
enablePerformanceOptimization: runtime.enablePerformanceOptimization,
121+
};
92122

93-
gui
94-
.add(
95-
{
96-
enableRenderingOptimization: canvas.getConfig().renderer.getConfig()
97-
.enableRenderingOptimization,
98-
},
99-
'enableRenderingOptimization',
100-
)
101-
.onChange((result) => {
102-
canvas.getConfig().renderer.getConfig().enableRenderingOptimization =
103-
result;
104-
});
123+
gui.add(observeConfig, 'objectCount').onChange((value) => {
124+
count = value;
125+
render();
126+
});
127+
gui.add(observeConfig, 'enablePerformanceOptimization').onChange((value) => {
128+
runtime.enablePerformanceOptimization = value;
129+
});
130+
gui.add(observeConfig, 'enableRenderingOptimization').onChange((value) => {
131+
canvas.getConfig().renderer.getConfig().enableRenderingOptimization = value;
132+
});
105133
}

__tests__/demos/perf/circles.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@ import { Circle } from '@antv/g';
22

33
export async function circles(context) {
44
const { canvas, container } = context;
5+
56
await canvas.ready;
67

7-
canvas.addEventListener('rerender', () => {
8-
console.log('rerender');
9-
});
8+
canvas.getConfig().renderer.getConfig().enableRenderingOptimization = true;
9+
10+
console.time('render');
1011

11-
for (let i = 0; i < 10000; i++) {
12+
for (let i = 0; i < 5e4; i++) {
1213
const circle = new Circle({
1314
style: {
1415
cx: Math.random() * 640,
@@ -22,6 +23,14 @@ export async function circles(context) {
2223
canvas.appendChild(circle);
2324
}
2425

26+
canvas.addEventListener(
27+
'rerender',
28+
() => {
29+
console.timeEnd('render');
30+
},
31+
{ once: true },
32+
);
33+
2534
// canvas.appendChild(
2635
// new Circle({
2736
// style: {
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import {
2+
Canvas,
3+
ElementEvent,
4+
Rect,
5+
Group,
6+
EventTarget,
7+
runtime,
8+
} from '@antv/g';
9+
import * as tinybench from 'tinybench';
10+
11+
/**
12+
* 元素高频销毁与实例化性能测试
13+
*/
14+
export async function destroyEvent(context: { canvas: Canvas }) {
15+
const { canvas } = context;
16+
console.log(canvas);
17+
18+
await canvas.ready;
19+
20+
const { width, height } = canvas.getConfig();
21+
const root = new Group();
22+
let count = 2e2;
23+
let rects = [];
24+
25+
function render() {
26+
root.destroyChildren();
27+
rects = [];
28+
29+
for (let i = 0; i < count; i++) {
30+
const x = Math.random() * width;
31+
const y = Math.random() * height;
32+
const size = 10 + Math.random() * 40;
33+
const speed = 1 + Math.random();
34+
35+
const rect = new Rect({
36+
style: {
37+
x,
38+
y,
39+
width: size,
40+
height: size,
41+
fill: 'white',
42+
stroke: '#000',
43+
lineWidth: 1,
44+
},
45+
});
46+
root.appendChild(rect);
47+
rects[i] = { x, y, size, speed, el: rect };
48+
}
49+
}
50+
51+
render();
52+
canvas.appendChild(root);
53+
54+
// benchmark
55+
// ----------
56+
const bench = new tinybench.Bench({ name: 'event benchmark', time: 1e2 });
57+
58+
bench.add('0', async () => {
59+
runtime.enablePerformanceOptimization = false;
60+
render();
61+
});
62+
bench.add('1', async () => {
63+
runtime.enablePerformanceOptimization = true;
64+
render();
65+
});
66+
67+
await bench.run();
68+
69+
console.log(bench.name);
70+
console.table(bench.table());
71+
console.log(bench.results);
72+
console.log(bench.tasks);
73+
74+
// ----------
75+
}

__tests__/demos/perf/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,7 @@ export { rects } from './rect';
33
export { image } from './image';
44
export { attrUpdate } from './attr-update';
55
export { massiveAttrs } from './massive-attrs';
6+
export { canvasApi } from './canvas-api';
7+
export { javascript } from './javascript';
8+
export { event } from './event';
9+
export { destroyEvent } from './destroy-event';

__tests__/demos/perf/javascript.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ export async function javascript(context: { canvas: Canvas; gui: lil.GUI }) {
1111

1212
// benchmark
1313
// ----------
14-
const bench = new tinybench.Bench({ name: 'canvas benchmark', time: 1e2 });
14+
const bench = new tinybench.Bench({
15+
name: 'javascript benchmark',
16+
time: 1e2,
17+
});
1518
const array = [
1619
'stroke',
1720
'shadowType',

0 commit comments

Comments
 (0)