Skip to content

Commit 0985661

Browse files
cardosonolanlawson
andauthored
perf(template-compiler): static-optimize on event listener object (#4468)
Co-authored-by: Nolan Lawson <nlawson@salesforce.com>
1 parent 934e666 commit 0985661

File tree

35 files changed

+668
-148
lines changed

35 files changed

+668
-148
lines changed

packages/@lwc/integration-karma/test/events/memoization/index.spec.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { createElement } from 'lwc';
22
import Deep from 'x/deep';
33
import List from 'x/list';
4+
import Mixed from 'x/mixed';
45

56
describe('deep listener', () => {
67
beforeEach(() => {
@@ -46,4 +47,28 @@ describe('deep listener', () => {
4647
elm.shadowRoot.querySelector('button').click();
4748
expect(window.clickBuffer).toEqual([1, 2]);
4849
});
50+
51+
// In this case, the click listener is re-bound on every render, because the referenced
52+
// listener is scoped inside a <template for:each>. However, `mainLogger.onChange` is
53+
// never re-bound because the `mainLogger` is scoped to the component.
54+
it('does redefine onClick for a list of deep click listeners but not the onChange for a single deep listener', async () => {
55+
const elm = createElement('x-mixed', { is: Mixed });
56+
document.body.appendChild(elm);
57+
58+
elm.loggers = [{ id: 1, onClick: () => window.clickBuffer.push(1) }];
59+
elm.mainLogger = {
60+
onChange: () => window.clickBuffer.push('foo'),
61+
};
62+
await Promise.resolve();
63+
elm.shadowRoot.querySelector('input').click();
64+
expect(window.clickBuffer).toEqual([1, 'foo']);
65+
66+
elm.loggers = [{ id: 2, onClick: () => window.clickBuffer.push(2) }];
67+
elm.mainLogger = {
68+
onChange: () => window.clickBuffer.push('bar'),
69+
};
70+
await Promise.resolve();
71+
elm.shadowRoot.querySelector('input').click();
72+
expect(window.clickBuffer).toEqual([1, 'foo', 2, 'foo']);
73+
});
4974
});
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<template>
2+
<template for:each={loggers} for:item="logger">
3+
<input
4+
key={logger.id}
5+
type="checkbox"
6+
onclick={logger.onClick}
7+
onchange={mainLogger.onChange}
8+
></input>
9+
</template>
10+
</template>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { LightningElement, api } from 'lwc';
2+
3+
export default class extends LightningElement {
4+
@api loggers = [];
5+
6+
@api mainLogger;
7+
}

packages/@lwc/template-compiler/src/__tests__/fixtures/dynamic-components/valid/attributes/expected.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@ function tmpl($api, $cmp, $slotset, $ctx) {
1212
classMap: stc0,
1313
slotAssignment: "slotName",
1414
key: 0,
15-
on: {
16-
click: _m0 || ($ctx._m0 = api_bind($cmp.handleClick)),
17-
},
15+
on:
16+
_m0 ||
17+
($ctx._m0 = {
18+
click: api_bind($cmp.handleClick),
19+
}),
1820
}),
1921
];
2022
/*LWC compiler vX.X.X*/

packages/@lwc/template-compiler/src/__tests__/fixtures/dynamic-components/valid/nested/expected.js

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,11 @@ function tmpl($api, $cmp, $slotset, $ctx) {
2323
classMap: stc0,
2424
props: stc1,
2525
key: 0,
26-
on: {
27-
click: _m0 || ($ctx._m0 = api_bind($cmp.handleOuterClick)),
28-
},
26+
on:
27+
_m0 ||
28+
($ctx._m0 = {
29+
click: api_bind($cmp.handleOuterClick),
30+
}),
2931
},
3032
[
3133
api_static_fragment($fragment1, 2),
@@ -35,9 +37,11 @@ function tmpl($api, $cmp, $slotset, $ctx) {
3537
classMap: stc0,
3638
props: stc1,
3739
key: 3,
38-
on: {
39-
click: _m1 || ($ctx._m1 = api_bind($cmp.handleOuterClick)),
40-
},
40+
on:
41+
_m1 ||
42+
($ctx._m1 = {
43+
click: api_bind($cmp.handleOuterClick),
44+
}),
4145
},
4246
[api_static_fragment($fragment2, 5)]
4347
),

packages/@lwc/template-compiler/src/__tests__/fixtures/events/component/expected.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@ function tmpl($api, $cmp, $slotset, $ctx) {
1212
api_element("section", stc0, [
1313
api_custom_element("ns-foo", _nsFoo, {
1414
key: 1,
15-
on: {
16-
foo: _m0 || ($ctx._m0 = api_bind($cmp.handleFoo)),
17-
},
15+
on:
16+
_m0 ||
17+
($ctx._m0 = {
18+
foo: api_bind($cmp.handleFoo),
19+
}),
1820
}),
1921
]),
2022
];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<template>
2+
<button onclick={onClick} ontouchstart={onTouchStart} ontouchend={onTouchEnd}></button>
3+
</template>
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
{
2+
"root": {
3+
"type": "Root",
4+
"location": {
5+
"startLine": 1,
6+
"startColumn": 1,
7+
"endLine": 3,
8+
"endColumn": 12,
9+
"start": 0,
10+
"end": 114,
11+
"startTag": {
12+
"startLine": 1,
13+
"startColumn": 1,
14+
"endLine": 1,
15+
"endColumn": 11,
16+
"start": 0,
17+
"end": 10
18+
},
19+
"endTag": {
20+
"startLine": 3,
21+
"startColumn": 1,
22+
"endLine": 3,
23+
"endColumn": 12,
24+
"start": 103,
25+
"end": 114
26+
}
27+
},
28+
"directives": [],
29+
"children": [
30+
{
31+
"type": "Element",
32+
"name": "button",
33+
"namespace": "http://www.w3.org/1999/xhtml",
34+
"location": {
35+
"startLine": 2,
36+
"startColumn": 5,
37+
"endLine": 2,
38+
"endColumn": 92,
39+
"start": 15,
40+
"end": 102,
41+
"startTag": {
42+
"startLine": 2,
43+
"startColumn": 5,
44+
"endLine": 2,
45+
"endColumn": 83,
46+
"start": 15,
47+
"end": 93
48+
},
49+
"endTag": {
50+
"startLine": 2,
51+
"startColumn": 83,
52+
"endLine": 2,
53+
"endColumn": 92,
54+
"start": 93,
55+
"end": 102
56+
}
57+
},
58+
"attributes": [],
59+
"properties": [],
60+
"directives": [],
61+
"listeners": [
62+
{
63+
"type": "EventListener",
64+
"name": "click",
65+
"handler": {
66+
"type": "Identifier",
67+
"start": 1,
68+
"end": 8,
69+
"name": "onClick",
70+
"location": {
71+
"startLine": 2,
72+
"startColumn": 13,
73+
"endLine": 2,
74+
"endColumn": 30,
75+
"start": 23,
76+
"end": 40
77+
}
78+
},
79+
"location": {
80+
"startLine": 2,
81+
"startColumn": 13,
82+
"endLine": 2,
83+
"endColumn": 30,
84+
"start": 23,
85+
"end": 40
86+
}
87+
},
88+
{
89+
"type": "EventListener",
90+
"name": "touchstart",
91+
"handler": {
92+
"type": "Identifier",
93+
"start": 1,
94+
"end": 13,
95+
"name": "onTouchStart",
96+
"location": {
97+
"startLine": 2,
98+
"startColumn": 31,
99+
"endLine": 2,
100+
"endColumn": 58,
101+
"start": 41,
102+
"end": 68
103+
}
104+
},
105+
"location": {
106+
"startLine": 2,
107+
"startColumn": 31,
108+
"endLine": 2,
109+
"endColumn": 58,
110+
"start": 41,
111+
"end": 68
112+
}
113+
},
114+
{
115+
"type": "EventListener",
116+
"name": "touchend",
117+
"handler": {
118+
"type": "Identifier",
119+
"start": 1,
120+
"end": 11,
121+
"name": "onTouchEnd",
122+
"location": {
123+
"startLine": 2,
124+
"startColumn": 59,
125+
"endLine": 2,
126+
"endColumn": 82,
127+
"start": 69,
128+
"end": 92
129+
}
130+
},
131+
"location": {
132+
"startLine": 2,
133+
"startColumn": 59,
134+
"endLine": 2,
135+
"endColumn": 82,
136+
"start": 69,
137+
"end": 92
138+
}
139+
}
140+
],
141+
"children": []
142+
}
143+
]
144+
}
145+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"enableStaticContentOptimization": false
3+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import _implicitStylesheets from "./non-static-optimized.css";
2+
import _implicitScopedStylesheets from "./non-static-optimized.scoped.css?scoped=true";
3+
import { freezeTemplate, registerTemplate } from "lwc";
4+
function tmpl($api, $cmp, $slotset, $ctx) {
5+
const { b: api_bind, h: api_element } = $api;
6+
const { _m0 } = $ctx;
7+
return [
8+
api_element("button", {
9+
key: 0,
10+
on:
11+
_m0 ||
12+
($ctx._m0 = {
13+
click: api_bind($cmp.onClick),
14+
touchstart: api_bind($cmp.onTouchStart),
15+
touchend: api_bind($cmp.onTouchEnd),
16+
}),
17+
}),
18+
];
19+
/*LWC compiler vX.X.X*/
20+
}
21+
export default registerTemplate(tmpl);
22+
tmpl.stylesheets = [];
23+
tmpl.stylesheetToken = "lwc-d9girnpd2k";
24+
tmpl.legacyStylesheetToken = "x-non-static-optimized_non-static-optimized";
25+
if (_implicitStylesheets) {
26+
tmpl.stylesheets.push.apply(tmpl.stylesheets, _implicitStylesheets);
27+
}
28+
if (_implicitScopedStylesheets) {
29+
tmpl.stylesheets.push.apply(tmpl.stylesheets, _implicitScopedStylesheets);
30+
}
31+
freezeTemplate(tmpl);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"warnings": []
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<template>
2+
<button onclick={onClick} ontouchstart={onTouchStart} ontouchend={onTouchEnd}></button>
3+
</template>

0 commit comments

Comments
 (0)