Please explain caching in complex render arrays The Scenario

In hook_block_configure(), I'm displaying a configuration form to users that is represented by a fairly complicated render array. The purpose of the form is to allow users to configure an arbitrary number of buttons as part of a button set.


Each button is individually configurable.
As part of each button's configuration, the user can select an icon from a list of icons. This list is mostly static, although users can upload additional icons on a per-site basis.
This module is for use in a Drupal multi-site configuration, where each site can field one or more of these button sets.
Each button configuration also features a preview rendering of the button.
There is a single rendering of the entire button set on the form as well.


The Question

How best to use caching within this render array? Is it possible to separately cache portions of the render array? For instance, could I separately cache each button configuration, as well as the icons and the rendered buttons?

While solutions to this exact situation would be appreciated, I'm actually more interested in insight into the finer points of adding caching to a complex render array. I believe that I've read most of the introductory documentation on caching that is readily available on the Internet, but haven't found much regarding more involved render arrays.

Sources

I found these sources to be very useful in attaining a basic understanding of caching in Drupal:


https://www.lullabot.com/articles/a-beginners-guide-to-caching-data-in-drupal-7
http://omnifik.com/blog/render-arrays-and-cache-drupal-7


Thanks to all for your insights!
http://omnifik.com/blog/render-arrays-and-cache-drupal-7 is an excellent resource, I use it as a guide when caching render arrays. The nice thing about render arrays is they are recursive. So for the hook_menu page callback you can have that function return mutiple items. As an example I have the page callback function looks like this

function my_page_callback() {
  // Form dumps values in the URL, act on them.
  $input_values_from_form = drupal_get_query_parameters();

  // Get form with URL values set in the form as defaults.
  $input_form = drupal_get_form('my_form', $input_value_from_form);

  // Build table render array.
  $table = array(
    '#theme' =&gt; 'table',
    '#pre_render' =&gt; array('my_table_pre_render'),
    '#header' =&gt; $header,
    '#rows' =&gt; $rows,
    '#links' =&gt; $links,
    '#url_queries' =&gt; $url_queries,
    '#filters' =&gt; $filters,
    '#entity_types' =&gt; $entity_types,
    '#missing_info' =&gt; $missing_info,
    '#attributes' =&gt; array('class' =&gt; array('table', 'table-striped')),
    '#attached' =&gt; array('css' =&gt; array(drupal_get_path('module', 'my_module') . '/css/table.css' =&gt; array('type' =&gt; 'file'))),
    '#cache' =&gt; array(
      'keys' =&gt; $input_values_from_form,
      // Cache this for 1 hour.
      'expire' =&gt; REQUEST_TIME + 3600,
    ),
  );

  // Put them together.
  $page_array = array($input_form, $table);

  return $page_array;
}


So this will render the input form first and the table second. Using this you can in theory split up your complex page into many smaller parts caching each array separately. 

In the above example theme_table does most of the work but some other parts get used inside my_table_pre_render so the '#theme' =&gt; 'table', here is a complex example but it shows how to do this.

Pick the keys for each render array wisely as in make it relevant only to that part of the page; see https://api.drupal.org/api/drupal/includes!common.inc/function/drupal_render_cid_create/7.x