Just spent a few hours looking into this. The problem is that for good reason the page cache doesn't load the page layout, which means that Mage_Catalog_Block_Breadcrumbs->_prepareLayout() doesn't get called when the page cache attempts to reload the cache for this block. _prepareLayout() is what loads the breadcrumb before calling Mage_Page_Block_Html_Breadcrumbs->_toHtml()
A quick way to replicate the problem with full page cache that is saved to the file system is to:
- Go to a product or category page
- Flush the full page cache
- Go into /var/full_page_cache and search for the folder containing two files that look like "%CONTAINER_BREADCRUMBS%" and delete them
This will require that the page cache attempt to reload just that block. Since the load doesn't call Mage_Catalog_Block_Breadcrumbs->_prepareLayout() the call to Mage_Page_Block_Html_Breadcrumbs->_toHtml() returns an empty string and the new cache files are empty until cache is completely purged and the full page is reloaded.
The fix I came up with for this isn't pretty, but it seemed to be the least invasive. Simply create a block override for the _toHtml() method that does what _prepareLayout() does.
class Package_Module_Block_Html_Breadcrumbs extends Mage_Page_Block_Html_Breadcrumbs
{
protected function _toHtml()
{
if (!is_array($this->_crumbs)) {
$this->addCrumb('home', array(
'label'=>Mage::helper('catalog')->__('Home'),
'title'=>Mage::helper('catalog')->__('Go to Home Page'),
'link'=>Mage::getBaseUrl()
));
$path = Mage::helper('catalog')->getBreadcrumbPath();
foreach ($path as $name => $breadcrumb) {
$this->addCrumb($name, $breadcrumb);
}
}
return parent::_toHtml();
}
}