     else
       new Trix.LocationRange start, end
 
-    if locationRange = @setDOMRange(locationRange)
+    if domRange = @createDOMRangeFromLocationRange(locationRange)
+      # Selection#addRange is unreasonably slow in WebKit when performed in the
+      # same call stack as a mouse or key event so defer calling it.
+      # https://code.google.com/p/chromium/issues/detail?id=423170
+      # https://code.google.com/p/chromium/issues/detail?id=138439
+      defer => setDOMRange(domRange) if document.activeElement is @element
       @updateCurrentLocationRange(locationRange)
-      locationRange
 
   setLocationRangeFromPoint: (point) ->
     if locationRange = @getLocationRangeAtPoint(point)

  getDOMRange = ->
    getDOMSelection()?.getRangeAt(0)

  getClientRects = ->
    rects = getDOMRange()?.getClientRects()
    rects if rects?.length

      @currentLocationRange = locationRange
      @delegate?.locationRangeDidChange?(@currentLocationRange)

  createDOMRangeFromLocationRange: (locationRange) ->
    rangeStart = @findContainerAndOffsetForLocation(locationRange.start)
    rangeEnd = if locationRange.isCollapsed()
      rangeStart
    else
      @findContainerAndOffsetForLocation(locationRange.end)

    if rangeStart? and rangeEnd?
      range = document.createRange()
      range.setStart(rangeStart...)
      range.setEnd(rangeEnd...)
      range

  createLocationRangeFromDOMRange: (range) ->
    return unless range? and @rangeWithinElement(range)
