magento-turpentine icon indicating copy to clipboard operation
magento-turpentine copied to clipboard

ESI.php observer - xpath very slow

Open hmphu opened this issue 8 years ago • 0 comments

Hi,

I turned on the php_slow_log and see that the function bellow take very long running time.

I tried to move $layout->getUpdate() outside the loop using a variable but it does not help.

Anybody found the general and good solutions?

    /**
     * Get the active layout handles for this block and any child blocks
     *
     * This is probably kind of slow since it uses a bunch of xpath searches
     * but this was the easiest way to get the info needed. Should be a target
     * for future optimization
     *
     * There is an issue with encoding the used handles in the URL, if the used
     * handles change (ex customer logs in), the cached version of the page will
     * still have the old handles encoded in it's ESI url. This can lead to
     * weirdness like the "Log in" link displaying for already logged in
     * visitors on pages that were initially visited by not-logged-in visitors.
     * Not sure of a solution for this yet.
     *
     * Above problem is currently solved by EsiController::_swapCustomerHandles()
     * but it would be best to find a more general solution to this.
     *
     * @param  Mage_Core_Block_Template $block
     * @return array
     */
    protected function _getBlockLayoutHandles($block) {
        Varien_Profiler::start('turpentine::observer::esi::_getBlockLayoutHandles');
        $layout = $block->getLayout();
        $layoutXml = Mage::helper('turpentine/esi')->getLayoutXml();
        $activeHandles = array();
        // get the xml node representing the block we're working on (from the
        // default handle probably)
        $blockNode = current($layout->getNode()->xpath(sprintf(
            '//block[@name=\'%s\']',
            $block->getNameInLayout() )));
        $childBlocks = Mage::helper('turpentine/data')
            ->getChildBlockNames($blockNode);
        foreach ($childBlocks as $blockName) {
            foreach ($layout->getUpdate()->getHandles() as $handle) {
                // check if this handle has any block or reference tags that
                // refer to this block or a child block, unless the handle name
                // is blank
                if ($handle !== '' && (strpos($handle, 'THEME') === 0 ||
                    $layoutXml->xpath(sprintf(
                        '//%s//*[@name=\'%s\']', $handle, $blockName )))) {
                    $activeHandles[] = $handle;
                }
            }
        }
        if ( ! $activeHandles) {
            $activeHandles[] = 'default';
        }
        Varien_Profiler::stop('turpentine::observer::esi::_getBlockLayoutHandles');
        return array_unique($activeHandles);
    }

hmphu avatar Nov 03 '16 04:11 hmphu