Performan em sites Joomla

Por
Nicholas K. Dionysopoulos

Em 5 partes:

Origiais em inglês

https://www.dionysopoulos.me/joomla-performance-tuning-i-start-at-the-beginning.html
https://www.dionysopoulos.me/joomla-performance-tuning-ii-basic-settings.html
https://www.dionysopoulos.me/joomla-performance-tuning-iii-static-media-optimization.html
https://www.dionysopoulos.me/joomla-performance-tuning-iv-site-building-calisthenics.html
https://www.dionysopoulos.me/joomla-performance-tuning-v-content-quality.html

Quarta parte

Joomla Performance Tuning IV: Site building calisthenics

Na terceira parte desta série, descrevi como extrair mais desempenho do seu site otimizando os arquivos de mídia estáticos. Hoje falarei sobre como dar os retoques finais que deixam seu site mais sofisticado e profissional. Eles têm a ver principalmente com a forma como o seu site interage com os mecanismos de pesquisa e as redes sociais, mas também há um pouco de desempenho aí. Acho que informações sobre como aprimorar seu site são a melhor forma de se despedir deste ano.

Calistenia de construção de sites
Dar beleza, força e vigor ao sites

Se você implementou todas as recomendações até agora, você está a cerca de 90% do caminho para um site com bom desempenho, boa classificação e fácil de manter. Esta seção é sobre como obter esse desempenho extra sem exagerar.

O que são "comprimentos bobos", ouço você perguntar com cansaço, tendo visto que algumas das recomendações aqui não são exatamente o que chamaríamos de diretas. Bem, existem pessoas que estão acostumadas a trabalhar em sites massivos, pelo menos em termos de volume de visualizações de páginas atendidas, que recomendarão ações que façam sentido no contexto dos sites que constroem, mas não no contexto dos sites de médio a pequeno porte. sites (realisticamente, extremamente pequenos) que a maioria das pessoas que lêem este artigo tendem a construir. Aqui estão algumas das recomendações que vi e que fazem sentido apenas em alguns contextos, mas são apresentadas como um axiomático Caminho Único e Verdadeiro:

Remova todos os espaços em branco usando substituições de modelo que usam concatenações de strings PHP para todo HTML. A maioria de vocês acha que isso é uma piada. Faz sentido quando você atende centenas de milhares de visualizações de páginas todos os dias em uma nuvem pública que cobra pelo volume de dados servidos. Transformar uma página de 300 KB em uma página de 299 KB tem um impacto financeiro apreciável quando se trata de trezentas mil visualizações de página por dia. Não faz sentido quando seu site tem de algumas centenas a milhares de visualizações de página por dia. Mais ainda, considerando o que você perde: você não tem destaque de sintaxe, é notoriamente difícil entender o que diabos está acontecendo e boa sorte para encontrar aquele DIV de fechamento ausente que estraga seu modelo.

Usando estruturas CSS "mínimas" e substituindo a saída de cada extensão instalada em seu site. Isso faz sentido em sites grandes com um orçamento grande, pois não apenas reduz a quantidade total de CSS que você veicula, mas também garante consistência absoluta de tudo o que é exibido no site. Também é notoriamente difícil de implementar porque você está tentando substituir TUDO primário e de terceiros e, em muitos casos, você precisa "hackear o núcleo" (modificar os arquivos PHP de algumas extensões) para alterar ou remover classes CSS codificadas ou hard HTML codificado. A implementação é uma montanha para escalar e leva uma eternidade. As atualizações são um pesadelo. Você só faz isso se for absolutamente necessário. Além dos maiores sites, que de qualquer maneira não usariam o Joomla, não conheço mais ninguém para quem faria sentido fazer isso em termos comerciais.

Substitua todas as extensões do site para não carregar nenhum arquivo CSS e JS, usando apenas arquivos combinados, minificados e pré-compactados que você implantou com o site. Sim, bem, como acima. É uma tarefa titânica que você nem sequer considera, a menos que haja uma razão absolutamente boa para isso.

