summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjamescook@chromium.org <jamescook@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-06-13 19:58:05 +0000
committerjamescook@chromium.org <jamescook@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-06-13 19:58:05 +0000
commit1baaab24edf8829e1aa80456b744624327562678 (patch)
tree387666f70e77eb9a6dc318642fdba5b530f9e237
parent199adec389d37c15fd30e1f998292774cc81c514 (diff)
downloadchromium_src-1baaab24edf8829e1aa80456b744624327562678.zip
chromium_src-1baaab24edf8829e1aa80456b744624327562678.tar.gz
chromium_src-1baaab24edf8829e1aa80456b744624327562678.tar.bz2
Merge 203338 "Reduce CPU usage by removing the timer from Files...."
> Reduce CPU usage by removing the timer from Files.app's scrollbars. > > The new fancy scrollbars were polling for size and content changes using a timer. This caused some cpu usage. This change improves it by listening to dom changes and also avoiding updating the dom if it is not necessary. > > Updating in case of resizing is done by emiting a relayout event on the scrollable area. > > Along the way, lots of resizing code has been moved from file_manager.js to file_table.js and file_grid.js. > > TEST=Run Files.app, resize window, check if scrollbars work fine. > BUG=245163 > > Review URL: https://chromiumcodereview.appspot.com/15648011 TBR=mtomasz@chromium.org Review URL: https://codereview.chromium.org/16987005 git-svn-id: svn://svn.chromium.org/chrome/branches/1500/src@206145 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/resources/file_manager/js/file_grid.js18
-rw-r--r--chrome/browser/resources/file_manager/js/file_manager.js19
-rw-r--r--chrome/browser/resources/file_manager/js/file_table.js19
-rw-r--r--chrome/browser/resources/file_manager/js/scrollbar.js70
-rw-r--r--chrome/browser/resources/file_manager/js/sidebar.js7
5 files changed, 102 insertions, 31 deletions
diff --git a/chrome/browser/resources/file_manager/js/file_grid.js b/chrome/browser/resources/file_manager/js/file_grid.js
index 55f1b76..d8a6e8d 100644
--- a/chrome/browser/resources/file_manager/js/file_grid.js
+++ b/chrome/browser/resources/file_manager/js/file_grid.js
@@ -61,6 +61,24 @@ FileGrid.prototype.updateListItemsMetadata = function(type, props) {
};
/**
+ * Redraws the UI. Skips multiple consecutive calls.
+ */
+FileGrid.prototype.relayout = function() {
+ if (this.resizeGridTimer_) {
+ clearTimeout(this.resizeGridTimer_);
+ this.resizeGridTimer_ = null;
+ }
+ this.resizeGridTimer_ = setTimeout(function() {
+ this.startBatchUpdates();
+ this.columns = 0;
+ this.redraw();
+ cr.dispatchSimpleEvent(this, 'relayout');
+ this.endBatchUpdates();
+ this.resizeGridTimer_ = null;
+ }.bind(this), 100);
+};
+
+/**
* Decorates thumbnail.
* @param {HTMLElement} li List item.
* @param {Entry} entry Entry to render a thumbnail for.
diff --git a/chrome/browser/resources/file_manager/js/file_manager.js b/chrome/browser/resources/file_manager/js/file_manager.js
index 7ab0fc6..70c7102 100644
--- a/chrome/browser/resources/file_manager/js/file_manager.js
+++ b/chrome/browser/resources/file_manager/js/file_manager.js
@@ -1418,22 +1418,9 @@ DialogType.isModal = function(type) {
* @private
*/
FileManager.prototype.onResize_ = function() {
- if (this.listType_ == FileManager.ListType.THUMBNAIL) {
- var g = this.grid_;
- g.startBatchUpdates();
- setTimeout(function() {
- g.columns = 0;
- g.redraw();
- g.endBatchUpdates();
- }, 0);
- } else {
- if (util.platform.newUI()) {
- if (this.table_.clientWidth > 0)
- this.table_.normalizeColumns();
- }
- this.table_.redraw();
- this.volumeList_.redraw();
- }
+ this.table_.relayout();
+ this.grid_.relayout();
+ this.directoryTree_.relayout();
if (!util.platform.newUI())
this.breadcrumbs_.truncate();
diff --git a/chrome/browser/resources/file_manager/js/file_table.js b/chrome/browser/resources/file_manager/js/file_table.js
index 92afbd4..72a39c4 100644
--- a/chrome/browser/resources/file_manager/js/file_table.js
+++ b/chrome/browser/resources/file_manager/js/file_table.js
@@ -659,6 +659,25 @@ FileTable.prototype.renderIconType_ = function(entry, columnId, table) {
};
/**
+ * Redraws the UI. Skips multiple consecutive calls.
+ */
+FileTable.prototype.relayout = function() {
+ if (this.resizeTableTimer_) {
+ clearTimeout(this.resizeTableTimer_);
+ this.resizeTableTimer_ = null;
+ }
+ this.resizeTableTimer_ = setTimeout(function() {
+ if (util.platform.newUI()) {
+ if (this.clientWidth > 0)
+ this.normalizeColumns();
+ }
+ this.redraw();
+ cr.dispatchSimpleEvent(this.list, 'relayout');
+ this.resizeTableTimer_ = null;
+ }.bind(this), 100);
+};
+
+/**
* Decorates (and wire up) a checkbox to be used in either a detail or a
* thumbnail list item.
* @param {HTMLInputElement} input Element to decorate.
diff --git a/chrome/browser/resources/file_manager/js/scrollbar.js b/chrome/browser/resources/file_manager/js/scrollbar.js
index b478f0c..24478d8 100644
--- a/chrome/browser/resources/file_manager/js/scrollbar.js
+++ b/chrome/browser/resources/file_manager/js/scrollbar.js
@@ -70,10 +70,6 @@ ScrollBar.prototype.decorate = function() {
this.onButtonPressed_.bind(this));
window.addEventListener('mouseup', this.onMouseUp_.bind(this));
window.addEventListener('mousemove', this.onMouseMove_.bind(this));
-
- // Unfortunately we need to pool, since we can't easily detect resizing
- // and content changes.
- setInterval(this.redraw_.bind(this), 50);
};
/**
@@ -83,7 +79,10 @@ ScrollBar.prototype.decorate = function() {
ScrollBar.prototype.attachToView = function(view) {
this.view_ = view;
this.view_.addEventListener('scroll', this.onScroll_.bind(this));
- this.redraw_();
+ this.view_.addEventListener('relayout', this.onRelayout_.bind(this));
+ this.domObserver_ = new WebKitMutationObserver(this.onDomChanged_.bind(this));
+ this.domObserver_.observe(this.view_, {subtree: true, attributes: true});
+ this.onRelayout_();
};
/**
@@ -91,6 +90,19 @@ ScrollBar.prototype.attachToView = function(view) {
* @private
*/
ScrollBar.prototype.onScroll_ = function() {
+ this.scrollTop_ = this.view_.scrollTop;
+ this.redraw_();
+};
+
+/**
+ * Relayout handler.
+ * @private
+ */
+ScrollBar.prototype.onRelayout_ = function() {
+ this.scrollHeight_ = this.view_.scrollHeight;
+ this.clientHeight_ = this.view_.clientHeight;
+ this.offsetTop_ = this.view_.offsetTop;
+ this.scrollTop_ = this.view_.scrollTop;
this.redraw_();
};
@@ -134,19 +146,35 @@ ScrollBar.prototype.onMouseMove_ = function(event) {
this.onMouseUp_(event);
return;
}
- var clientSize = this.view_.clientHeight;
- var totalSize = this.view_.scrollHeight;
+ var clientSize = this.clientHeight_;
+ var totalSize = this.scrollHeight_;
var buttonSize = Math.max(50, clientSize / totalSize * clientSize);
var buttonPosition = this.buttonPressedPosition_ +
(event.screenY - this.buttonPressedEvent_.screenY);
var scrollPosition = totalSize * (buttonPosition / clientSize);
+ this.scrollTop_ = scrollPosition;
this.view_.scrollTop = scrollPosition;
this.redraw_();
};
/**
+ * Handles changed in Dom by redrawing the scrollbar. Ignores consecutive calls.
+ * @private
+ */
+ScrollBar.prototype.onDomChanged_ = function() {
+ if (this.domChangedTimer_) {
+ clearTimeout(this.domChangedTimer_);
+ this.domChangedTimer_ = null;
+ }
+ this.domChangedTimer_ = setTimeout(function() {
+ this.onRelayout_();
+ this.domChangedTimer_ = null;
+ }.bind(this), 50);
+};
+
+/**
* Redraws the scrollbar.
* @private
*/
@@ -154,17 +182,29 @@ ScrollBar.prototype.redraw_ = function() {
if (!this.view_)
return;
- var clientSize = this.view_.clientHeight;
- var clientTop = this.view_.offsetTop;
- var scrollPosition = this.view_.scrollTop;
- var totalSize = this.view_.scrollHeight;
-
- this.hidden = totalSize <= clientSize;
+ var clientSize = this.clientHeight_;
+ var clientTop = this.offsetTop_;
+ var scrollPosition = this.scrollTop_;
+ var totalSize = this.scrollHeight_;
+ var hidden = totalSize <= clientSize;
var buttonSize = Math.max(50, clientSize / totalSize * clientSize);
var buttonPosition = scrollPosition / (totalSize - clientSize) *
(clientSize - buttonSize);
+ var buttonTop = buttonPosition + clientTop;
+
+ var time = Date.now();
+ if (this.hidden != hidden ||
+ this.lastButtonTop_ != buttonTop ||
+ this.lastButtonSize_ != buttonSize) {
+ requestAnimationFrame(function() {
+ this.hidden = hidden;
+ this.button_.style.top = buttonTop + 'px';
+ this.button_.style.height = buttonSize + 'px';
+ console.log(Date.now() - time);
+ }.bind(this));
+ }
- this.button_.style.top = buttonPosition + clientTop + 'px';
- this.button_.style.height = buttonSize + 'px';
+ this.lastButtonTop_ = buttonTop;
+ this.lastButtonSize_ = buttonSize;
};
diff --git a/chrome/browser/resources/file_manager/js/sidebar.js b/chrome/browser/resources/file_manager/js/sidebar.js
index 28aec0b..23ec5f9 100644
--- a/chrome/browser/resources/file_manager/js/sidebar.js
+++ b/chrome/browser/resources/file_manager/js/sidebar.js
@@ -761,3 +761,10 @@ DirectoryTree.prototype.clearTree_ = function(redraw) {
cr.dispatchSimpleEvent(this, 'content-updated');
}
};
+
+/**
+ * Updates the UI after the layout has changed.
+ */
+DirectoryTree.prototype.relayout = function() {
+ cr.dispatchSimpleEvent(this, 'relayout');
+};