How to deal with block cached for anonymous user? I have placed in the site's home, via twig, a views block of nodes with a random sort and obliviously no cache active.
Therefore, at each page reload different nodes appear.
The problem is that block get still cached for anonymous users.
For now, we can't yet do performance test of the site, so we'd rather not disable the Internal Page Cache module.
The Internal page documentation says:

Websites that serve personalized content to anonymous users (dynamic, per-session, e.g. a shopping cart) will want to disable the Internal Page Cache module. This module assumes pages are identical for all anonymous users. Those websites can still take advantage of the Dynamic Page Cache module though, or can alternatively do their personalization using JavaScript + AJAX.

So after failing to find anything else useful, I've tried this solution to solve the issue.
Unfortunately I found no module that let &quot;load&quot; the block via ajax, or something similar. For now I've implemented a custom route that render the block view:
&lt;?php

namespace Drupal\my_module\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use Drupal\Core\Render\Renderer;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\sdm_user\SdmUserSalesforceClient;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Response;

/**
 * Provides route responses for the Example module.
 */
class myController extends ControllerBase {

  

  /**
   * @var \Drupal\Core\Render\Renderer
   */
  private  $renderer;

  /**
   * @param \Drupal\Core\Render\Renderer $renderer
   */
  public function __construct(Renderer $renderer){
    $this-&gt;renderer = $renderer;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container-&gt;get('renderer')
    );
  }

  /**
   * @return array
   *   A simple renderable array.
   */
  public function render($id, $display) {
    $view = \Drupal\views\Views::getView($id);
    $render_array = $view-&gt;buildRenderable($display);
    $rendered = $this-&gt;renderer-&gt;renderRoot($render_array);
    $response = new Response();
    $response-&gt;setContent($rendered);
   
    return $response;

  }
}

And then in a custom js, load the necessary block via ajax:
(function ($, Drupal, drupalSettings) {
    Drupal.behaviors.products_in_home = {
        attach: function (context, settings) {
            $(document, context).once('products_in_home').each(function () {
                jQuery.ajax({
                    url: drupalSettings.path.currentLanguage + '/ajax/views/prodotti/products',
                    method: 'GET',
                    success: function (data) {
                        $(&quot;.products-container-home&quot;).html(data);
                    }
                });
            });
        }
    }
}(jQuery, Drupal, drupalSettings));

This works, but I'm kinda baffled: is this the only approach possible?
I mean, do I need to manually load via ajax every block\thing in the site that will suffer this problem?
Isn't there a module\API\some approach that can generally solve this problem, without custom specific code for every element?
In general the Internal Page Cache is a rather simple solution. If you need more features replace it with Varnish or a CDN. Most of them provide similar features, like for example ESI to serve dynamic blocks if you can't use Javascript. I think most people would use Javascript in this case, though, and there is a fully cacheable solution. You can deliver all eligible node IDs in drupalSettings and then select and fetch a random node in Javascript. Both, the page containing all eligible nodes and the node randomly fetched, are cacheable, so you can provide the dynamic behavior without any performance hit.