Aplicativos da web progressivos (PWA). O principal benefício de um PWA é que seu conteúdo está disponível off-line. A desvantagem é que fica substancialmente mais complicado construir um site como esse, especialmente quando você se aventura fora do conteúdo principal. Para alguns sites, faz sentido. Por exemplo, se você estiver construindo um recurso educacional, implementá-lo como um PWA pode estar fazendo a obra de Deus, já que você permite que um aluno fique à espreita fora de um estabelecimento com uma rede WiFi aberta, basicamente baixe o material no qual ele está interessado e volte para casa para estudar sem degradar sua experiência. Para a maioria dos sites, entretanto, isso não faz sentido ou é uma coisa realmente idiota de se fazer. Por exemplo, não quero que o site da sua marca fique para sempre no cache do meu navegador, especialmente se eu tiver um dispositivo de baixo custo com armazenamento limitado que poderia usar de maneira muito melhor. Então, você sabe, se você decidir seguir o caminho do PWA, certifique-se de que realmente há necessidade disso, em vez de "é a nova moda e todas as crianças legais estão fazendo isso".

Em vez de sugestões elaboradas e muitas vezes irrealistas como essa, vou me concentrar nas coisas mais simples que você provavelmente usará nos sites Joomla que criar.

PS: Por favor, não escreva comentários raivosos sobre como todas essas técnicas fazem sentido em todos os sites porque, você sabe, elas não fazem. Você pode ter o privilégio de trabalhar para poucos, selecionar todos os anos clientes que paguem bem e tenham tempo para você implementar essas técnicas elaboradas, entregar o site e não olhar para trás. Esse é o seu privilégio, não a realidade que a maioria das pessoas enfrenta. A maioria das pessoas trabalha com prazos apertados, orçamentos ainda mais apertados, mudanças diárias de metas e faz o trabalho pesado de manter os sites dia após dia.

Cartões OpenGraph e Twitter

Se você já digitou uma URL em uma rede social como o Facebook (e suas outras propriedades da web, como Instagram, Messenger e WhatsApp) ou Twitter, você deve ter visto algo interessante acontecendo. Você recebe uma espécie de cartão com uma imagem e uma breve descrição do conteúdo da página. Você pode até obter links para o autor ou editor do conteúdo dessa rede social. Como funciona essa mágica? A resposta, meu amigo, NÃO está soprando no vento, são meta tags. Ou seja, as metatags OpenGraph e Twitter Card.

Existem duas maneiras de fazer isso: usar uma extensão de terceiros; ou editar seu template e fazer substituições de template.

A primeira maneira é sem dúvida muito mais simples. Primeiro, você precisará usar o plug-in do site Phoca para adicionar o namespace OpenGraph necessário ao seu elemento HTML. Edite as opções do site e defina a opção “Atributos HTML XMLNS” para:

xmlns:og="https://ogp.me/ns#",xmlns:fb="https://www.facebook.com/2008/fbml"

Em seguida, use o plug-in de conteúdo Phoca Open Graph para configurar suas tags OpenGraph e Twitter Card para seu conteúdo. Observe que existem dois plug-ins, um chamado Phoca Open Graph Plugin (é o que você precisa) e Phoca Open Graph System Plugin.

A desvantagem de usar plug-ins é que, bem, há mais código que precisa ser carregado em seu site e você realmente não precisa deles se puder editar seu template. A primeira mudança é obviamente alterar o elemento HTML raiz do seu template para incluir o namespace do OpenGraph, por exemplo:

<html lang="<?php echo $this->idioma; ?>" dir="<?php echo $this->direção; ?>" prefix="og: http://ogp.me/ns#" >

O leitor astuto pode perceber que estamos usando prefixo em vez de um namespace XML. Esta é a forma recomendada que funciona em navegadores mais recentes, ou seja, Internet Explorer 10 e posterior.

Em seguida, você precisa criar substituições de template para exibição de categorias e artigos que incluam as tags OpenGraph e Twitter Card necessárias. Por exemplo, uma substituição de template de artigo (templates/MY_TEMPLATE/html/com_content/article/default.php) pode ser algo como:

$imagesRegistry = new \Joomla\Registry\Registry($this->item->images ?? '{}');
$imageIntro = $imagesRegistry->get('image_intro', null);
$imageFull = $imagesRegistry->get('image_fulltext', $imageIntro);
$canonicalURL = Route::_(ContentHelperRoute::getArticleRoute($this->item->id), true, Route::TLS_IGNORE, true);

