Index: src/wp-includes/js/heartbeat.js
===================================================================
--- src/wp-includes/js/heartbeat.js	(revision 26243)
+++ src/wp-includes/js/heartbeat.js	(working copy)
@@ -34,8 +34,8 @@
 	var Heartbeat = function() {
 		var $document = $(document),
 			settings = {
-				// Used to stop the "beat"
-				isRunning: true,
+				// Suspend/resume
+				suspended: false,
 
 				// Current screen id, defaults to the JS global 'pagenow' when present (in the admin) or 'front'
 				screenId: '',
@@ -145,7 +145,12 @@
 				focused();
 			}).on( 'unload.wp-heartbeat', function() {
 				// Don't connect any more
-				settings.isRunning = false;
+				settings.suspended = true;
+
+				// Abort the last request if not completed
+				if ( settings.xhr && settings.xhr.readyState !== 4 ) {
+					settings.xhr.abort();
+				}
 			});
 
 			// Check for user activity every 30 seconds.
@@ -274,7 +279,7 @@
 
 			// If the connection to the server is slower than the interval,
 			// heartbeat connects as soon as the previous connection's response is received.
-			if ( settings.connecting ) {
+			if ( settings.connecting || settings.suspended ) {
 				return;
 			}
 
@@ -351,7 +356,7 @@
 			var delta = time() - settings.lastTick,
 				interval = settings.mainInterval;
 
-			if ( ! settings.isRunning ) {
+			if ( settings.suspended ) {
 				return;
 			}
 
@@ -403,6 +408,9 @@
 			clearFocusTimers();
 			settings.userActivity = time();
 
+			// Resume if suspended
+			settings.suspended = false;
+
 			if ( ! settings.hasFocus ) {
 				settings.hasFocus = true;
 				scheduleNextTick();
@@ -513,6 +521,11 @@
 				blurred();
 			}
 
+			if ( lastActive > 1800000 ) {
+				// Suspend after 30 min. of inactivity
+				settings.suspended = true;
+			}
+
 			if ( ! settings.userActivityEvents ) {
 				$document.on( 'mouseover.wp-heartbeat-active keyup.wp-heartbeat-active', function(){ userIsActive(); } );
 
