Score:0

How can I Speed up Cache calls?

cn flag

I have a site with a few complicated forms. They require a lot of CPU time to calculate, so I am caching the $form array in order to be able to deliver the form quickly to the user. To do this, I am using an abstract class based on FormBase. Here is the code for this class:

abstract class PM_FormBase extends FormBase {
  public function buildForm(array $form, FormStateInterface $form_state) {
    $formValues = $form_state->getUserInput();
    // If this is not a form submission, so get from cache
    if (0 == count($formValues)) {
      $building = 'Park_Avenue_Manor'; // Hard coded for now, for testing
      $cid = $building . '_' . $this->getFormId();
      if ($cache = \Drupal::cache()->get($cid)) {
        \Drupal::messenger()->addMessage('From Cache'); // Just for Testing
        $form = $cache->data;
      }
      else {
        \Drupal::messenger()->addMessage('NO, NOT From Cache'); // Just for Testing
        $form = $this->buildCompleteForm($form, $form_state);
        // Set cache to expire 1 hour
        \Drupal::cache()->set($cid, $form, strtotime("+1 hours"));
        // Store form ID as well. This is used in function buildFormsCache
        $formIds = \Drupal::cache()->get('PM_FormBase_Form_IDs');
        if (!$formIds) $formIds = (object)['data' => []];
        if(!in_array($cid,$formIds->data)) {
          $formIds->data[] = $cid;
          \Drupal::cache()->set('PM_FormBase_Form_IDs', $formIds->data);
        }
      }
    }
    // If it's a form submission, so process regularly
    else {
      $form = $this->buildCompleteForm($form, $form_state);
    }
    return $form;
  }
}

Then an actual form definition looks like this:

namespace Drupal\midwayliving\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;

class showBuildingStatus extends PM_FormBase {
  public function getFormId() {
    return 'showBuildingStatus_form';
  }
  public function buildCompleteForm($form, $form_state) {

Based on the addMessage code, I can verify that the caching is working as expected. When I initially implemented this, the load time for the showBuildingStatus form went down from 20 seconds to 2 seconds. The PM_FormBase code was a bit simpler then.

Today if I turn off the caching (disable the PM_FormBase code), the page loads in 30 or 50 seconds. If I enable the caching then it takes 20 or 30 seconds.

This is on our development server, that no one is using except me. On the live server it takes 30 or 35 seconds. To load a simple static page takes a second or two, so the server and the site are working normally.

I don't understand why a static page loads in 2 seconds, but a cached form takes 30 seconds.

Kevin avatar
in flag
A static page like just HTML? Is this using memory backed cache or is it stored in the database?
Hershel avatar
cn flag
Yes, just HTML in a Drupal node. Cache is in the DB.
4uk4 avatar
cn flag
Even if you cache the form build it still needs to be processed and rendered. But you can cache the rendered form in the render cache the same as any other rendered HTML.
Jaypan avatar
de flag
I would suggest a debugger, such as xdebug, or a profiler, such as Web Profiler (https://www.drupal.org/project/webprofiler) so you can drill down and figure out exactly what is taking this amount of time. The caching code you have shown looks mostly fine.
Kevin avatar
in flag
Try implementing Memcache or Redis to take the strain off the database. Then profile from there.
No Sssweat avatar
ua flag
If you have a lot of form fields consider doing a multistep form instead.
ng flag
Just to mention it, you could use https://www.drupal.org/docs/develop/development-tools/xhprof-code-profiler for profiling too.
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.