$doc->setMetaData('og:type', 'blog');
$doc->setMetaData('og:título', $this->item->título);
$doc->setMetaData('og:descrição', $doc->getDescription());
$doc->setMetaData('og:nome_do_site', $app->get('nomedosite'));
$doc->setMetaData('og:url', $canonicalURL);
$doc->setMetaData('og:imagem', $imageFull);
$doc->setMetaData('twitter:cartão', 'summary_large_image');
$doc->setMetaData('twitter:site', '@seu_twitter_handle');
$doc->setMetaData('twitter:criador', '@seu_twitter_handle');
$doc->setMetaData('twitter:descrição', $doc->getDescription());
$doc->setMetaData('twitter:título', $this->item->título);

Uma substituição de template de blog de categoria também precisaria de um código semelhante ao seguinte:

$canonicalURL = Route::_(ContentHelperRoute::getCategoryRoute($category->id), true, Route::TLS_IGNORE, true);

$doc->setMetaData('og:type', 'blog');
$doc->setMetaData('og:title', $this->params->get('page_title', $category->title));
$doc->setMetaData('og:descrição', $doc->getDescription());
$doc->setMetaData('og:nome_do_site', $app->get('nomedosite'));
$doc->setMetaData('og:url', $canonicalURL);
$doc->setMetaData('og:image', $category->params->get('image'));
$doc->setMetaData('twitter:cartão', 'summary_large_image');
$doc->setMetaData('twitter:site', '@seu_twitter_handle');
$doc->setMetaData('twitter:criador', '@seu_twitter_handle');

Usar substituições de template obviamente funciona melhor se você já pretende criar seu próprio template, criando, portanto, grandes quantidades de substituições de template de qualquer maneira. Se não tiver certeza, escolha o terceiro método de plug-ins.

Pré-busca de DNS e pré-carregamento de recursos externos

Algum tempo atrás na série eu disse que os navegadores não sabem magicamente quais arquivos precisam solicitar quando estão carregando a página, eles começam a carregar os arquivos quando descobrem que precisam deles ou você os envia para o navegador com HTTP/2 Push . Eu menti um pouco. Você pode dar algumas dicas ao navegador para que ele comece a preparar as coisas enquanto ainda está baixando os primeiros bytes do seu conteúdo HTML usando as tags de pré-busca e pré-carregamento de DNS. Mas acho que estou me adiantando.

Pré-busca de DNS

Quando descrevi como um navegador recupera arquivos CSS, JavaScript e de imagem necessários para renderizar a página, usei um modelo simplista onde o navegador envia uma solicitação para "seu servidor". A suposição tácita era que "seu servidor" se refere ao mesmo servidor e nome de domínio daquele de onde está carregando o conteúdo HTML. Na maioria dos sites Joomla, esse é realmente o caso. No entanto, seu site pode estar usando um CDN externo para hospedar alguns arquivos de mídia, incluir CSS do Google Fonts ou um recurso semelhante, carregar JavaScript de um serviço externo e assim por diante. Todos esses são recursos hospedados em um nome de domínio diferente daquele que hospeda seu site e entrega seu conteúdo HTML. Seu navegador não pode se conectar magicamente a esses nomes de domínio externos; os nomes de domínio precisam ser resolvidos primeiro para um endereço IP por meio de uma consulta DNS.

As consultas DNS podem ser lentas, especialmente em conexões de alta latência, como satélite, celular ou apenas WiFi compartilhado de má qualidade. Isso adiciona um atraso no carregamento desse recurso, que pode variar de irritante (grandes mudanças de layout) a totalmente problemático (uma inclusão de JavaScript não adiada e não assíncrona está fazendo com que a página pare de carregar).

Usando a pré-busca de DNS, você pode avisar ao navegador, basicamente informando que ele precisará resolver esses nomes de domínio durante a renderização da página. O navegador pode fazer as consultas DNS enquanto gira os polegares, esperando que um arquivo JavaScript ou CSS de bloqueio seja finalmente carregado, economizando algum tempo do usuário nas partes posteriores da renderização da página.

Outro bom motivo para fornecer a dica de pré-busca de DNS é quando você sabe que uma interação do usuário fará com que um recurso seja carregado de um site externo. Por exemplo, se você sabe que clicar em um botão Curtir causará uma conexão com o nome de domínio de uma rede social, faz sentido informar ao navegador para resolver o nome de domínio com antecedência para fazer com que esse botão pareça mais responsivo à interação do usuário.

