Cache images in custom module without caching entire render array I created a module that generates a slide show. This isn't using views, I'm manually loading nodes that contain images and placing them inside a render array in a block plugin. When running an audit in chrome I noticed a message


  The following resources are explicitly non-cacheable.


Then it lists all the images present in that slideshow. After reading this I understand that you can cache render arrays, but I still need it to be dynamic, so that the slideshow updates everytime a node is added. Also different slideshows are shown to different users so I need that dynamic as well.

Is there a way to cache only the images in a render array?
Blocks are cached by default in Drupal 8.  The image non-cachable warning isn't a drupal issue.  It's a false flag from chrome.  Because image derivatives in Drupal (those generated from an image style) have a query argument chrome thinks it's not cachable.

To test that your block plug-in is caching, you can put a die() statement inside the build method to test if the code runs on each page load.  If it is running on each page load, you can comment out elements until it does use cache.  Then it should run the code once and then on subsequent page loads it won't run the code.

To make sure your block is refreshed when certain nodes are cleared, you can add them to the cache tags in your build array.  This may happen automatically if you are pulling the render array from each image from the node it came from.  Otherwise you can add them in your code like this:

$build['image']['#cache']['tags'][] = 'node:123';


To test, clear the cache and reload the page.  Verify on the cache_render table that the block is cached and your tag is there.  

To test that editing that node updates the block, first update that node.  Then on the next page load of the page with your block, it should re-run the code for your block plugin.

To make sure the block is unique per user, you can add the user context to the cache contexts array

$build['image']['#cache']['contexts'][] = 'user';


To test, clear the cache, then reload the page with your block.  Check on the cache_render table that the cached item has user in the cid column.

Something like:

entity_view:block:my_block:[languages:language_interface]=en:[theme]=abilitylab_theme:[user]=123 


Then test the block with a different user, and there you go:  Unique block per user.