Como acelerar Drupal por código con Big Pipe

Tunel nocturno con luces

En algunas ocasiones cuando desarrollamos una web y estamos creando una página con mucha carga resulta desesperante el no saber que podemos hacer para acelerarla o al menos que las partes que más tardan no ralenticen al resto.

Para problemas como esos se creó el módulo Big Pipe, el cual viene incluido en el core de Drupal. Y muchos sitios lo tienen activo sin saber por qué y creen que les ayuda cuando realmente no le sacan partido, y es que Big pipe por defecto, "no hace nada" y Drupal lo aprovecha, pero sin que nos demos cuenta.

Pues en este articulo veremos como nosotros también podemos sacarle provecho utilizándolo y forzando su uso, y es que Big Pipe solamente funciona si existe una sesión de usuario (por eso existe el módulo Sessionless Big Pipe), pero siempre podemos forzar su uso por código, aunque no tengamos una sesión, y es lo que veremos.

Los render array de Lazy loader

Vamos a partir de un ejemplo muy básico y forzaremos que la web se quede esperando durante 3 segundos.

sleep(3);

$parametro = 'El valor normal a mostrar.';

$build['content_adicional'] = [
  '#type' => 'item',
  '#markup' => $parametro,
];

$build['content'] = [
  '#type' => 'item',
  '#markup' => $this->t('La carga normal!'),
];

return $build;

En ese ejemplo tan sencillo, podemos ver como tenemos 2 render array pero hay un sleep que provocará un retraso de 3 segundos en la carga de la web, esto va a provocar lentitud ya que el servidor se quedará esperando.

Ahora vamos a modificarlo para utilizar el render elemento Lazy loader y de esa manera forzar Big pipe y que la carga inicial de la web no se vea afectada.

$parametro = 'El valor del lazy a mostrar.';

$build['lazy_content'] = [
  '#lazy_builder' => [
  '\Drupal\nekotuto\LazyLoader::lazyLoad',
    [
      $parametro,
    ]
  ],
  '#create_placeholder' => TRUE,
];

$build['content'] = [
  '#type' => 'item',
  '#markup' => $this->t('Este es el rápido!'),
];

return $build;

Ahi hemos modificado el render array para que cargue desde otra clase llamando a un método llamado "lazyLoad" (puede ser el nombre que queramos) y le pasamos un parámetro, el cual es el texto para mostrar, y fijaros además en la opción "#create_placeholder" y es muy importante que la añadáis, de lo contrario no funcionará correctamente.

La clase del lazy load

Ahora veamos el código de la clase que mostrará el contenido, en la cual hemos añadido el sleep de 3 segundos para simular la misma lentitud al cargar la página.

class LazyLoader implements TrustedCallbackInterface {

  public static function lazyLoad($parametro) {
    sleep(3);
    return [
      '#type' => 'item',
      '#markup' => $parametro,
    ];
  }

  public static function trustedCallbacks() {
    return [
      'lazyLoad',
    ];
  }

}

Ahi la tenemos, únicamente consiste en un sleep de 3 segundos y directamente el render array con el texto a mostrar. Debido a que Drupal nos fuerza a utilizar la interfaz TrustedCallbackInterface por razones de seguridad, también tenemos que añadir el método necesario y dentro un array con los métodos de los callback en los cuales se puede confiar.

Y listo, eso es todo, si alguna vez tenéis algo que tarda demasiado en cargar y ralentiza la web, siempre podéis utilizar este sistema para simular que carga más velozmente, y en este ejemplo hemos visto como mostramos un texto, pero realmente podemos hacer lo que queramos siempre que devolvamos un render array, es decir, podemos aprovechar esto para hacer una petición a una API externa que es muy lenta por poner un ejemplo.

Comparte este artículo:
Publicado por Borja
Image

Me metí en la aventura de Drupal con la versión 6, y aquí estoy, 10 años después, escribiendo articulos y haciendo videos sobre Drupal, quien me lo iba a decir. Aunque he probado otros framworks y cms, me quedo con Drupal de lejos, pero Symfony y Django estan entre mis favoritos. Aficionado a la montaña, la bicicleta, y el comer, de eso que no falte.