Existem duas maneiras de fazer isso: usando uma extensão de terceiros ou editando seu template.

Você pode (ab) usar o plugin HeadTag de Michael Richey para inserir as meta tags necessárias em seu site. Use a guia Tags de grupo de usuários, adicione uma regra para o grupo de usuários públicos, já que este é o grupo de usuários que se aplica tanto a convidados quanto a usuários logados, e selecione o tipo de tag personalizada. A “Declaração de script/estilo ou tag personalizada” a ser inserida é uma ou mais linhas de pré-busca de DNS. Por exemplo:

<link rel="dns-prefetch" href="https://fonts.gstatic.com">
<link rel="dns-prefetch" href="https://fonts.googleapis.com">
<link rel="dns-prefetch" href="https://www.google.com">
<link rel="dns-prefetch" href="https://www.gstatic.com">

Observe que o atributo href é a raiz do domínio. Não há caminho.

Se estiver modificando seu template, você pode usar o código PHP como o seguinte antes de começar a gerar o elemento HEAD no documento HTML:

/** @var \Joomla\CMS\Application\SiteApplication $app */
$app = JFactory::getApplication();
/** @var \Joomla\CMS\Document\HtmlDocument $doc */
$doc = $app->getDocument();
$doc->addCustomTag('<link rel="dns-prefetch" href="https://fonts.gstatic.com"> ');
$doc->addCustomTag('<link rel="dns-prefetch" href="https://fonts.googleapis.com"> ');
$doc->addCustomTag('<link rel="dns-prefetch" href="https://www.google.com"> ');
$doc->addCustomTag('<link rel="dns-prefetch" href="https://www.gstatic.com"> ');

Pré-conectar

Fazer com que o navegador faça a consulta DNS com antecedência é ótimo. Se você, no entanto, sabe que o navegador definitivamente precisará se conectar ao site externo para extrair recursos usados para renderizar a página – como CSS, JavaScript, imagens ou arquivos de fonte – faz ainda mais sentido dizer ao navegador para abrir uma conexão HTTP com o servidor externo e mantenha-o pronto.

Isso funciona exatamente da mesma maneira que a pré-busca de DNS, exceto que em vez de rel="dns-prefetch" você usa rel="preconnect". O caso de uso prático que encontrei para isso é o Google Fonts, onde você definitivamente sabe que o navegador precisará se conectar a fonts.gstatic.com para recuperar o arquivo de fonte real. Também estou planejando usá-lo na página de vídeo do nosso site comercial para iniciar uma conexão com o CDN de onde o vídeo e a imagem do quadro do banner são recuperados, reduzindo apenas um pouquinho o tempo necessário para iniciar a reprodução do vídeo.

Pré-carregamento de recursos

Em alguns casos, os arquivos que precisam ser carregados não são imediatamente óbvios para o navegador, apenas analisando o HTML da sua página. Alguns recursos podem ser referenciados a partir de um arquivo CSS ou JavaScript. Quando isso acontece, o navegador diz "ah, ótimo, deixe-me adicionar outro arquivo à minha lista de tarefas". Isso pode ter um efeito adverso no desempenho do seu site porque esse arquivo pode ser importante, por exemplo. um arquivo de fonte ou imagem que causará uma mudança de layout ou um arquivo JSON ou JavaScript hospedado externamente que só se tornará aparente quando o navegador terminar de analisar e executar outra parte do JavaScript. Este último é muito comum ao incluir código JavaScript de serviços de terceiros.

Novamente, você pode avisar seu navegador, dizendo-lhe que ele precisará recuperar tal ou tal arquivo. Ao dar a dica logo no início da seção HEAD do documento HTML, o navegador pode otimizar a recuperação desse arquivo, ou seja, começar a baixá-lo em segundo plano enquanto seu thread principal está ocupado aguardando e analisando qualquer bloqueio de CSS e JavaScript na página.

Assim como a pré-busca de DNS, o pré-carregamento de recursos funciona colocando elementos LINK especiais no HEAD do site.

Se você estiver usando um plugin para fazer isso, os elementos LINK ficarão assim:

<link rel="preload" href="https://www.example.com/media/jui/fonts/IcoMoon.woff" as="font" crossorigin="anonymous">

