Skip to content

Commit bda624f

Browse files
committed
perf(toggle): events are not zoned
1 parent c792ab6 commit bda624f

File tree

5 files changed

+57
-33
lines changed

5 files changed

+57
-33
lines changed

src/components/toggle/test/toggle.spec.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

22
import { Toggle } from '../toggle';
3-
import { mockConfig, mockPlatform, mockHaptic, mockElementRef, mockGestureController, mockRenderer, mockItem, mockForm, mockChangeDetectorRef } from '../../../util/mock-providers';
3+
import { mockConfig, mockPlatform, mockHaptic, mockElementRef, mockGestureController, mockRenderer, mockItem, mockForm, mockChangeDetectorRef, mockZone } from '../../../util/mock-providers';
44
import { commonInputTest, BOOLEAN_CORPUS } from '../../../util/input-tester';
55

66
describe('Toggle', () => {
@@ -16,7 +16,8 @@ describe('Toggle', () => {
1616
const haptic = mockHaptic();
1717
const cd = mockChangeDetectorRef();
1818
const gesture = mockGestureController();
19-
const toggle = new Toggle(form, config, platform, elementRef, renderer, haptic, item, gesture, null, cd);
19+
const zone = mockZone();
20+
const toggle = new Toggle(form, config, platform, elementRef, renderer, haptic, item, gesture, null, cd, zone);
2021

2122
commonInputTest(toggle, {
2223
defaultValue: false,

src/components/toggle/toggle-gesture.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export class ToggleGesture extends PanGesture {
2020
plt,
2121
toggle.getNativeElement(), {
2222
threshold: 0,
23-
zone: true,
23+
zone: false,
2424
domController: domCtrl,
2525
gesture: gestureCtrl.createGesture({
2626
name: GESTURE_TOGGLE,

src/components/toggle/toggle.md.scss

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,11 @@ $toggle-md-item-right-padding: 12px ($item-md-padding-right / 2) 12px
6161
.toggle-md {
6262
position: relative;
6363

64+
padding: $toggle-md-padding;
65+
6466
width: $toggle-md-track-width;
6567
height: $toggle-md-track-height;
6668

67-
padding: $toggle-md-padding;
68-
6969
box-sizing: content-box;
7070
}
7171

@@ -107,6 +107,10 @@ $toggle-md-item-right-padding: 12px ($item-md-padding-right / 2) 12px
107107

108108
transition-duration: $toggle-md-transition-duration;
109109
transition-property: transform, background-color;
110+
111+
will-change: transform, background-color;
112+
113+
contain: strict;
110114
}
111115

112116

src/components/toggle/toggle.ts

Lines changed: 40 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { AfterViewInit, ChangeDetectorRef, Component, ElementRef, forwardRef, HostListener, Input, OnDestroy, Optional, Renderer, ViewEncapsulation } from '@angular/core';
1+
import { NgZone, AfterViewInit, ChangeDetectorRef, Component, ElementRef, forwardRef, HostListener, Input, OnDestroy, Optional, Renderer, ViewEncapsulation } from '@angular/core';
22
import { NG_VALUE_ACCESSOR } from '@angular/forms';
33

44
import { Config } from '../../config/config';
@@ -13,7 +13,6 @@ import { KEY_ENTER, KEY_SPACE } from '../../platform/key';
1313
import { Platform } from '../../platform/platform';
1414
import { ToggleGesture } from './toggle-gesture';
1515

16-
1716
export const TOGGLE_VALUE_ACCESSOR: any = {
1817
provide: NG_VALUE_ACCESSOR,
1918
useExisting: forwardRef(() => Toggle),
@@ -109,7 +108,8 @@ export class Toggle extends BaseInput<boolean> implements IonicTapInput, AfterVi
109108
@Optional() item: Item,
110109
private _gestureCtrl: GestureController,
111110
private _domCtrl: DomController,
112-
private _cd: ChangeDetectorRef
111+
private _cd: ChangeDetectorRef,
112+
private _zone: NgZone,
113113
) {
114114
super(config, elementRef, renderer, 'toggle', false, form, item, null);
115115
}
@@ -142,9 +142,11 @@ export class Toggle extends BaseInput<boolean> implements IonicTapInput, AfterVi
142142
assert(startX, 'startX must be valid');
143143
console.debug('toggle, _onDragStart', startX);
144144

145-
this._startX = startX;
146-
this._fireFocus();
147-
this._activated = true;
145+
this._zone.run(() => {
146+
this._startX = startX;
147+
this._fireFocus();
148+
this._activated = true;
149+
});
148150
}
149151

150152
/**
@@ -156,22 +158,32 @@ export class Toggle extends BaseInput<boolean> implements IonicTapInput, AfterVi
156158
return;
157159
}
158160

159-
console.debug('toggle, _onDragMove', currentX);
161+
let dirty = false;
162+
let value: boolean;
163+
let activated: boolean;
160164

161165
if (this._value) {
162166
if (currentX + 15 < this._startX) {
163-
this.value = false;
164-
this._haptic.selection();
165-
this._startX = currentX;
166-
this._activated = true;
167+
dirty = true;
168+
value = false;
169+
activated = true;
167170
}
168171

169172
} else if (currentX - 15 > this._startX) {
170-
this.value = true;
171-
this._haptic.selection();
172-
this._startX = currentX;
173-
this._activated = (currentX < this._startX + 5);
173+
dirty = true;
174+
value = true;
175+
activated = (currentX < this._startX + 5);
176+
}
177+
178+
if (dirty) {
179+
this._zone.run(() => {
180+
this.value = value;
181+
this._startX = currentX;
182+
this._activated = activated;
183+
this._haptic.selection();
184+
});
174185
}
186+
175187
}
176188

177189
/**
@@ -184,20 +196,22 @@ export class Toggle extends BaseInput<boolean> implements IonicTapInput, AfterVi
184196
}
185197
console.debug('toggle, _onDragEnd', endX);
186198

187-
if (this._value) {
188-
if (this._startX + 4 > endX) {
189-
this.value = false;
199+
this._zone.run(() => {
200+
if (this._value) {
201+
if (this._startX + 4 > endX) {
202+
this.value = false;
203+
this._haptic.selection();
204+
}
205+
206+
} else if (this._startX - 4 < endX) {
207+
this.value = true;
190208
this._haptic.selection();
191209
}
192210

193-
} else if (this._startX - 4 < endX) {
194-
this.value = true;
195-
this._haptic.selection();
196-
}
197-
198-
this._activated = false;
199-
this._fireBlur();
200-
this._startX = null;
211+
this._activated = false;
212+
this._fireBlur();
213+
this._startX = null;
214+
});
201215
}
202216

203217
/**

src/util/base-input.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ElementRef, EventEmitter, Input, Output, Renderer } from '@angular/core';
1+
import { ElementRef, EventEmitter, Input, NgZone, Output, Renderer } from '@angular/core';
22
import { ControlValueAccessor } from '@angular/forms';
33
import { NgControl } from '@angular/forms';
44

@@ -130,6 +130,8 @@ export class BaseInput<T> extends Ion implements CommonInput<T> {
130130
* @hidden
131131
*/
132132
_writeValue(val: any): boolean {
133+
assert(NgZone.isInAngularZone(), 'callback should be zoned');
134+
133135
if (isUndefined(val)) {
134136
return false;
135137
}
@@ -154,7 +156,10 @@ export class BaseInput<T> extends Ion implements CommonInput<T> {
154156
*/
155157
_fireIonChange() {
156158
if (this._init) {
157-
this._debouncer.debounce(() => this.ionChange.emit(this));
159+
this._debouncer.debounce(() => {
160+
assert(NgZone.isInAngularZone(), 'callback should be zoned');
161+
this.ionChange.emit(this);
162+
});
158163
}
159164
}
160165

0 commit comments

Comments
 (0)