We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 37172
    • 3 Posts
    Делал сайт с верхним меню (js, выпадающее, содержит все страницы сайта) и боковым меню (отображает продукцию). Всего около 400 страниц с 6 уровнями иерархии.

    Столкнулся с такой проблемой - даже со включенным кэшированием, Wayfinder постоянно перестраивает оба меню, в результате страница грузится около 2.68s при каждой загрузке.

    Включение &cacheResults в вызове Wayfinder дало ускорение до 2.07s

    Покопался в коде, понял следующее - при переходе со страницы на страницу Wayfinder заново выстраивает всю структуру и потом еще обрабатывает её, присваивая классы текущему пункту меню. Оптимизация hide sub menus описанная в инете не помогла: боковое меню стало работать быстрее, но оставалось еще верхнее меню, которое работало так же медленно.

    Решил делать так: выстраивать меню целиком, сохранять его в кэше. Потом для бокового меню отдельно фильтровать скриптом и присваивать классы.

    В итоге родился вот такой сниппет:

    /*  Snippet WayfinderKSV 
     *  Author: Sergey Kravtsov
     *  Author email: [email protected] 
    */
    
    //Get the current context, not necessarily, but I have multisite 
    $context=$modx->getOption('context_name')."_";
    
    switch($mode) // In the call of the snippet will indicate the mode
    {
    case 'topmenu': //Top menu
    $key=$context.'wftopmenu'; //Cachekey name
    $snippet='Wayfinder'; //Wayfinder params
    $params=array(
       'startId' => 0,
       'outerTpl'=>'topMenuOuterTpl',
       'innerTpl'=>'topMenuInnerTpl',
       'rowTpl'=>'topMenuRowTpl',
       'level'=>4
    );
    break;
    
    
    case 'production'://Side menu
    $key=$context.'wfprodmenu';//Cache key name
    $snippet='Wayfinder'; //Wayfinder paramenters
    $params=array(
       'startId' => $modx->getOption('product_id'), 
       'hereClass'=>' ', //​​Set spaces, so Wayfinder will not add here and active classes
       'selfClass'=>' ',  
       'rowTpl'=>'sideMenuRowTpl',
       'rowIdPrefix'=>'sm_', //There are keys needed for filtering below
       'levelClass'=>'level_', 
       'outerClass'=>'prodmenu',
       'level'=>4
    );
    break;
    }
    
    $cached_wf = $modx->cacheManager->get($key); //Get the saved version of the cache
    if(!$cached_wf ) //If not found
    {
    $wf= $modx->runSnippet($snippet,$params); //Start Wayfinder
    $cacheres=$modx->cacheManager->set($key,$wf,7200); //Caching Wayfinder output
    }
    else $wf=$cached_wf; 
    
    
    if($mode=='production' ) //Filter, if sidemenu
    {
     $id=$modx->resource->get('id');
     $parents=$modx->getParentIds($id); 
     $root_parents=array(0,$modx->getOption('product_id')); 
     $parents = array_diff($parents, $root_parents); 
    
     $find=array();
     $replace=array();
    
     $i=0;
     foreach($parents as $p){
       $find[$i]='id="sm_'.$p.'" class="';
       $replace[$i]=$find[$i].' current '; //all "parent" node in the menu put the class 'current'
       $i++;
       }
      $find[$i]='id="sm_'.$id.'" class="';
       $replace[$i]=$find[$i].' active  current '; //set the current document 'active current'
    
     
     $wf=str_replace($find,$replace,$wf);
    }
    
    echo $wf;


    Теперь с помощью CSS спрячем всё лишнее:

    #sidemenu-box ul.prodmenu li.level_2,
    #sidemenu-box ul.prodmenu li.level_3,
    #sidemenu-box ul.prodmenu li.level_4,
    #sidemenu-box ul.prodmenu li.level_5,
    #sidemenu-box ul.prodmenu li.level_6{
    	display:none;
    }
    
    #sidemenu-box ul.prodmenu li.current ul li.level_2,
    #sidemenu-box ul.prodmenu li.current ul li.current ul li.level_3,
    #sidemenu-box ul.prodmenu li.current ul li.current ul li.current ul li.level_3,
    #sidemenu-box ul.prodmenu li.current ul li.current ul li.current ul li.current ul li.level_4,
    #sidemenu-box ul.prodmenu li.current ul li.current ul li.current ul li.current ul li.current ul li.level_5{
    	display:inherit;
    }



    Сам вызов сниппета такой:

    [[WayfinderKSV? &mode=`production` ]]


    Результаты работы такие (время загрузки страницы):
    1. Без фильтрации (верхнее меню) - 707ms
    2. С фильтрацией (боковое меню) 1.2s

    Исходное время 2.68s, то есть достигнуто ускорение минимум в 2 раза.

    Метод, возможно, не самый красивый, но:

    1. Удобный, т.к. не требует ломать чужие сниппеты
    2. Может быть применен к любым другим сниппетам.

    Ниже прикрепил файликом отдельным, с русскими комментами. [ed. note: sergey.kravtsov last edited this post 12 years, 5 months ago.]
      • 785
      • 2,113 Posts
      Quote from: sergey.kravtsov at Oct 01, 2011, 03:13 PM
      Всего около 400 страниц с 6 уровнями иерархии
      Quote from: sergey.kravtsov at Oct 01, 2011, 03:13 PM
      Без фильтрации (верхнее меню) - 707s
      Не понял – это более 10 минут загрузка? И это успех?
      Quote from: sergey.kravtsov at Oct 01, 2011, 03:13 PM
      С фильтрацией (боковое меню) 1.2s
      Мне все же кажется, что более секунды для сайта из 400 страниц – очень много. Для интереса попробовал в Evo создавать полное меню с помощью Wayfinder без каких-либо доработок на сайте из 650 страниц на 4 уровнях – без кэширования получилось примерно дополнительных 0,5 секунды. Еще раз убедился в «тормознутости» Revo…
        Создание сайтов на MODx, поддержка сайтов, поисковая оптимизация, программирование, копирайтинг
        Статьи о MODx, регулярно новые публикации
        • 37172
        • 3 Posts
        Сорри, 707мс (0,7с).
        Это время загрузки страницы всей, там не только меню. Отдельно скорость построения меню не считал. Revo не быстрый, но мне нравится.
          • 52996
          • 15 Posts
          Quote from: sergey.kravtsov at Oct 02, 2011, 03:44 PM
          Сорри, 707мс (0,7с).
          Это время загрузки страницы всей, там не только меню. Отдельно скорость построения меню не считал. Revo не быстрый, но мне нравится.
          Рево круче EVO в разы и на нем можно построить все что угодно. просто вы не те компоненты выбираете, меню лучше делать не через вайфиндер, а через pdoMenu и со скоростью проблем не будет