Da mesma forma, ao editar o arquivo index.php do seu template, ele ficará assim:

$doc->addCustomTag(sprintf('<link rel="preload" href="/%smedia/jui/fonts/IcoMoon.woff" as="font" crossorigin="anonymous">',Joomla\CMS\Uri\Uri::root(true )));

É importante observar que, diferentemente da pré-busca de DNS, você fornece uma URL completa para um arquivo no atributo href. Além disso, o atributo as é obrigatório e informa ao navegador a intenção de uso desse arquivo, por exemplo. fonte, imagem, vídeo etc. O atributo crossorigin é essencialmente obrigatório para navegadores modernos e os instrui como lidar com a autenticação de solicitação. Configurá-lo como anônimo não envia cookies, autenticação HTTP ou certificados SSL do lado do cliente e é sempre permitido. Configurá-lo para use-credentials passará cookies, autenticação HTTP ou certificados SSL do lado do cliente, mas está sujeito à política de recursos de origem cruzada do site, que pode efetivamente impedir a solicitação, anulando seu esforço em sugerir o navegador.

Trocar fontes

Este é um recurso importante quando você usa fontes personalizadas. Por padrão, o navegador tentará adivinhar se deve exibir algum texto enquanto sua fonte personalizada ainda não foi carregada e analisada. Se a sua fonte CSS não incluir uma fonte de sistema substituta, o comportamento padrão é "bloquear", o que significa que seu navegador não exibirá nenhum texto antes de recuperar a fonte personalizada que você especificou. Você já visitou um site que exibia todo o texto para sempre e ficou frustrado ao olhar para uma página quase toda em branco com alguns elementos de imagem aqui e ali até puf! todo o texto estava lá de repente? Sim, é por isso.

Felizmente, você pode dizer ao navegador para fazer algo diferente usando o atributo CSS font-display. Configurá-lo para swap significa que o navegador ficará impaciente e voltará à fonte padrão enquanto aguarda o download da fonte personalizada. Quando a fonte personalizada for baixada, mesmo que demore vários minutos, a página será renderizada novamente com a nova fonte. Se você configurá-lo como substituto, o navegador também ficará impaciente, mas se a fonte personalizada não carregar em segundos, ele permanecerá com a fonte do sistema substituto e ignorará completamente a fonte personalizada.

Se você estiver usando o Google Fonts, basta substituir /css? com /css2? no URL e anexando &display=swap. Por exemplo, carregar o Noto Sans torna-se:

<link href="https://fonts.googleapis.com/css2?family=Open+Sans&display=swap" rel="stylesheet">

A melhor coisa a fazer é configurar boas fontes substitutas e definir a exibição da fonte para troca. Para fontes de ícones, você deve usar block para que o que seja renderizado seja um espaço em branco enquanto a fonte do ícone está carregando.

Falando em alternativas de fontes, você deve incluir fontes do sistema como alternativas. Por exemplo, fontes sem serifa podem ter um substituto de

BlinkMacSystemFont, -apple-system, "Segoe UI", "Roboto", Helvetica, Arial, sans-serif

que abrange dispositivos Apple mais novos e mais antigos, Windows 7 a 10, Android e sistemas legados, preferindo a interface de usuário padrão sem fonte serifada em cada plataforma. A ideia é que o usuário veja uma fonte familiar em vez do substituto sem serifa padrão, normalmente mais feio. Em dispositivos Apple, por exemplo, o padrão é a fonte do sistema San Francisco em vez da fonte Helvetica.

Ícones do site (favicons)

Nos velhos tempos, quando os dinossauros vagavam pela Terra e 800x600 pixels eram considerados “alta resolução” – isso seria por volta de 2001 – havia favicons de 16x16 pixels, originalmente destinados a apresentar um logotipo de site nos sites favoritos marcados pelo usuário. Avançando duas décadas, esses ícones não têm mais 16 pixels quadrados ou estão limitados a marcadores.

