     @updateCustomGutterDecorationState()
     @updating = false
 
+    @resetTrackedUpdates()
     @state
 
+  resetTrackedUpdates: ->
+    @shouldUpdateDecorations = false
+
+  invalidateState: ->
+    @shouldUpdateDecorations = true
+
   observeModel: ->
-    @disposables.add @model.onDidChange => @emitDidUpdateState()
-    @disposables.add @model.onDidUpdateDecorations => @emitDidUpdateState()
+    @disposables.add @model.onDidChange =>
+      @shouldUpdateDecorations = true
+      @emitDidUpdateState()
+
+    @disposables.add @model.onDidUpdateDecorations =>
+      @shouldUpdateDecorations = true
+      @emitDidUpdateState()
+
     @disposables.add @model.onDidChangeGrammar(@didChangeGrammar.bind(this))
-    @disposables.add @model.onDidChangePlaceholderText => @emitDidUpdateState()
-    @disposables.add @model.onDidChangeMini => @emitDidUpdateState()
-    @disposables.add @model.onDidChangeLineNumberGutterVisible => @emitDidUpdateState()
+    @disposables.add @model.onDidChangePlaceholderText =>
+      @emitDidUpdateState()
+
+    @disposables.add @model.onDidChangeMini =>
+      @shouldUpdateDecorations = true
+      @emitDidUpdateState()
+
+    @disposables.add @model.onDidChangeLineNumberGutterVisible =>
+      @emitDidUpdateState()
 
     @disposables.add @model.onDidAddCursor(@didAddCursor.bind(this))
     @disposables.add @model.onDidRequestAutoscroll(@requestAutoscroll.bind(this))

    @pendingScrollLogicalPosition = null if overrideScroll
    @pendingScrollTop = scrollTop

    @emitDidUpdateState()

  getScrollTop: ->

    @observeModel()
    @observeConfig()
    @buildState()
    @invalidateState()
    @startBlinkingCursors() if @focused
    @startReflowing() if @continuousReflow
    @updating = false
