From 7738eeeaccbc7e08c6b47d2499d8f7c3d958be0d Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Thu, 24 Jul 2014 17:23:04 -0700 Subject: [PATCH] Give the line-numbers div an opaque background for better GPU perf We sample both the background color of the editor and the gutter. If the gutter has an actual background color, we use it. Otherwise we fall back to the same background as the editor. --- spec/editor-component-spec.coffee | 12 ++++++++++++ src/editor-component.coffee | 22 +++++++++++++++++----- src/gutter-component.coffee | 8 ++++++-- 3 files changed, 35 insertions(+), 7 deletions(-) diff --git a/spec/editor-component-spec.coffee b/spec/editor-component-spec.coffee index 7f9626111..850e2e9b8 100644 --- a/spec/editor-component-spec.coffee +++ b/spec/editor-component-spec.coffee @@ -504,6 +504,18 @@ describe "EditorComponent", -> runSetImmediateCallbacks() expect(componentNode.querySelector('.line-numbers').offsetHeight).toBe componentNode.offsetHeight + it "applies the background color of the gutter or the editor to the line numbers to improve GPU performance", -> + gutterNode = componentNode.querySelector('.gutter') + lineNumbersNode = gutterNode.querySelector('.line-numbers') + {backgroundColor} = getComputedStyle(wrapperNode) + expect(lineNumbersNode.style.backgroundColor).toBe backgroundColor + + # favor gutter color if it's assigned + gutterNode.style.backgroundColor = 'rgb(255, 0, 0)' + advanceClock(component.domPollingInterval) + runSetImmediateCallbacks() + expect(lineNumbersNode.style.backgroundColor).toBe 'rgb(255, 0, 0)' + describe "when the editor.showLineNumbers config is false", -> it "doesn't render any line numbers", -> expect(component.refs.gutter).toBeDefined() diff --git a/src/editor-component.coffee b/src/editor-component.coffee index f9e015ad7..1f285f35c 100644 --- a/src/editor-component.coffee +++ b/src/editor-component.coffee @@ -25,6 +25,7 @@ EditorComponent = React.createClass visible: false autoHeight: false backgroundColor: null + gutterBackgroundColor: null pendingScrollTop: null pendingScrollLeft: null selectOnMouseMove: false @@ -92,12 +93,12 @@ EditorComponent = React.createClass className += ' has-selection' if hasSelection div {className, style, tabIndex: -1}, - if not mini and showLineNumbers + if @shouldRenderGutter() GutterComponent { ref: 'gutter', onMouseDown: @onGutterMouseDown, lineDecorations, defaultCharWidth, editor, renderedRowRange, maxLineNumberDigits, scrollViewHeight, scrollTop, scrollHeight, lineHeightInPixels, @pendingChanges, mouseWheelScreenRow, - @useHardwareAcceleration, @performedInitialMeasurement + @useHardwareAcceleration, @performedInitialMeasurement, @backgroundColor, @gutterBackgroundColor } div ref: 'scrollView', className: 'scroll-view', onMouseDown: @onMouseDown, @@ -158,6 +159,9 @@ EditorComponent = React.createClass {editor} = @props Math.max(1, Math.ceil(editor.getHeight() / editor.getLineHeightInPixels())) + shouldRenderGutter: -> + not @props.mini and @state.showLineNumbers + getInitialState: -> {} getDefaultProps: -> @@ -222,7 +226,7 @@ EditorComponent = React.createClass @updatesPaused = true @measureLineHeightAndDefaultCharWidth() @measureHeightAndWidth() - @sampleBackgroundColor() + @sampleBackgroundColors() @measureScrollbars() @props.editor.setVisible(true) @updatesPaused = false @@ -774,7 +778,7 @@ EditorComponent = React.createClass if @visible = @isVisible() if wasVisible @measureHeightAndWidth() - @sampleBackgroundColor() + @sampleBackgroundColors() else @performInitialMeasurement() @forceUpdate() @@ -816,13 +820,21 @@ EditorComponent = React.createClass clientWidth -= paddingLeft editor.setWidth(clientWidth) if clientWidth > 0 - sampleBackgroundColor: (suppressUpdate) -> + sampleBackgroundColors: (suppressUpdate) -> {parentView} = @props + {showLineNumbers} = @state {backgroundColor} = getComputedStyle(parentView.element) + if backgroundColor isnt @backgroundColor @backgroundColor = backgroundColor @requestUpdate() unless suppressUpdate + if @shouldRenderGutter() + gutterBackgroundColor = getComputedStyle(@refs.gutter.getDOMNode()).backgroundColor + if gutterBackgroundColor isnt @gutterBackgroundColor + @gutterBackgroundColor = gutterBackgroundColor + @requestUpdate() unless suppressUpdate + measureLineHeightAndDefaultCharWidthIfNeeded: (prevState) -> if not isEqualForProperties(prevState, @state, 'lineHeight', 'fontSize', 'fontFamily') if @visible diff --git a/src/gutter-component.coffee b/src/gutter-component.coffee index ede951657..e9eeddaf9 100644 --- a/src/gutter-component.coffee +++ b/src/gutter-component.coffee @@ -16,12 +16,16 @@ GutterComponent = React.createClass measuredWidth: null render: -> - {scrollHeight, scrollViewHeight, onMouseDown} = @props + {scrollHeight, scrollViewHeight, onMouseDown, backgroundColor, gutterBackgroundColor} = @props + + if gutterBackgroundColor isnt 'rbga(0, 0, 0, 0)' + backgroundColor = gutterBackgroundColor div className: 'gutter', onClick: @onClick, onMouseDown: onMouseDown, div className: 'line-numbers', ref: 'lineNumbers', style: height: Math.max(scrollHeight, scrollViewHeight) WebkitTransform: @getTransform() + backgroundColor: backgroundColor getTransform: -> {scrollTop, useHardwareAcceleration} = @props @@ -47,7 +51,7 @@ GutterComponent = React.createClass shouldComponentUpdate: (newProps) -> return true unless isEqualForProperties(newProps, @props, 'renderedRowRange', 'scrollTop', 'lineHeightInPixels', 'mouseWheelScreenRow', 'lineDecorations', - 'scrollViewHeight', 'useHardwareAcceleration' + 'scrollViewHeight', 'useHardwareAcceleration', 'backgroundColor', 'gutterBackgroundColor' ) {renderedRowRange, pendingChanges, lineDecorations} = newProps