É claro que os favicons ainda são usados para marcadores e guias de sites, assim como faziam há 20 anos. Eles também são usados para exibir ícones de toque em smartphones e tablets quando você cria um atalho para o site na tela inicial. Além disso, eles são usados por serviços de terceiros para criar um logotipo para o seu site. Se você não sabia sobre esse uso, confira este CodePen de terceiros(https://codepen.io/Jivings/pen/eYdpBOQ).

Para complicar ainda mais as coisas, existem vários tamanhos exigidos por diferentes gerações de smartphones, tablets, navegadores e sistemas operacionais. Você pode encontrar uma ótima referência para tudo isso em https://github.com/audreyfeldroy/favicon-cheat-sheet

Se criássemos uma lista que suportasse todos os dispositivos, navegadores e sistemas operacionais de 2013 a 2020, inclusive, teríamos o seguinte:

Um arquivo ICO contendo 16x16, 24x24, 32x32, 48x48 e 64x64 pixels.
Sete arquivos PNG nos tamanhos 32x32, 128x128, 152x152, 167x167, 180x180, 192x192 e 196x196 pixels.
Um PNG de 144x144 pixels e uma cor de fundo para os blocos do site da UI Moderna do Windows que estão obsoletos, mas ainda não foram removidos (e muito usados no Windows 7, que as pessoas ainda usam por qualquer motivo).

Adicioná-los ao Joomla requer editar o arquivo index.php do template e colocá-lo antes de gerar o HEAD do documento HTML. Supondo que seus arquivos estejam armazenados em images/logos/favicon temos o seguinte código:

$doc = JFactory::getApplication()->getDocument();
$baseUrl = JUri::base();

// O bom e velho 16px

favicon quare
$doc->addFavicon($baseUrl . 'images/logos/favicon/favicon-16.ico');
// Fallback padrão: 152x152 pixels
$doc->addHeadLink($baseUrl . 'images/logos/favicon/favicon-152.png', 'apple-touch-icon-precomposed', 'rel');
// Bloco da UI moderna do Windows
$doc->setMetaData('msapplication-TileColor', '#d43431');
$doc->setMetaData('msapplication-TileImage', $baseUrl . 'images/logos/favicon/favicon-144.png');
//Todos os outros tamanhos
$doc->addHeadLink($baseUrl . 'images/logos/favicon/favicon-196.png', 'apple-touch-icon-precomposed', 'rel', ['tamanhos' => "196x196"]);
$doc->addHeadLink($baseUrl . 'images/logos/favicon/favicon-192.png', 'apple-touch-icon-precomposed', 'rel', ['tamanhos' => "192x192"]);
$doc->addHeadLink($baseUrl . 'images/logos/favicon/favicon-180.png', 'apple-touch-icon-precomposed', 'rel', ['tamanhos' => "180x180"]);
$doc->addHeadLink($baseUrl . 'images/logos/favicon/favicon-167.png', 'apple-touch-icon-precomposed', 'rel', ['tamanhos' => "167x167"]);
$doc->addHeadLink($baseUrl . 'images/logos/favicon/favicon-152.png', 'apple-touch-icon-precomposed', 'rel', ['tamanhos' => "152x152"]);
$doc->addHeadLink($baseUrl . 'images/logos/favicon/favicon-128.png', 'apple-touch-icon-precomposed', 'rel', ['tamanhos' => "128x128"]);
$doc->addHeadLink($baseUrl . 'images/logos/favicon/favicon-32.png', 'icon', 'rel', ['tamanhos' => "32x32"]);

O problema óbvio é que você precisa se lembrar de fazer todas essas alterações que podem ser impraticáveis. Você pode automatizar isso enviando apenas dois arquivos em sua pasta images/logos/favicon:

favicon.ico que você ainda precisa gerar, mas pode escapar incluindo apenas o ícone legado de 16x16px
favicon.png um PNG transparente de 512x512 pixels com a versão de alta qualidade do seu logotipo

Você pode então usar este código substancialmente mais complicado para gerar automaticamente todos os tamanhos necessários:

/**
* Generate favicons.
*
* You need to upload two files to the $basePath folder, by default images/logos/favicon :
* - favicon.ico which includes 16x16, 24x24, 32x32, 48x48 and 64x64 pixel images.
* - favicon.png a 512x512 pixel transparent PNG
*
* @param string $basePath Path with your favicons relative to your site's root
* @param int[] $favIconSizes List of sizes to generate e.g. [32, 57, 152], see https://github.com/audreyr/favicon-cheat-sheet
* @param string|null $tileColor HTML hex color for the IE Modern UI tile icon, null to skip generating it
* @param int $defaultSize Fallback favicon size when the browser doesn't request a specific dimension
*/
$faviconGenerator = function (string $basePath, array $favIconSizes, ?string $tileColor, int $defaultSize = 152) use ($doc) {
$ensureSize = function (int $size) use ($basePath) {
$filePath = JPATH_SITE . '/' . $basePath . '/favicon-' . $size . '.png';

if (!file_exists($filePath))
{
try
{
(new \Joomla\CMS\Image\Image(dirname($filePath) . '/favicon.jpg'))
->resize($size, $size)
->toFile($filePath, IMAGETYPE_PNG, ['quality' => 9]);
}
catch (\Exception $e)
{
}
}

return basename($filePath);
};

$baseUrl = Uri::base(false) . $basePath . '/';

// Fallback .ICO file
$doc->addFavicon($baseUrl . 'favicon.ico?' . $doc->getMediaVersion());
// Default favicon
$doc->addHeadLink($baseUrl . $ensureSize($defaultSize) . '?' . $doc->getMediaVersion(), 'apple-touch-icon-precomposed', 'rel');
// Internet Explorer Modern UI (formerly Metro) tile icon, classic Edge
if (!is_null($tileColor))
{
$doc->setMetaData('msapplication-TileColor', $tileColor);
$doc->setMetaData('msapplication-TileImage', $baseUrl . $ensureSize(144) . '?' . $doc->getMediaVersion());
}
// All other favicons
foreach ($favIconSizes as $size)
{
$doc->addHeadLink($baseUrl . $ensureSize($size) . '?' . $doc->getMediaVersion(), 'apple-touch-icon-precomposed', 'rel', ['sizes' => "{$size}x{$size}"]);
}
};
$faviconGenerator('images/logos/favicon', [
// Favicons size reference: https://github.com/audreyr/favicon-cheat-sheet
32, // Default fallback for most desktop browsers.
// 57, // Deprecated: Standard iOS home screen (iPod Touch, iPhone first generation to 3G), old Android
// 72, // Deprecated: First- and second-generation iPad
// 76, // Deprecated: iPad home screen icon
// 96, // Deprecated: GoogleTV icon
// 114, // Deprecated: iPhone retina touch icon with iOS <= 6
// 120, // Deprecated: iPhone retina touch icon with iOS >= 7
128, // Chrome Web Store icon & Small Windows 8 Star Screen Icon
// 144, // Deprecated: IE10 Metro tile for pinned site, iPad Retina with iOS <=> 6
152, // iPad Retina with iOS >= 7
167, // iPad Retina with iOS >= 10 (in practice iOS will still use 152×152)
180, // iPhone Retina
192, // Google Developer Web App Manifest Recommendation
// 195, // Deprecated: Opera Speed Dial icon (Not working in Opera 15 and later)
196, // Chrome for Android home screen icon
// 228, // Deprecated: Opera Coast icon
], '#d43431');

Este código pode não produzir os melhores resultados em todas as circunstâncias. Os logotipos reduzidos podem parecer um pouco desfocados. Sempre que possível, gere você mesmo os PNGs a partir de uma fonte vetorial e ajuste manualmente o tamanho dos arquivos PNG com pngcrush ou uma ferramenta semelhante.

Avisos de análises e cookies

Como você está navegando na web como todos nós, você já deve estar profundamente frustrado com os banners de cookies que ocupam todos os cantos da web. Na maioria dos casos, os únicos cookies aplicáveis que não são obrigatórios são aqueles utilizados por serviços analíticos como o Google Analytics. Se o seu site precisa mostrar um banner de cookie só porque você está usando o Analytics, pare e pense: você realmente precisa dos recursos fornecidos pelo Google Analytics ou serviços semelhantes?

Na maioria dos casos, você não precisa desses recursos avançados. Se tudo que você precisa é de análises básicas sobre quantas pessoas visitaram seu site, se vieram de pesquisa orgânica ou de um link de referência e de qual país elas vêm, você pode não precisar procurar além do painel de controle de hospedagem, que provavelmente já oferece AWstats ou uma solução semelhante. Eles funcionam analisando os logs de acesso do servidor web e não exigem cookies, portanto, não há banners de cookies em seu site.

Outra solução é usar um serviço de análise auto-hospedado, como o Matomo (anteriormente chamado de Piwik). Ele oferece a maioria dos recursos que você obteria com o Google Analytics, mas como é uma solução original compatível com GDPR e CCPA, você nem precisa mostrar um banner de cookie. Ele pode até importar dados do Google Analytics para que você tenha continuidade de seus dados, se isso for importante para seu caso de uso comercial.

Ao eliminar a necessidade de um banner de cookie, você torna seu site mais fácil de navegar e muito menos frustrante para seus usuários. Saber que você pode fazer isso sem sacrificar os dados necessários para tomar decisões de negócios e sem forçar seus usuários a compartilhar seus dados com terceiros que ganham dinheiro com a venda de anúncios personalizados (o Google é principalmente uma rede de anúncios, se você ainda não o fez). notado) é fortalecedor.

