เรามีไซต์ที่ไม่ได้แคชหน้าแรกและมีส่วนหัว:
x-แคช: มิส, มิส
x-แคชฮิต: 0, 0
x-content-type-options: nosniff
x-drupal-dynamic-cache: ไม่สามารถเข้าถึงได้
ฉันจำกัดขอบเขตนี้ให้แคบลงถึงเนื้อหาของขอบเขตเนื้อหา และปิดใช้งาน "เนื้อหาของหน้าหลัก" สำหรับหน้าแรก สิ่งนี้ทำให้ฉันได้รับแคช HIT และไม่ตอบกลับเป็น UNCACHEABLE อีกต่อไปจากตรงนั้น ฉันจำกัดขอบเขตให้แคบลงถึงตัวจัดรูปแบบฟิลด์ที่ใช้ในย่อหน้า เรามีแบบกำหนดเองที่ขยายตัวจัดรูปแบบการแสดงเอนทิตีปกติ
ถ้าฉันเปลี่ยนกลับเป็นตัวจัดรูปแบบ "Render entity" ดั้งเดิม ทุกอย่างก็ปกติดี ดังนั้น จะต้องเป็นสิ่งที่เรากำลังทำในฟอร์แมตแบบกำหนดเองนี้ซึ่งเป็นสาเหตุของปัญหา
ฉันเห็นได้เมื่อฉันติดตามด้วย xdebug ที่ควร CacheResponse ของ DynamicPageCacheSubscriber ส่งคืน FALSE เนื่องจากมีบางอย่างตั้งค่าอายุสูงสุดเป็น 0 (ไม่ใช่รหัส) ดูเหมือนว่าการเรียกใช้ addCacheableDependency อาจทริกเกอร์พฤติกรรมนี้ในฟอร์แมตเตอร์:
โดยพื้นฐานแล้ว ตัวจัดรูปแบบจะเพิ่มข้อมูลแคชในการเรนเดอร์ ดังนั้นหากมีการอัปเดตรายการอ้างอิงใด ๆ แคชควรจะใช้ไม่ได้สำหรับย่อหน้าโฮสต์นั้น ดังนั้นมันจึงแสดงผลใหม่:
$view_builder = \Drupal::entityTypeManager()->getViewBuilder($entity->getEntityTypeId());
$elements[$delta] = $view_builder->view($entity, $view_mode, $entity->language()->getId());
พยายาม {
$parent = $items->getParent();
$parent_entity = $parent->getValue();
$elements[$delta]['#cache']['keys'][] = $parent_entity->id();
$elements[$delta]['#cache']['keys'][] = $parent_entity->bundle();
$elements[$delta]['#cache']['keys'][] = $parent_entity->getEntityTypeId();
$elements[$delta]['#cache']['keys'][] = 'delta_' $เดลต้า;
$elements[$delta]['#cache']['keys'][] = 'context_aware';
$this->renderer->addCacheableDependency($องค์ประกอบ[$delta], $parent);
ถ้า ($entity->hasField('field_author')) {
$child = $entity->field_author->เอนทิตี;
ถ้า (isset($child)) {
$this->renderer->addCacheableDependency($องค์ประกอบ[$delta], $child);
}
}
// คำสั่งที่คล้ายกันกับ addCacheableDependency
ถ้าฉันแสดงความคิดเห็นในบรรทัดเริ่มต้นนี้:
$this->renderer->addCacheableDependency($องค์ประกอบ[$delta], $parent);
จากนั้นฉันได้รับการตอบกลับที่แคชได้ดูเหมือนว่าเป็นเพราะรายการ $parent (แม้ว่าจะเป็นโหนดหรือย่อหน้าหรือเอนทิตีสื่อก็ตาม) ทริกเกอร์สิ่งนี้:
/**
* สร้างวัตถุ CacheableMetadata จากวัตถุที่ขึ้นต่อกัน
*
* @param \Drupal\Core\Cache\CacheableDependencyInterface|ผสม $object
* วัตถุที่มีข้อมูลเมตาของ cacheability เพื่อดึงข้อมูล หากนำไปปฏิบัติ
* CacheableDependencyInterface ข้อมูลเมตาความสามารถในการแคชจะถูกใช้
* มิฉะนั้น วัตถุที่ส่งผ่านจะต้องถือว่าไม่สามารถแคชได้ ดังนั้น
* ตั้งค่าอายุสูงสุดเป็น 0
*
* @return คงที่
*/
ฟังก์ชันสแตติกสาธารณะ createFromObject($object) {
ถ้า ($ วัตถุอินสแตนซ์ของ CacheableDependencyInterface) {
$meta = ใหม่คง ();
$meta->cacheContexts = $object->getCacheContexts();
$meta->cacheTags = $object->getCacheTags();
$meta->cacheMaxAge = $object->getCacheMaxAge();
ส่งคืน $meta;
}
// ต้องถือว่าวัตถุที่ไม่ได้ใช้ CacheableDependencyInterface
// ที่ไม่สามารถแคชได้ ดังนั้นให้ตั้งค่า max-age เป็น 0
$meta = ใหม่คง ();
$meta->cacheMaxAge = 0;
ส่งคืน $meta;
}
การตั้งค่า cacheMaxAge เป็น 0 เนื่องจากไม่ใช่อินสแตนซ์ของ CacheableDependencyInterface
หากฉันตั้งค่าคีย์แคชแล้ว จำเป็นต้องใช้บรรทัดนี้หรือไม่:
$this->renderer->addCacheableDependency($องค์ประกอบ[$delta], $parent);
หากฉันลบออก จะมีผลเสียหรือไม่ (เช่น การเรนเดอร์จอแสดงผลไม่แสดงผลซ้ำเมื่อมีการบันทึกรายการอ้างอิง)