From 27ca94d2a2610110df54c86da2ec462bd68ccbc7 Mon Sep 17 00:00:00 2001 From: redhoodsu Date: Fri, 1 Nov 2019 17:43:03 +0800 Subject: [PATCH] perf(console): rendering --- src/Console/Logger.js | 57 ++++++-- src/Console/Logger.scss | 314 ++++++++++++++++++++-------------------- src/style/style.scss | 1 - 3 files changed, 201 insertions(+), 171 deletions(-) diff --git a/src/Console/Logger.js b/src/Console/Logger.js index f97a3c1..1458227 100644 --- a/src/Console/Logger.js +++ b/src/Console/Logger.js @@ -36,7 +36,9 @@ export default class Logger extends Emitter { this._$fakeEl = $container.find('ul.eruda-fake-logs') this._fakeEl = this._$fakeEl.get(0) this._$topSpace = $container.find('.eruda-top-space') + this._topSpace = this._$topSpace.get(0) this._$bottomSpace = $container.find('.eruda-bottom-space') + this._bottomSpace = this._$bottomSpace.get(0) this._topSpaceHeight = 0 this._bottomSpaceHeight = 0 this._logs = [] @@ -53,7 +55,9 @@ export default class Logger extends Emitter { this._isAtBottom = true this._groupStack = new Stack() - this.renderViewport = throttle(force => this._renderViewport(force), 16) + this.renderViewport = throttle(force => { + this._renderViewport(force) + }, 16) // https://developers.google.cn/web/tools/chrome-devtools/console/utilities this._global = { @@ -352,7 +356,6 @@ export default class Logger extends Emitter { } this._attachLog(log) - this._updateLogSize(log) this.emit('insert', log) @@ -364,18 +367,21 @@ export default class Logger extends Emitter { } _updateTopSpace(height) { this._topSpaceHeight = height - this._$topSpace.css({ height }) + this._topSpace.style.height = height + 'px' } _updateBottomSpace(height) { this._bottomSpaceHeight = height - this._$bottomSpace.css({ height }) + this._bottomSpace.style.height = height + 'px' } _updateLogSize(log) { - if (this._fakeEl.offsetParent === null) return + const fakeEl = this._fakeEl + if (isHidden(this._fakeEl)) return if (!log.isAttached()) { - this._fakeEl.appendChild(log.el) + fakeEl.appendChild(log.el) log.updateSize() - this._fakeEl.removeChild(log.el) + if (fakeEl.children > 100) { + fakeEl.innerHTML = '' + } return } log.updateSize() @@ -566,7 +572,7 @@ export default class Logger extends Emitter { } _renderViewport(force = true) { const container = this._container - if (container.offsetParent === null) return + if (isHidden(container)) return const { scrollTop, offsetWidth, offsetHeight } = container let top = scrollTop let bottom = scrollTop + offsetHeight @@ -590,17 +596,32 @@ export default class Logger extends Emitter { let bottomSpaceHeight = 0 let currentHeight = 0 - this._$el.html('') - const frag = document.createDocumentFragment() - for (let i = 0, len = displayLogs.length; i < len; i++) { + this._el.innerHTML = '' + const len = displayLogs.length + + const fakeEl = this._fakeEl + const fakeFrag = document.createDocumentFragment() + const logs = [] + for (let i = 0; i < len; i++) { const log = displayLogs[i] - const { el } = log - let { height } = log - const { width } = log + const { width, height } = log if (height === 0 || width !== offsetWidth) { - this._updateLogSize(log) - height = log.height + fakeFrag.appendChild(log.el) + logs.push(log) } + } + if (logs.length > 0) { + fakeEl.appendChild(fakeFrag) + for (let i = 0, len = logs.length; i < len; i++) { + logs[i].updateSize() + } + fakeEl.innerHTML = '' + } + + const frag = document.createDocumentFragment() + for (let i = 0; i < len; i++) { + const log = displayLogs[i] + const { el, height } = log if (currentHeight > bottom) { bottomSpaceHeight += height @@ -636,3 +657,7 @@ export default class Logger extends Emitter { } } } + +function isHidden(el) { + return el.offsetParent === null +} diff --git a/src/Console/Logger.scss b/src/Console/Logger.scss index a7040a9..8302342 100644 --- a/src/Console/Logger.scss +++ b/src/Console/Logger.scss @@ -9,6 +9,7 @@ @include overflow-auto(y); height: 100%; position: relative; + will-change: scroll-position; } .fake-logs { position: absolute; @@ -17,174 +18,179 @@ pointer-events: none; visibility: hidden; width: 100%; + * { + overflow: hidden; + color: black; + position: static; + } } .logs { font-size: $font-size; padding-top: 1px; - .log-container { - box-sizing: content-box; + } + .log-container { + box-sizing: content-box; + } + .header { + white-space: nowrap; + display: flex; + font-size: $font-size-s; + color: $gray; + border-top: 1px solid transparent; + border-bottom: 1px solid $gray-light; + .time-container { + @include overflow-auto(x); + padding: 3px $padding; } - .header { - white-space: nowrap; - display: flex; - font-size: $font-size-s; - color: $gray; - border-top: 1px solid transparent; - border-bottom: 1px solid $gray-light; - .time-container { - @include overflow-auto(x); - padding: 3px $padding; + } + .nesting-level { + width: 14px; + flex-shrink: 0; + margin-top: -1px; + margin-bottom: -1px; + position: relative; + border-right: 1px solid $gray; + &.group-closed::before { + content: ''; + } + &::before { + border-bottom: 1px solid #a5a5a5; + position: absolute; + top: 0; + left: 0; + margin-left: 100%; + width: 5px; + height: 100%; + box-sizing: border-box; + } + } + .log-item { + position: relative; + display: flex; + @include clear-float(); + border-top: 1px solid transparent; + border-bottom: 1px solid $gray-light; + margin-top: -1px; + min-height: 24px; + a { + color: $blue !important; + } + .icon-container { + padding-top: 2px; + margin: 0 -6px 0 $padding; + .icon { + line-height: 20px; + font-size: 12px; + color: $gray-dark; + position: relative; + } + .icon-caret-right, + .icon-caret-down { + left: -2px; + color: $gray; + } + .icon-arrow-right { + color: $blue; + } + .icon-info { + color: $blue; + } + .icon-error { + color: $red; + } + .icon-warn { + top: -1px; + color: $yellow-dark; } } - .nesting-level { - width: 14px; - flex-shrink: 0; - margin-top: -1px; - margin-bottom: -1px; - position: relative; - border-right: 1px solid $gray; - &.group-closed::before { - content: ''; - } - &::before { - border-bottom: 1px solid #a5a5a5; - position: absolute; - top: 0; - left: 0; - margin-left: 100%; - width: 5px; - height: 100%; - box-sizing: border-box; + .count { + background: $blue; + padding: 2px 4px; + color: #fff; + border-radius: 10px; + float: left; + margin: 3px -6px 0 $padding; + } + .log-content-wrapper { + flex: 1; + overflow: hidden; + } + .log-content { + padding: 3px 0; + margin: 0 $padding; + @include overflow-auto(x); + white-space: pre-wrap; + user-select: text; + * { + user-select: text; } } - .log-item { - position: relative; - display: flex; - @include clear-float(); - border-top: 1px solid transparent; - border-bottom: 1px solid $gray-light; - margin-top: -1px; - min-height: 24px; - a { - color: $blue !important; + &.input { + background: #fff; + } + &.html, + &.table { + table { + width: 100%; + background: #fff; + border-collapse: collapse; + box-shadow: $box-shadow; + border-radius: $border-radius; + overflow: hidden; + th { + background: $blue; + color: #fff; + } + th, + td { + border-left: 1px solid $gray; + padding: 3px $padding; + &:first-child { + border-left: none !important; + } + } + tr:nth-child(even) { + background: $gray-light; + } } - .icon-container { - padding-top: 2px; - margin: 0 -6px 0 $padding; - .icon { - line-height: 20px; - font-size: 12px; - color: $gray-dark; - position: relative; - } - .icon-caret-right, - .icon-caret-down { - left: -2px; - color: $gray; - } - .icon-arrow-right { - color: $blue; - } - .icon-info { - color: $blue; - } - .icon-error { - color: $red; - } - .icon-warn { - top: -1px; - color: $yellow-dark; - } + .blue { + color: $blue; + } + } + &.error { + z-index: 50; + background: $red-light; + color: $red; + border-top: 1px solid $red; + border-bottom: 1px solid $red; + .stack { + padding-left: 1.2em; + white-space: nowrap; } .count { - background: $blue; - padding: 2px 4px; - color: #fff; - border-radius: 10px; - float: left; - margin: 3px -6px 0 $padding; - } - .log-content-wrapper { - flex: 1; - overflow: hidden; - } - .log-content { - padding: 3px 0; - margin: 0 $padding; - @include overflow-auto(x); - white-space: pre-wrap; - user-select: text; - * { - user-select: text; - } - } - &.input { - background: #fff; - } - &.html, - &.table { - table { - width: 100%; - background: #fff; - border-collapse: collapse; - box-shadow: $box-shadow; - border-radius: $border-radius; - overflow: hidden; - th { - background: $blue; - color: #fff; - } - th, - td { - border-left: 1px solid $gray; - padding: 3px $padding; - &:first-child { - border-left: none !important; - } - } - tr:nth-child(even) { - background: $gray-light; - } - } - .blue { - color: $blue; - } - } - &.error { - z-index: 50; - background: $red-light; - color: $red; - border-top: 1px solid $red; - border-bottom: 1px solid $red; - .stack { - padding-left: 1.2em; - white-space: nowrap; - } - .count { - background: $red; - } - } - &.debug { - z-index: 20; - } - &.warn { - z-index: 40; - background: #fffbe6; - border-top: 1px solid $yellow; - border-bottom: 1px solid $yellow; - } - &.info { - z-index: 30; - } - &.output { - color: $gray-dark; - } - &.group, - &.groupCollapsed { - color: #222; - font-weight: bold; + background: $red; } } + &.debug { + z-index: 20; + } + &.warn { + z-index: 40; + background: #fffbe6; + border-top: 1px solid $yellow; + border-bottom: 1px solid $yellow; + } + &.info { + z-index: 30; + } + &.output { + color: $gray-dark; + } + &.group, + &.groupCollapsed { + color: #222; + font-weight: bold; + } } } } diff --git a/src/style/style.scss b/src/style/style.scss index c4ccb14..2524df6 100644 --- a/src/style/style.scss +++ b/src/style/style.scss @@ -3,7 +3,6 @@ .container { pointer-events: none; - will-change: transform; position: fixed; left: 0; top: 0;