Como manter menus enormes no Drupal
Certa vez, abri um menu do Drupal com vários milhares de links e observei o navegador desistir antes de mim. A página, tecnicamente, carregou. Mas depois cada clique parecia que eu estava pedindo a uma impressora velha para explicar seus sentimentos.
Comece com o BigMenu e o Menu Select
Se um site Drupal tem um grande menu editorial, o primeiro problema geralmente não é a arquitetura. É a tela do editor. A página de administração de menus do núcleo do Drupal pode se tornar um suplício quando o menu cresce para milhares de links. O BigMenu resolve isso mudando a forma como os editores visualizam e gerenciam o menu: em vez de renderizar a árvore inteira na página, ele permite abrir sub-árvores via AJAX quando o editor precisa delas. https://www.drupal.org/project/bigmenu
Isso parece um detalhe até você trabalhar com a interface de menu padrão em um site grande. Uma árvore recolhida ainda dói se o Drupal teve de construí-la por completo antes de a página ficar utilizável. O valor do BigMenu está em evitar esse carregamento massivo inicial. O editor vê a parte da árvore que solicitou, não a floresta inteira. https://www.drupal.org/project/bigmenu
O Menu Select resolve outro problema irritante. Nos formulários de conteúdo, os editores muitas vezes precisam escolher um item de menu pai. Com um menu grande, o dropdown comum fica absurdo. Ninguém quer rolar por milhares de elementos só para colocar uma página sob o pai certo. O Menu Select substitui essa experiência por uma hierarquia mais amigável e pode adicionar autocompletar, para que o editor possa buscar o link pai em vez de caçá-lo manualmente por todo o menu. https://www.drupal.org/project/menu_select
Gosto dessa divisão. O BigMenu ajuda quando você gerencia o próprio menu. O Menu Select ajuda quando você vincula conteúdo ao menu. É fácil confundi-los, porque ambos tratam do UX de menus, mas eles corrigem momentos diferentes do fluxo de trabalho editorial.
Menu Select Ajax: carregue a seleção quando o editor precisar dela
O Menu Select com autocompletar já é um grande avanço. Mas em sites muito grandes, mesmo um widget mais amigável ainda pode ser pesado demais se o formulário tentar preparar dados de menu demais antes de o editor ter feito qualquer coisa. É aqui que o padrão AJAX de seleção de menu faz sentido.
A ideia é simples: o formulário não deve construir o seletor de pai completo para um menu enorme no carregamento inicial. Ele deve esperar. Quando o editor escolhe um menu, digita uma busca ou abre um ramo, o Drupal pode executar uma pequena requisição AJAX e devolver apenas a parte correspondente do menu. A Form API do Drupal dá suporte a esse padrão por meio de elementos de formulário com AJAX, em que a ação do usuário dispara uma reconstrução no servidor e apenas a parte selecionada do formulário é substituída. https://www.drupal.org/docs/develop/drupal-apis/javascript-api/ajax-forms
Na prática, a seleção de menu por AJAX costuma ter duas camadas. A primeira camada é o seletor visível: um campo de busca, uma escolha de pai ou um pequeno ramo expansível. A segunda camada é o valor salvo: o ID de plugin do link de menu propriamente dito ou a referência ao pai de que o Drupal precisa ao salvar o formulário.
Essa distinção importa. Os editores devem trabalhar com rótulos, caminhos e títulos de página familiares. O Drupal deve armazenar valores de máquina estáveis. Quando essas duas tarefas se misturam, os widgets de menus grandes ficam frágeis. Surgem rótulos duplicados, opções de pai obscuras e reconstruções lentas de formulário.
Um bom fluxo de seleção de menu por AJAX parece quase entediante. O editor começa a digitar parte de um título. O Drupal devolve uma lista curta de possíveis links pais, de preferência com contexto suficiente para distinguir títulos iguais. O editor escolhe um. O formulário salva o link de menu escolhido nos bastidores. Nenhuma lista de seleção gigante. Nenhuma renderização da árvore inteira. Nenhum navegador derretendo.
O mesmo padrão funciona para ramos expansíveis. Primeiro mostre o nível superior. Quando o editor abre um pai, carregue os filhos daquele pai. Se ele abre mais um filho, carregue o próximo nível. É assim que a interface deve se comportar quando o conjunto de dados é grande: pequena requisição, pequena resposta, próxima ação clara.
Com 10.000 itens de menu, pare de carregar antecipadamente
Quando um menu chega a cerca de 10.000 itens, paro de pensar nele como um menu Drupal comum. Tecnicamente ainda é um menu. Operacionalmente, parece mais um índice de conteúdo em forma de árvore.
Um erro comum é começar pela raiz, carregar a árvore inteira, expandir o caminho ativo e depois descartar a maior parte do resultado. Isso funciona em menus pequenos. Em um menu enorme, é ir na direção errada.
A melhor abordagem que usei é o carregamento reverso. Comece pelo link de menu ativo da página atual. A partir dele, carregue apenas seus pais. Isso fornece o caminho ativo sem precisar pedir ao Drupal para construir todos os ramos não relacionados. As APIs de menu do Drupal dão suporte a esse sentido de navegação: o menu link manager consegue encontrar links por rota e também fornece os IDs de pai do plugin de link de menu. https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Menu%21MenuActiveTrail.php/11.x https://api.drupal.org/api/drupal/core%21lib%21drupal%21core%21menu%21menulinkmanagerinterface.php/function/menulinkmanagerinterface%3A%3Agetparentids/9
Isso muda completamente o perfil de custo. Um menu enorme pode ter 10.000 itens, mas o caminho ativo de uma página costuma ser curto. Podem ser cinco níveis. Podem ser sete. Mesmo em um catálogo profundo, raramente há dezenas de ancestrais para um único item. Então, em vez de carregar 10.000 links para descobrir um caminho, você carrega o item ativo e sobe.
Depois disso, você pode decidir de quanta navegação ao redor a página realmente precisa. Às vezes o caminho de pais basta. Às vezes você também precisa dos filhos do item ativo. Às vezes precisa dos itens vizinhos no mesmo nível, para um menu de seção. Ótimo. Carregue essas fatias de forma consciente. Não deixe a frase «precisamos de navegação» se transformar discretamente em «carregar a árvore inteira a cada requisição».
O sistema de árvores de menu do Drupal já pensa em termos de parâmetros de árvore, caminhos ativos e transformações. A abordagem comum de carregamento de árvore pode expandir os links ao longo do caminho ativo atual, o que é útil para menus normais. https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Menu%21MenuLinkTreeInterface.php/interface/MenuLinkTreeInterface/8.2.x Mas, para um menu muito grande, prefiro ser mais rigoroso. Primeiro encontre o link ativo. Depois carregue seus pais. Depois carregue apenas o ramo necessário para a página atual.
A verdadeira regra de manutenção: nunca faça os editores pagarem pelo menu inteiro
Menus enormes no Drupal não são apenas um problema de renderização. São um problema editorial, um problema de construção de formulários, um problema de cache e, às vezes, um problema de arquitetura da informação que alguém vem adiando há três anos.
O BigMenu ajuda os editores a trabalhar com árvores grandes sem abrir tudo de uma vez. https://www.drupal.org/project/bigmenu O Menu Select torna a escolha do pai tolerável, especialmente com autocompletar. https://www.drupal.org/project/menu_select A seleção por AJAX evita que os formulários preparem milhares de opções antes de o editor dar o primeiro clique significativo. https://www.drupal.org/docs/develop/drupal-apis/javascript-api/ajax-forms
Para a navegação de frontend, o carregamento reverso é a parte que eu defenderia com mais insistência. Comece pelo link de menu ativo. Carregue apenas os pais. Acrescente filhos ou vizinhos somente quando o design realmente precisar deles. Só esse hábito impede que um menu de 10.000 itens transforme cada requisição em um castigo.
O navegador nunca deveria carregar o menu inteiro só porque uma página precisa saber onde está.
Procurando a melhor empresa de desenvolvimento Drupal do mercado? Você acabou de encontrá-la.
Somos a maior agência digital focada em Drupal, criada para um desenvolvimento de plataformas rápido, seguro e escalável, sem concessões. De novos projetos e redesigns a migrações e suporte de longo prazo, nossos especialistas em Drupal entregam resultados de nível corporativo com o cuidado de uma agência boutique.
Agende uma ligação hoje e vamos transformar o seu roadmap de Drupal em uma realidade de alto desempenho.
Ivan Abramenko, arquiteto Drupal principal
ivan.abramenko@drupalbook.org
projects@drupalbook.org