diff --git token.pages.inc token.pages.inc
index b57feb3..237e599 100644
--- token.pages.inc
+++ token.pages.inc
@@ -33,8 +33,11 @@ function theme_tree_table($variables) {
  * @ingroup themeable
  */
 function theme_token_tree($variables) {
+  $trees = &drupal_static(__FUNCTION__, array());
   $token_types = $variables['token_types'];
   $info = token_get_info();
+  drupal_add_js(drupal_get_path('module', 'token') . '/token.js');
+  drupal_add_css(drupal_get_path('module', 'token') . '/token.css');
 
   if ($token_types == 'all') {
     $token_types = array_keys($info['types']);
@@ -43,58 +46,73 @@ function theme_token_tree($variables) {
     $token_types = array_merge($token_types, token_get_global_token_types());
   }
 
-  $header = array(
-    t('Name'),
-    t('Token'),
-    t('Description'),
+  $options = array(
+    'flat' => TRUE,
+    'restricted' => $variables['show_restricted'],
+    'depth' => $variables['recursion_limit'],
   );
-  $rows = array();
 
-  foreach ($info['types'] as $type => $type_info) {
-    if (!in_array($type, $token_types)) {
-      continue;
-    }
-
-    if (count($token_types) > 1) {
-      $row = _token_token_tree_format_row($type, $type_info, TRUE);
-      unset($row['data']['value']);
-      $rows[] = $row;
-    }
+  $cid = 'theme_token_tree' . hash('sha256', serialize(array_merge($token_types, $options)));
+  if (isset($trees[$cid])) {
+    return $trees[$cid];
+  }
 
-    $options = array(
-      'flat' => TRUE,
-      'restricted' => $variables['show_restricted'],
-      'depth' => $variables['recursion_limit'],
+  if ($cached = cache_get($cid, 'cache_token')) {
+    // Add the tree table library to ensure that the table is rendered
+    // correctly if theme_tree_table() does not run.
+    drupal_add_library('token', 'treeTable');
+    $return = $trees[$cid] = $cached->data;
+  }
+  else {
+    $header = array(
+      t('Name'),
+      t('Token'),
+      t('Description'),
     );
-    $tree = token_build_tree($type, $options);
-    foreach ($tree as $token => $token_info) {
-      if (!empty($token_info['restricted']) && empty($variables['show_restricted'])) {
+    $rows = array();
+
+    foreach ($info['types'] as $type => $type_info) {
+      if (!in_array($type, $token_types)) {
         continue;
       }
-      if (count($token_types) > 1 && !isset($token_info['parent'])) {
-        $token_info['parent'] = $type;
+
+      if (count($token_types) > 1) {
+        $row = _token_token_tree_format_row($type, $type_info, TRUE);
+        unset($row['data']['value']);
+        $rows[] = $row;
+      }
+
+      $tree = token_build_tree($type, $options);
+      foreach ($tree as $token => $token_info) {
+        if (!empty($token_info['restricted']) && empty($variables['show_restricted'])) {
+          continue;
+        }
+        if (count($token_types) > 1 && !isset($token_info['parent'])) {
+          $token_info['parent'] = $type;
+        }
+        $row = _token_token_tree_format_row($token, $token_info);
+        unset($row['data']['value']);
+        $rows[] = $row;
       }
-      $row = _token_token_tree_format_row($token, $token_info);
-      unset($row['data']['value']);
-      $rows[] = $row;
     }
-  }
 
-  drupal_add_js(drupal_get_path('module', 'token') . '/token.js');
-  drupal_add_css(drupal_get_path('module', 'token') . '/token.css');
 
-  $table_options = array(
-    'header' => $header,
-    'rows' => $rows,
-    'attributes' => array('class' => array('token-tree')),
-    'empty' => t('No tokens available.'),
-  );
-  if ($variables['click_insert']) {
-    $table_options['caption'] = t('Click a token to insert it into the field you\'ve last clicked.');
-    $table_options['attributes']['class'][] = 'token-click-insert';
+    $table_options = array(
+      'header' => $header,
+      'rows' => $rows,
+      'attributes' => array('class' => array('token-tree')),
+      'empty' => t('No tokens available.'),
+    );
+    if ($variables['click_insert']) {
+      $table_options['caption'] = t('Click a token to insert it into the field you\'ve last clicked.');
+      $table_options['attributes']['class'][] = 'token-click-insert';
+    }
+
+    $trees[$cid] = $return = theme('tree_table', $table_options);
+    cache_set($cid, $return, 'cache_token');
   }
 
-  return theme('tree_table', $table_options);
+  return $return;
 }
 
 /**
