все мы знаем такие правила:
Код: Выделить всё
'<module:[\w-]+>' => '<module>/default/index',
'<module:[\w-]+>/<action:[\w-]+>/<id:\d+>' => '<module>/default/<action>',
'<module:[\w-]+>/<action:[\w-]+>' => '<module>/default/<action>',
'<module:[\w-]+>/<controller:[\w-]+>/<action:[\w-]+>/<id:\d+>' => '<module>/<controller>/<action>',
'<module:[\w-]+>/<controller:[\w-]+>/<action:[\w-]+>' => '<module>/<controller>/<action>'
Код: Выделить всё
[
'pattern' => 'posts/<page:\d+>/<tag>',
'route' => 'post/index',
'defaults' => ['page' => 1, 'tag' => ''],
],
Дальше есть два сценария работы: парсинг урла и создание урла.
1. При парсинге урла мы перебираем каждое из 100 правил пока не найдем в одном из правил подходящую под урл регулярку. Как только мы нашли нужное правило, мы узнаем роут, куда направляем запрос и инициализируем необходимый контроллер.
2. При создании урла мы перебираем все правила, пока не совпадет роут урла и роут правила. При совпадении мы останавливаемся, т.к. знаем каким правилом нам генерировать ссылку.
Теперь выделим проблемы: кол-во памяти, выделяемое на объекты и неконтроллируемое кол-во итераций на нахождение нужного правила.
Во втором сценарии при 100 ссылках на странице и 100 правилах урлов мы теоретически получим до 10000 итераций для нахождения нужного правила.
Способы решения:
а) выделение групп правил (post: post/update, post/new, post/ajaxCount, post/delete, post/comment/edit) в отдельный класс.
Код: Выделить всё
'rules' => [
['class' => 'PostUrlRule'],
// ...
]
Таким образом мы сократим кол-во объектов правил в разы, условно со 100 до 20, облегчив потребление памяти и уменьшив кол-во итераций на парсинг ссылки.
Этот пункт, скажем, хинт для разработчика.
UPD: в комментах упомянули GroupUrlRule для yii2, который решает проблему с группированием, но усугубляет проблему с памятью.
Следующий пункт - предложение для разработчиков yii (для включения в ядро или для написания расширения):
б) добавить функционал теггирования правил
Код: Выделить всё
[
'pattern' => 'goods',
'route' => 'goods/index',
'suffix' => '.json',
'tag' => 'goods'
],
['class' => 'PostUrlRule', 'tag' => 'post'],
Допустим у нас 100 правил, в конце массива находятся 10 правил группы post, последнее из которых (100-е) обрабатывает ссылки роута post/view. На странице у нас 100 ссылок на посты, генерируемых через createUrl. Для генерации всех ссылок придется сделать 10000 итераций.
При введении теггирования, мы можем в каком-то месте задать для роута приоритетный тег (теги или даже веса), например
Код: Выделить всё
Yii::$app->getUrlManager()->setPriorityRuleTag('post')
При объединении двух вариантов ваш урлменджер убыстрится до скоростей формулы 1.
PS Такие оптимизации возможно не имеют смысла для небольших проектов. Для больших эти оптимизации дадут существенный профит.