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.