Index: src/wp-admin/js/editor-expand.js
===================================================================
--- src/wp-admin/js/editor-expand.js	(revision 38285)
+++ src/wp-admin/js/editor-expand.js	(working copy)
@@ -16,6 +16,8 @@
 			$textTop = $( '#ed_toolbar' ),
 			$textEditor = $( '#content' ),
 			textEditor = $textEditor[0],
+			$textEditorClone = $textEditor.clone().attr({ id: 'content-clone', name: null }),
+			textEditorClone = $textEditorClone[0],
 			oldTextLength = 0,
 			$bottom = $( '#post-status-info' ),
 			$menuBar = $(),
@@ -53,6 +55,47 @@
 				sideSortablesHeight: 0
 			};
 
+		var shrinkTextarea = window._.throttle( function() {
+			var top = window.scrollTop;
+			var height = parseInt( textEditor.style.height, 10 );
+
+			textEditorClone.value = textEditor.value;
+
+			if ( textEditorClone.scrollHeight > autoresizeMinHeight ) {
+				textEditor.style.height = textEditorClone.scrollHeight + 'px';
+			} else if ( textEditorClone.scrollHeight < height ) {
+				textEditor.style.height = autoresizeMinHeight + 'px';
+			}
+
+			// Prevent scroll-jumping in Firefox and IE.
+			window.scrollTop = top;
+
+			if ( textEditor.scrollHeight < height ) {
+				adjust();
+			}
+		}, 500 );
+
+		function textEditorResize() {
+			var length = textEditor.value.length;
+
+			if ( mceEditor && ! mceEditor.isHidden() ) {
+				return;
+			}
+
+			if ( ! mceEditor && initialMode === 'tinymce' ) {
+				return;
+			}
+
+			if ( length < oldTextLength ) {
+				shrinkTextarea();
+			} else if ( parseInt( textEditor.style.height, 10 ) < textEditor.scrollHeight ) {
+				textEditor.style.height = Math.ceil( textEditor.scrollHeight ) + 'px';
+				adjust();
+			}
+
+			oldTextLength = length;
+		}
+
 		function getHeights() {
 			var windowWidth = $window.width();
 
@@ -75,43 +118,9 @@
 			}
 		}
 
-		function textEditorResize() {
-			if ( mceEditor && ! mceEditor.isHidden() ) {
-				return;
-			}
+		// Append the cloned textarea after the "real" one and move it off screen.
+		$textEditor.after( $textEditorClone.css({ position: 'absolute', left: '-10000em' }) );
 
-			if ( ! mceEditor && initialMode === 'tinymce' ) {
-				return;
-			}
-
-			var length = textEditor.value.length;
-			var height = parseInt( textEditor.style.height, 10 );
-			var top = window.scrollTop;
-
-			if ( length < oldTextLength ) {
-				// textEditor.scrollHeight is not adjusted until the next line.
-				textEditor.style.height = 'auto';
-
-				if ( textEditor.scrollHeight > autoresizeMinHeight ) {
-					textEditor.style.height = textEditor.scrollHeight + 'px';
-				} else {
-					textEditor.style.height = autoresizeMinHeight + 'px';
-				}
-
-				// Prevent scroll-jumping in Firefox and IE.
-				window.scrollTop = top;
-
-				if ( textEditor.scrollHeight < height ) {
-					adjust();
-				}
-			} else if ( height < textEditor.scrollHeight ) {
-				textEditor.style.height = textEditor.scrollHeight + 'px';
-				adjust();
-			}
-
-			oldTextLength = length;
-		}
-
 		// We need to wait for TinyMCE to initialize.
 		$document.on( 'tinymce-editor-init.editor-expand', function( event, editor ) {
 			var VK = window.tinymce.util.VK,
Index: src/wp-includes/script-loader.php
===================================================================
--- src/wp-includes/script-loader.php	(revision 38285)
+++ src/wp-includes/script-loader.php	(working copy)
@@ -563,7 +563,7 @@
 			'suggestedImgAlt' => __( 'Suggested image #%d' ),
 		) );
 
-		$scripts->add( 'editor-expand', "/wp-admin/js/editor-expand$suffix.js", array( 'jquery' ), false, 1 );
+		$scripts->add( 'editor-expand', "/wp-admin/js/editor-expand$suffix.js", array( 'jquery', 'underscore' ), false, 1 );
 
 		$scripts->add( 'link', "/wp-admin/js/link$suffix.js", array( 'wp-lists', 'postbox' ), false, 1 );
 