Modo escuro/dark

Muito provavelmente o design do seu site vem apenas em um esquema de cores e é provável que seja um tema “claro”, ou seja, um fundo claro com texto escuro. Este tem sido o caso da maioria dos sites nas últimas duas décadas e é consistente com o que a maioria dos sistemas operacionais costumava oferecer apenas como opção.

Para alguns usuários esse esquema de cores é inacessível e usar cores de tela invertidas simplesmente não é uma solução muito boa; todas as cores são invertidas, incluindo ilustrações e imagens, criando uma experiência chocante. Oferecer também um esquema de cores escuras para o seu site o tornará mais acessível. Isso também tornará seu site mais atraente para pessoas que preferem esquemas de cores escuras em vez de cores claras – um bom ponto a considerar se o público-alvo do seu site são geeks e jogadores.

Já escrevi sobre o que é o Modo Escuro, por que e como usá-lo e recentemente fiz uma apresentação sobre o Modo Escuro. Vou simplesmente criar um link para esses recursos, em vez de me repetir no que já é um artigo muito longo.
https://www.dionysopoulos.me/dark-mode-is-the-new-black.html
https://www.joomlashack.com/blog/tutorials/dark-mode/

AMP

Comecei a trabalhar nesta série de artigos em julho de 2020 e pretendia recomendar AMP (Accelerated Mobile Pages) para o seu site. Já não tenho tanta certeza.

