0

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?

2

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.

  • So if I understand correctly the images actually are being cached, it's just that chrome doesn't realize this? – Matt Mar 22 '17 at 15:57
  • Yes, I believe that's what's going on with that warning. That's not a Drupal message, but a chrome message. You can test by looking the meta data of the image in Chrome's network tab, or by looking at the access log on your server to see if the images are reserved on each page request. – oknate Mar 22 '17 at 16:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.