Skip to content

Commit 47c454a

Browse files
mheveryIgorMinar
authored andcommitted
change to keydown from keyup; add delayed $updateView
- There was a perceived lag when typing do to the fact that we were listening on the keyup event instead of keydown. The issue with keydown is that we can not read the value of the input field. To solve this we schedule a defer call and perform the model update then. - To prevent calling $eval on root scope too many times as well as to prevent drowning the browser with too many updates we now call the $eval only after 25ms and any additional requests get ignored. The new update service is called $updateView
1 parent 16086aa commit 47c454a

18 files changed

+204
-51
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@ build/
22
angularjs.netrc
33
jstd.log
44
.DS_Store
5-
regression/temp.html
5+
regression/temp*.html
6+
performance/temp*.html
67
.idea/workspace.xml

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@
55
not needed.
66
- $location service now listens for `onhashchange` events (if supported by browser) instead of
77
constant polling.
8+
- input widgets known listens on keydown events instead of keyup which improves perceived
9+
performance
10+
11+
### API
12+
13+
- new service $updateView which should be used in favor of $root.$eval() to run a complete eval on
14+
the entire document. This service bulks and throttles DOM updates to improve performance.
815

916
### Breaking changes
1017
- API for accessing registered services — `scope.$inject` — was renamed to

docs/collect.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ var TAG = {
244244
name: function(doc, name, value) {
245245
var parts = value.split(/\./);
246246
doc.name = value;
247-
doc.shortName = parts.pop();
247+
doc.shortName = parts.pop().replace('#', '.');
248248
doc.depth = parts.length;
249249
},
250250
param: function(doc, name, value){
@@ -378,6 +378,7 @@ function processNgDoc(documentation, doc) {
378378
if (doc.methodOf) {
379379
if (parent = documentation.byName[doc.methodOf]) {
380380
(parent.method = parent.method || []).push(doc);
381+
parent.method.sort(keywordSort);
381382
} else {
382383
throw 'Owner "' + doc.methodOf + '" is not defined.';
383384
}

docs/docs.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
SyntaxHighlighter['defaults'].toolbar = false;
2-
31
DocsController.$inject = ['$location', '$browser', '$window'];
42
function DocsController($location, $browser, $window) {
53
this.pages = NG_PAGES;
@@ -38,10 +36,12 @@ function DocsController($location, $browser, $window) {
3836
return "mailto:angular@googlegroups.com?" +
3937
"subject=" + escape("Feedback on " + $location.href) + "&" +
4038
"body=" + escape("Hi there,\n\nI read " + $location.href + " and wanted to ask ....");
41-
}
39+
};
4240

4341
}
4442

4543
angular.filter('short', function(name){
4644
return (name||'').split(/\./).pop();
47-
});
45+
});
46+
47+
SyntaxHighlighter['defaults'].toolbar = false;

docs/service.template

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,23 @@
2525
{{/requires}}
2626
</ul>
2727

28+
{{#method.length}}
2829
<h2>Methods</h2>
2930
<ul>
3031
{{#method}}
31-
<li><tt>{{shortName}}</tt>: {{{description}}}</li>
32+
<li><tt>{{shortName}}()</tt>: {{{description}}}</li>
3233
{{/method}}
3334
</ul>
35+
{{/method.length}}
3436

37+
{{#property.length}}
3538
<h2>Properties</h2>
3639
<ul>
3740
{{#property}}
3841
<li><tt>{{name}}:{{#type}}{{type}}{{/type}}</tt>{{#description}}: {{{description}}}{{/description}}</li>
3942
{{/property}}
4043
</ul>
44+
{{/property.length}}
4145

4246
{{#example}}
4347
<h2>Example</h2>

perf/noangular.html

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2+
<html xmlns:ng="http://angularjs.org">
3+
<head>
4+
<script>
5+
function el(id) {
6+
return document.getElementById(id);
7+
}
8+
function update() {
9+
el("output").innerHTML = el("input").value;
10+
}
11+
</script>
12+
</head>
13+
<body>
14+
Your name: <input id="input" type="text" value="World"
15+
onkeydown="setTimeout(update,0)"/>
16+
<hr/>
17+
Hello <span id="output">{{yourname}}</span>!
18+
</body>
19+
</html>

src/Browser.js

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -136,9 +136,7 @@ function Browser(window, document, body, XHR, $log) {
136136
* @methodOf angular.service.$browser
137137
*/
138138
self.poll = function() {
139-
foreach(pollFns, function(pollFn){
140-
pollFn();
141-
});
139+
foreach(pollFns, function(pollFn){ pollFn(); });
142140
};
143141

144142
/**
@@ -319,22 +317,23 @@ function Browser(window, document, body, XHR, $log) {
319317

320318
/**
321319
* @workInProgress
322-
* @ngdoc
320+
* @ngdoc method
323321
* @name angular.service.$browser#defer
324322
* @methodOf angular.service.$browser
323+
* @param {function()} fn A function, who's execution should be defered.
324+
* @param {int=} [delay=0] of milliseconds to defer the function execution.
325325
*
326326
* @description
327-
* Executes a fn asynchroniously via `setTimeout(fn, 0)`.
327+
* Executes a fn asynchroniously via `setTimeout(fn, delay)`.
328328
*
329329
* Unlike when calling `setTimeout` directly, in test this function is mocked and instead of using
330330
* `setTimeout` in tests, the fns are queued in an array, which can be programaticaly flushed via
331331
* `$browser.defer.flush()`.
332332
*
333-
* @param {function()} fn A function, who's execution should be defered.
334333
*/
335-
self.defer = function(fn) {
334+
self.defer = function(fn, delay) {
336335
outstandingRequestCount++;
337-
setTimeout(function() { completeOutstandingRequest(fn); }, 0);
336+
setTimeout(function() { completeOutstandingRequest(fn); }, delay || 0);
338337
};
339338

340339
//////////////////////////////////////////////////////////////

src/Compiler.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ Template.prototype = {
7474
*/
7575
function retrieveScope(element) {
7676
var scope;
77+
element = jqLite(element);
7778
while (element && !(scope = element.data($$scope))) {
7879
element = element.parent();
7980
}

src/Injector.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,12 @@ function createInjector(providerScope, providers, cache) {
6767
}
6868
return returnValue;
6969
};
70-
}
70+
}
71+
72+
function injectService(services, fn) {
73+
return extend(fn, {$inject:services});;
74+
}
75+
76+
function injectUpdateView(fn) {
77+
return injectService(['$updateView'], fn);
78+
}

src/directives.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -423,14 +423,14 @@ angularDirective("ng:bind-attr", function(expression){
423423
* TODO: maybe we should consider allowing users to control event propagation in the future.
424424
*/
425425
angularDirective("ng:click", function(expression, element){
426-
return function(element){
426+
return injectUpdateView(function($updateView, element){
427427
var self = this;
428428
element.bind('click', function(event){
429429
self.$tryEval(expression, element);
430-
self.$root.$eval();
430+
$updateView();
431431
event.stopPropagation();
432432
});
433-
};
433+
});
434434
});
435435

436436

@@ -471,14 +471,14 @@ angularDirective("ng:click", function(expression, element){
471471
* server and reloading the current page).
472472
*/
473473
angularDirective("ng:submit", function(expression, element) {
474-
return function(element) {
474+
return injectUpdateView(function($updateView, element) {
475475
var self = this;
476476
element.bind('submit', function(event) {
477477
self.$tryEval(expression, element);
478-
self.$root.$eval();
478+
$updateView();
479479
event.preventDefault();
480480
});
481-
};
481+
});
482482
});
483483

484484

0 commit comments

Comments
 (0)