diff --git a/core/includes/common.inc b/core/includes/common.inc
index 0dbabd8..ba755b6 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -1292,6 +1292,12 @@ function drupal_http_header_attributes(array $attributes = array()) {
  *     internal to the site, $options['language'] is used to determine whether
  *     the link is "active", or pointing to the current page (the language as
  *     well as the path must match). This element is also used by url().
+ *   - 'set_active_class' (default FALSE): Whether l() should compare the $path,
+ *     language and query options to the current URL to determine whether the
+ *     link is "active", and if so, apply an "active" class to the link. It is
+ *     important to use this sparingly as any content containing a link
+ *     generated by l() with active class processing enabled is incompatible
+ *     with render caching elements on more than a per-page basis.
  *   - Additional $options elements used by the url() function.
  *
  * @return string
@@ -1313,6 +1319,7 @@ function l($text, $path, array $options = array()) {
     'query' => array(),
     'html' => FALSE,
     'language' => NULL,
+    'set_active_class' => FALSE,
   );
 
   // Add a hreflang attribute if we know the language of this link's url and
@@ -1321,35 +1328,39 @@ function l($text, $path, array $options = array()) {
     $variables['options']['attributes']['hreflang'] = $variables['options']['language']->id;
   }
 
-  // Because l() is called very often we statically cache values that require an
-  // extra function call.
-  static $drupal_static_fast;
-  if (!isset($drupal_static_fast['active'])) {
-    $drupal_static_fast['active'] = &drupal_static(__FUNCTION__);
-  }
-  $active = &$drupal_static_fast['active'];
-  if (!isset($active)) {
-    $active = array(
-      'path' => current_path(),
-      'front_page' => drupal_is_front_page(),
-      'language' => language(Language::TYPE_URL)->id,
-      'query' => Drupal::service('request')->query->all(),
-    );
-  }
-
-  // Determine whether this link is "active', meaning that it links to the
-  // current page. It is important that we stop checking "active" conditions if
-  // we know the link is not active. This helps ensure that l() remains fast.
-  // An active link's path is equal to the current path.
-  $variables['url_is_active'] = ($path == $active['path'] || ($path == '<front>' && $active['front_page']))
-  // The language of an active link is equal to the current language.
-  && (empty($variables['options']['language']) || $variables['options']['language']->id == $active['language'])
-  // The query parameters of an active link are equal to the current parameters.
-  && ($variables['options']['query'] == $active['query']);
+  // Process the active class if the 'set_active_class' option is not empty.
+  if (!empty($variables['options']['set_active_class'])) {
+    // Because l() is called very often we statically cache values that require
+    // an extra function call.
+    static $drupal_static_fast;
+    if (!isset($drupal_static_fast['active'])) {
+      $drupal_static_fast['active'] = &drupal_static(__FUNCTION__);
+    }
+    $active = &$drupal_static_fast['active'];
+    if (!isset($active)) {
+      $active = array(
+        'path' => current_path(),
+        'front_page' => drupal_is_front_page(),
+        'language' => language(Language::TYPE_URL)->id,
+        'query' => Drupal::service('request')->query->all(),
+      );
+    }
 
-  // Add the "active" class if appropriate.
-  if ($variables['url_is_active']) {
-    $variables['options']['attributes']['class'][] = 'active';
+    // Determine whether this link is "active', meaning that it links to the
+    // current page. It is important that we stop checking "active" conditions
+    // if we know the link is not active. This helps ensure that l() remains
+    // fast.
+    // An active link's path is equal to the current path.
+    $variables['url_is_active'] = ($path == $active['path'] || ($path == '<front>' && $active['front_page']))
+    // The language of an active link is equal to the current language.
+    && (empty($variables['options']['language']) || $variables['options']['language']->id == $active['language'])
+    // The query parameters of an active link are equal to the current parameters.
+    && ($variables['options']['query'] == $active['query']);
+
+    // Add the "active" class if appropriate.
+    if ($variables['url_is_active']) {
+      $variables['options']['attributes']['class'][] = 'active';
+    }
   }
 
   // Remove all HTML and PHP tags from a tooltip, calling expensive strip_tags()
diff --git a/core/includes/menu.inc b/core/includes/menu.inc
index 2486594..76ac367 100644
--- a/core/includes/menu.inc
+++ b/core/includes/menu.inc
@@ -1662,6 +1662,7 @@ function theme_menu_link(array $variables) {
   if ($element['#below']) {
     $sub_menu = drupal_render($element['#below']);
   }
+  $element['#localized_options']['set_active_class'] = TRUE;
   $output = l($element['#title'], $element['#href'], $element['#localized_options']);
   return '<li' . new Attribute($element['#attributes']) . '>' . $output . $sub_menu . "</li>\n";
 }
@@ -1697,7 +1698,7 @@ function theme_menu_local_task($variables) {
     $link['localized_options']['html'] = TRUE;
     $link_text = t('!local-task-title!active', array('!local-task-title' => $link['title'], '!active' => $active));
   }
-
+  $link['localized_options']['set_active_class'] = TRUE;
   return '<li' . (!empty($variables['element']['#active']) ? ' class="active"' : '') . '>' . l($link_text, $link['href'], $link['localized_options']) . '</li>';
 }
 
@@ -1720,6 +1721,7 @@ function theme_menu_local_action($variables) {
   );
   $link['localized_options']['attributes']['class'][] = 'button';
   $link['localized_options']['attributes']['class'][] = 'button-action';
+  $link['localized_options']['set_active_class'] = TRUE;
 
   $output = '<li>';
   $output .= l($link['title'], $link['href'], $link['localized_options']);
