Skip to content

Commit 30bd8be

Browse files
committed
perf optimization for watcher dep collection
1 parent 6d0697b commit 30bd8be

File tree

5 files changed

+43
-18
lines changed

5 files changed

+43
-18
lines changed

src/directives/repeat.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ module.exports = {
406406
)
407407
}
408408
} else {
409-
_.define(data, this.id, vm)
409+
_.define(data, id, vm)
410410
}
411411
} else {
412412
if (!cache[data]) {

src/observer/array.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ _.define(
8181
/* istanbul ignore if */
8282
if (!this.length) return
8383
if (typeof index !== 'number') {
84-
index = this.indexOf(index)
84+
index = _.indexOf(this, index)
8585
}
8686
if (index > -1) {
8787
this.splice(index, 1)

src/observer/dep.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
var uid = 0
21
var _ = require('../util')
32

43
/**
@@ -9,7 +8,6 @@ var _ = require('../util')
98
*/
109

1110
function Dep () {
12-
this.id = ++uid
1311
this.subs = []
1412
}
1513

src/util/lang.js

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,13 @@ exports.classify = function (str) {
105105
*/
106106

107107
exports.bind = function (fn, ctx) {
108-
return function () {
109-
return fn.apply(ctx, arguments)
108+
return function (a) {
109+
var l = arguments.length
110+
return l
111+
? l > 1
112+
? fn.apply(ctx, arguments)
113+
: fn.call(ctx, a)
114+
: fn.call(ctx)
110115
}
111116
}
112117

@@ -227,4 +232,19 @@ exports.debounce = function(func, wait) {
227232
}
228233
return result
229234
}
235+
}
236+
237+
/**
238+
* Manual indexOf because it's slightly faster than
239+
* native.
240+
*
241+
* @param {Array} arr
242+
* @param {*} obj
243+
*/
244+
245+
exports.indexOf = function (arr, obj) {
246+
for (var i = 0, l = arr.length; i < l; i++) {
247+
if (arr[i] === obj) return i
248+
}
249+
return -1
230250
}

src/watcher.js

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ function Watcher (vm, expression, cb, options) {
3131
options = options || {}
3232
this.deep = !!options.deep
3333
this.user = !!options.user
34-
this.deps = Object.create(null)
34+
this.deps = []
35+
this.newDeps = []
3536
// setup filters if any.
3637
// We delegate directive filters here to the watcher
3738
// because they need to be included in the dependency
@@ -56,12 +57,15 @@ var p = Watcher.prototype
5657
*/
5758

5859
p.addDep = function (dep) {
59-
var id = dep.id
60-
if (!this.newDeps[id]) {
61-
this.newDeps[id] = dep
62-
if (!this.deps[id]) {
63-
this.deps[id] = dep
60+
var newDeps = this.newDeps
61+
var old = this.deps
62+
if (_.indexOf(newDeps, dep) < 0) {
63+
newDeps.push(dep)
64+
var i = _.indexOf(old, dep)
65+
if (i < 0) {
6466
dep.addSub(this)
67+
} else {
68+
old[i] = null
6569
}
6670
}
6771
}
@@ -123,7 +127,6 @@ p.set = function (value) {
123127

124128
p.beforeGet = function () {
125129
Observer.target = this
126-
this.newDeps = {}
127130
}
128131

129132
/**
@@ -132,12 +135,15 @@ p.beforeGet = function () {
132135

133136
p.afterGet = function () {
134137
Observer.target = null
135-
for (var id in this.deps) {
136-
if (!this.newDeps[id]) {
137-
this.deps[id].removeSub(this)
138+
var i = this.deps.length
139+
while (i--) {
140+
var dep = this.deps[i]
141+
if (dep) {
142+
dep.removeSub(this)
138143
}
139144
}
140145
this.deps = this.newDeps
146+
this.newDeps = []
141147
}
142148

143149
/**
@@ -220,8 +226,9 @@ p.teardown = function () {
220226
if (!this.vm._isBeingDestroyed) {
221227
this.vm._watcherList.$remove(this)
222228
}
223-
for (var id in this.deps) {
224-
this.deps[id].removeSub(this)
229+
var i = this.deps.length
230+
while (i--) {
231+
this.deps[i].removeSub(this)
225232
}
226233
this.active = false
227234
this.vm = this.cbs = this.value = null

0 commit comments

Comments
 (0)