Se você ainda não sabia, AMP é praticamente um subconjunto de HTML com algumas peculiaridades que tornam o carregamento mais rápido em dispositivos móveis. É muito mais restritivo do que um site responsivo normal. O apelo do padrão AMP é que o Google priorizará o conteúdo AMP nos carrosséis de resultados de pesquisa quando um usuário fizer uma pesquisa usando o aplicativo do Google em um smartphone.

A desvantagem é que o AMP é muito específico do Google e não tem suporte fora do ecossistema do Google. Além disso, as pessoas que clicarem nos resultados de pesquisa que apontam para as páginas AMP do seu site verão google.com na barra de endereço do navegador, em vez do seu site. Sinto que essas são as principais desvantagens que isolam você do seu público.

O fato de um membro do Comitê Consultivo da AMP ter renunciado recentemente porque sentiu que o Google havia sequestrado todo o projeto AMP para seu próprio ganho e que o Procurador Geral do Texas entrou com uma ação antitruste contra o Google que acabaria com o tratamento preferencial da AMP no carrossel de pesquisa me faz pensar se faz sentido introduzir AMP em seu site. Pela minha experiência, a integração é praticamente simples se você quiser criar seu próprio modelo personalizado para suas páginas AMP.

Por fim, com base nas análises que coletei em meu próprio site, o AMP não traz tanto tráfego quanto deveria. A maior parte do meu tráfego vem de links diretos de outros lugares, pesquisa orgânica que leva ao meu template responsivo regular e mídia social. O AMP era apenas um pontinho no radar das fontes de tráfego.

Então, em vez de dizer como integrar AMP ao seu site, direi que provavelmente não deveria. Se você estiver, no entanto, ele estará

Antes de implementá-lo, existem soluções para Joomla. Usei o wbAMP, mas devo avisar que criar um modelo personalizado é bastante complicado. Estou inclinado a remover o AMP do meu site em uma iteração futura - muito provavelmente quando eu refazer meu site no Joomla 4.0 assim que a versão do Joomla for lançada oficialmente.

Termina em:

https://www.dionysopoulos.me/joomla-performance-tuning-v-content-quality.html