Score:2

การดีบักส่วนหัว "UNCACHEABLE"

ธง in

เรามีไซต์ที่ไม่ได้แคชหน้าแรกและมีส่วนหัว:

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);

หากฉันลบออก จะมีผลเสียหรือไม่ (เช่น การเรนเดอร์จอแสดงผลไม่แสดงผลซ้ำเมื่อมีการบันทึกรายการอ้างอิง)

4uk4 avatar
cn flag
การตั้งค่าคีย์แคชไม่เพียงพอ คุณต้องมีแท็กแคชด้วย ดังนั้นอย่าลบบรรทัดนี้ เพียงตรวจสอบว่าวัตถุนั้นไม่เป็น NULL
sonfd avatar
in flag
ใช่ แคชคีย์ไม่ได้ทำอะไรเลย บริบท แท็ก และอายุสูงสุดคือสิ่งที่คุณต้องการให้แน่ใจว่าจะดำเนินการต่อไป
Kevin avatar
in flag
$parent ไม่เป็นโมฆะ แต่ได้รับใน createFromObject เป็นอินสแตนซ์ของ EntityAdapter (ที่มีโหนดเอนทิตีหรือย่อหน้า) ซึ่งฉันไม่สามารถติดตามได้ว่ากำลังใช้งาน CacheableDependencyInterface
4uk4 avatar
cn flag
ตกลง ตอนนี้ฉันพบปัญหาแล้ว เอนทิตีที่มีข้อมูลแคชคือ `$parent_entity`
Kevin avatar
in flag
นั่นคือสิ่งที่ฉันสงสัย ขอบคุณที่ยืนยัน การเปลี่ยนแปลงที่ส่งกลับการตอบสนองที่แคชได้ไปยังเบราว์เซอร์
Score:4
ธง in

นี่เป็นการลงลึกในการแก้ปัญหาที่ดี ดังที่กล่าวถึงโดย 4k4 ปัญหาคือสิ่งแรก เพิ่ม CacheableDependency ไลน์.

แทนที่จะส่งเอนทิตีของโฮสต์เอง ฉันกลับส่งออบเจกต์ที่ส่งคืนมาโดยไม่ตั้งใจ รับผู้ปกครอง ซึ่งเป็น พิมพ์ข้อมูล ตัวอย่างที่ไม่ได้ใช้งาน CacheableDependencyInterface - จึงทำให้อายุสูงสุดถูกกำหนดเป็น 0 และ ไม่สามารถเข้าถึงได้ ผลลัพธ์ส่วนหัว

ผ่านเอนทิตี (ส่งคืนจาก รับค่า ()) แก้ไขปัญหา:

    $parent = $items->getParent();
    $parent_entity = $parent->getValue();
    ...
    $this->renderer->addCacheableDependency($องค์ประกอบ[$delta], $parent_entity);

โพสต์คำตอบ

คนส่วนใหญ่ไม่เข้าใจว่าการถามคำถามมากมายจะปลดล็อกการเรียนรู้และปรับปรุงความสัมพันธ์ระหว่างบุคคล ตัวอย่างเช่น ในการศึกษาของ Alison แม้ว่าผู้คนจะจำได้อย่างแม่นยำว่ามีคำถามกี่ข้อที่ถูกถามในการสนทนา แต่พวกเขาไม่เข้าใจความเชื่อมโยงระหว่างคำถามและความชอบ จากการศึกษาทั้ง 4 เรื่องที่ผู้เข้าร่วมมีส่วนร่วมในการสนทนาด้วยตนเองหรืออ่านบันทึกการสนทนาของผู้อื่น ผู้คนมักไม่ตระหนักว่าการถามคำถามจะมีอิทธิพลหรือมีอิทธิพลต่อระดับมิตรภาพระหว่างผู้สนทนา