Crossbrowsing, Firefox, caching e SEO
Quattro chiacchiere… Spero interessanti.
**) Cross-browsing: quali browser utilizzare per lo sviluppo?
Una prima versione di Mozilla Firefox realmente stabile e di successo fu la 1.5 risalente alla fine del 2005. Molto valido sul piano delle prestazioni, un ulteriore punto di forza di Firefox è dato dall’espandibilità, potendo vantare un amplissimo deposito di plugin (addon) integrabili nativamente. I plugin forniscono funzionalità aggiuntive e numerose opzioni di personalizzazione e configurazione.
In particolare, Firefox combinato con il plugin Firebug diventa uno strumento di sviluppo essenziale per il webmaster.
Firefox ha dalla sua una buona capacità di trattamento di codice HTML non valido: è in grado di individuare e correggere automaticamente errori di codifica HTML (p.e. tag non chiusi), garantendo un rendering ottimale delle pagine. Questo aspetto è importante per l’utilizzatore normale, ma può generare qualche problema agli sviluppatori meno smaliziati. Firefox attualmente è usato da più di un internauta su cinque (il 23%) e ciò lo rende il secondo browser più popolare della rete dopo Internet Explorer. Uno sviluppo Web non può quindi esimersi dalla compatibilità con Firefox.
Le ultime versioni di Internet Explorer (la 7 e la 8 ) sono molto migliorate sul piano prestazionale rispetto alla precedente versione 6. Essendo il browser più popolare, uno sviluppo Web che voglia fregiarsi dell’etichetta “crossbrowser” non può prescindere da una corretta visualizzazione su IE. Rispetto a Firefox, IE è molto più rigido sugli standard di codifica HTML ed è meno “propenso” alla correzione automatica di errori di codifica. Questa rigidità, comunque, spesso aiuta ad ottenere sviluppi maggiormente aderenti con gli standard e più inclini a superare eventuali test di validazione. Internet Explorer versione 8 ha una modalità di funzionamento “compatibile” con le versioni precenti (in particolare IE 7), ciò permette, con lo stesso browser, di provare il comportamento di una pagina Web con due versioni diverse 7 e 8. La modalità compatibile, comunque, non copre anche le caratteristiche del più vecchio (e ancora diffuso) IE 6. Per questo motivo, è sempre utile avere sottomano una macchina virtuale (Microsoft ne fornisce di gratuite e a scadenza su questo link) con l’IE 6 attivo. Nell’uso di IE 6, è bene considerare che questa versione soffre di antipatici bug di rendering, generalmente indirizzabili con l’uso di CSS dedicati. Un sito Web funzionante con IE e Firefox è buon candidato ad essere considerato crossbrowser.
In tutto questo non escluderei Chrome di Google. Chrome è un browser interessante con ottime caratteristiche sul piano del rendering, della stabilità (su questi aspetti preferibile anche a Firefox), è basato su Webkit un framework che è anche il motore di Apple Safari (browser per piattaforma MACOS) e di altre applicazioni. Inoltre, Chrome è un prodotto di Google e come tale gode e godrà di una diffusione sempre più crescente e capillare. La corretta visualizzazione del sito su Chrome, in aggiunta a Firefox e IE, garantisce una maggiore copertura dei possibili browser usabili dagli utenti.
Dopo Internet Explorer, Mozilla Firefox e Apple Safari, il quarto browser più usato è Opera. Opera offre ottime caratteristiche di usabilità ed espandibilità. Comunque, in Italia, Opera ha un grado di diffusione molto contenuto. Pragmaticamente, la compatibilità con i tre browser precedenti (IE, FF, Chrome), a meno di requisiti particolari, offre una buona garanzia di compatibilità anche con Opera.
**) Firefox e la cache: sorpresa!
Tutti i browser usano la cache. La cache è l’area (di memoria e su disco) in cui il motore del browser deposita temporaneamente i file scaricati per poterli recuperare velocemente al momento della visualizzazione ripetuta delle medesime pagine. L’accesso ai file scaricati in locale è – ovviamente – più veloce rispetto a scaricare i medesimi dalla rete. Per la navigazione, la cache è una funzionalità importante. Per lo sviluppatore, potrebbe essere necessario disabilitare la cache temporaneamente al fine di disporre di una versione sempre fresca delle pagine in corso di realizzazione. Inoltre, le aree di amministrazione di alcuni CMS (per esempio Joomla) possono risentire della cache attivata.
Con la versione 3.x di Firefox (almeno fino alla 3.5.2), non è più possibile impostare il funzionamento della cache dall’interfaccia di configurazione del browser. Scelta discutibile, ma fortunatamente superabile attraverso l’impostazione del parametro browser.cache.check_doc_frequency dalla pagina di configurazione accessibile digitando about:config. Il parametro suddetto può assumere uno dei seguenti valori numerici:
0 una volta per sessione
1 ognivolta
2 mai
3 quando è scaduta la pagina
L’impostazione di default è la 3, l’impostazione adeguata per lo sviluppatore è 1.
**) Caching mediante header HTTP e metatag HTML
Mi è spesso capitato di imbattermi nelle seguenti impostazioni (codice PHP esemplificativo):
header( ‘Expires: Mon, 26 Jul 1997 05:00:00 GMT’ );
header( ‘Last-Modified: ‘ . gmdate( ‘D, d M Y H:i:s’ ) . ‘ GMT’ );
header( ‘Cache-Control: no-store, no-cache, must-revalidate’ );
header( ‘Cache-Control: post-check=0, pre-check=0′, false );
header( ‘Pragma: no-cache’ );
Questa sequenza, per ragioni che non rientrano nell’obiettivo di questo post, sono molto frequenti su sistemi Joomla.
Attraverso queste istruzioni, il Web Server invia (prima del codice HTML della pagina) informazioni (dette header HTTP) che sono leggibili solo dai browser o da eventuali proxy. PHP, come mostrato sopra, permette di personalizzare l’invio di queste informazioni per ogni singola pagina. In alternativa a PHP, è possibile configurare direttamente il web server (per esempio impostazioni nel file .htacces di Apache) affinché esso generi gli header HTTP desiderati.
Oltre agli header HTTP, è possibile inviare la medesima tipologia di informazioni inserendo nella sezione <HEAD></HEAD> della pagina HTML dei metatag. Per esempio, i metatag funzionalmente equivalenti alle istruzioni precedenti sono (sempre con riferimento ad uso PHP):
<META HTTP-EQUIV=”EXPIRES” CONTENT=”Mon, 26 Jul 1997 05:00:00 GMT”>
<META HTTP-EQUIV=”LAST-MODIFIED” CONTENT=”<?=gmdate( ‘D, d M Y H:i:s’ ) . ‘ GMT’?>”>
<META HTTP-EQUIV=”CACHE-CONTROL” CONTENT=”no-store, no-cache, must-revalidate”>
<META HTTP-EQUIV=”CACHE-CONTROL” CONTENT=”post-check=0, pre-check=0″>
<META HTTP-EQUIV=”PRAGMA” CONTENT=”NO-CACHE”>
Diciamo subito che il metodo più corretto per controllare il meccanismo di caching sarebbe tramite gli header HTTP. I browser, ma soprattutto i proxy, potrebbero ignorare i metatag. A differenza dei header HTTP, i metatag sono istruzioni contenute nel codice HTML della pagina.
Google e gli altri motori di ricerca sono in grado di elaborare entrambe le tipologie (header e meta), ma – come vedremo – ci sono alcune eccezioni.
Analizziamo anzitutto il significato delle informazioni inviate (a prescindere dalla modalità header HTTP o metatag).
La prima informazione “expires” indica la data, in formato GMT, di scandenza della pagina. Una pagina scaduta non dovrebbe essere memorizzata nella cache del browser e una nuova copia dovrebbe essere richiesta dal browser.
L’informazione “last-modified” indica la data, in formato GMT, dell’ultima volta il cui il documento è stato modificato.
L’informazione “cache-control”/”no-store, no-cache, must-revalidate” indica che nessuna parte della pagina ottenuta in risposta deve essere memorizzata permanentemente (su disco) nella cache (no-store); un’eventuale richiesta futura della pagina deve sempre prevedere una rivalidazione con il server, non è possibile usare direttamente la versione in cache (no-cache); la pagina ottenuta non può essere successivamente riusata se è scaduta, il browser è obbligato a validare la pagina con il server (must-revalidate).
“cache-control”/”post-check=0, pre-check=0″: la direttiva “post-check” definisce un intervallo di tempo in secondi tale per cui, se entro questo tempo la pagina è richiamata, essa viene letta dalla cache e poi aggiornata in background allo scadere del tempo. La direttiva “pre-check” definisce un intervallo di tempo in secondi tale per cui, se entro questo tempo la pagina è richiamata, essa viene prima riletta dal server e poi visualizzata.
L’informazione “pragma”/”no-cache” esegue la stessa funzione di cache-control=”no-cache”, ma è necessario utilizzarla per mantenere la compatibilità con la versione 1.0 del protocollo HTTP (vecchi browser p.e. IE 5 o sistemi proxy datati).
Come già anticipato è meglio specificare i comandi sulla cache mediante header HTTP piuttosto che con metatag. I metatag, infatti, possono influenzare i browser ma i proxy e altri sistemi intermedi potrebbero comunque “cachare” le informazioni.
Veniamo ora agli effetti “SEO” delle suddette impostazioni di cache.
**) Caching e SEO
Expires
Generalmente, “expires” è usato in combinazione con ”revisit-after”, per esempio:
<META NAME=”revisit-after” CONTENT=” 30 days “>
attraverso questo metatag, si sostiene su alcuni forum più o meno specializzati, sarebbe possibile condizionare la frequenza di crawling dei motori di ricerca.
Ancora un altro modo di usare “expires” è il seguente:
<META HTTP-EQUIV=”expires”CONTENT=”0″>
in questo modo si disabiliterebbe il caching obbligando i motori di ricerca (e, in generale, tutti i web client) a rileggere la pagina dal server.
Praticamente: “expires” è ignorato dai motori di ricerca. Una pagina già indicizzata che scade (stando all’impostazione di “expires”) non risente di penalizzazione in SERP (posizioni peggiori rispetto a pagine più nuove), inoltre, “revisit-after” non influenza la frequenza di crawling.
Tuttavia, è opportuno che una pagina nuova abbia un “expires” consistente con la sua prima indicizzazione. Mettiamoci nei panni di un ipotetico motore di ricerca: alla prima indicizzazione, che senso avrebbe indicizzare (o ben posizionare) una nuova pagina già scaduta tempo addietro?
Interessante anche la seguente nota di Google [1]:
“The http-equiv values pragma and expires are attempts at bypassing caches without having to set the HTTP headers correctly. These are probably unnecessary uses; any scenario where there is a legitimate reason to limit caching, the author is going to have enough control over the server to send the appropriate headers. In addition, the meta tags can’t be considered reliable (e.g. proxies and transparent caches aren’t going to honour them).”
Last Modified
Questa è un’istruzione molto discussa. Sono in molti a sostenere che possa contribuire ad influenzare la frequenza di crawling. A mio avviso, questo comando può influenzare il crawling (ma non la frequenza) se il web server è in grado di supportare anche la request HTTP If-Modified-Since. Attraverso questa request, un client (e nello specifico un crawler) può richiedere al web server (attraverso una HTTP GET), se una pagina è stata modificata dopo una certa data; in caso affermativo viene restituita la pagina, in caso negativo un errore 304.
Google scrive [2]:
“Make sure your web server supports the If-Modified-Since HTTP header. This feature allows your web server to tell Google whether your content has changed since we last crawled your site. Supporting this feature saves you bandwidth and overhead.”
E’ mia convizione che – in aderenza con l’RFC 2068[3] – Google utilizzi l’impostazione “last-modified” per poter comporre una richiesta “If-Modified-Since” che sia consistente con l’orologio del web server, per evitare problemi di sincronizzazione con data ed orario. La mancanza di sincronizzazione deriva da una diversa configurazione del web server e del sistema su cui il googlebot è in esecuzione. La mancanza di sincronizzazione obbligherebbe l’istanza di googlebot a perlustrare sempre tutte le pagine di un sito, con un’evidente penalizzazione in termine di banda e sovraccarico dei web server.
“cache-control=no-cache” e “pragma”
Queste istruzioni non influenzano i motori di ricerca. Esse sono invece utili agli utenti finali. Ad esempio: se i contenuti del tuo sito cambiano quotidianamente, queste istruzioni permetterebbero ai browser degli utenti di recuperare sempre la versione più recente delle pagine.
Analogamente, le altre impostazioni “cache-control” indicate in precedenza, non influenzano i motori di ricerca.
Nel caso di Google, qualora si volesse:
- eliminare completamente una pagina dall’indice del motore (anche se altre pagine contengono link a essa), è necessario aggiungere il metatag”noindex”. Quando Google rileva un metatag “noindex” su una pagina, elimina completamente la pagina dai risultati di ricerca. I contenuti verranno eliminati alla successiva scansione (crawling). <META NAME=”ROBOTS” CONTENT=”NOINDEX”> Questa direttiva non esclude che i link contenuti della pagina vengano seguiti dal googlebot (per evitare questa possibilità bisognerebbe aggiungere il comando “NOFOLLOW” oltre al “NOINDEX”;
- rimuovere una copia della pagina dalla cache di Google, è necessario aggiungere un metatag “noarchive” alla pagina oppure modificarne il contenuto. <META NAME=”GOOGLEBOT” CONTENT=”NOARCHIVE”> In genere, è necessario utilizzare il metatag “noarchive” per rimuovere in modo permanente la versione cache, mentre occorre modificare il contenuto della pagina se si desidera rimuoverla in modo temporaneo, fino alla successiva scansione e al successivo aggiornamento della versione cache con i contenuti più recenti.
**) Quando la cache è un problema. Un consiglio agli sviluppatori.
Chiudo questo post con un consiglio. <<La visualizzazione di contenuti aggiornati in tempo reale non dovrebbe essere eseguita solo ed esclusivamente ricorrendo alla generazione one-time mediante scripting server side>>. Mi spiego meglio. Se una homepage deve visualizzare, ad ogni accesso, dei contenuti diversi, sarebbe cosa buona utilizzare soluzioni come componenti Flash o Ajax, piuttosto che limitarsi a generare dinamicamente in blocco la nuova pagina (p.e. attraverso PHP o altro scripting server side).
Quest’ultima soluzione, infatti, potrebbe andare incontro a numerosi problemi di caching derivanti dalla diversa modalità con cui i browser (e sistemi intermedi) interpretano le eventuali direttive di caching e al modo con cui si è implementata la generazione dei link alle pagine interne del sito (vedi p.e. Joomla SEF).
Spesso, si preferisce la soluzione di generazione “in blocco” in quanto si ritiene che componenti attivi come Flash o codice Ajax non siano leggibili da Google o altri motori. Quest’idea, in realtà, non è più vera: la nuova generazione di crawler è in grado di esaminare i contenuti dinamici incapsulati in componenti Flash e codice Javascript. Infine, eventuali accorgimenti ed impostazioni di caching ad-hoc, potrebbero risolvere il problema di caching sui browser ma aprire problemi successivi con i motori di ricerca.
**) Risorse sulla rete:
[1] http://code.google.com/intl/it-IT/webstats/2005-12/metadata.html
[2] http://www.google.com/support/webmasters/bin/answer.py?answer=35769&hl=en
[3] http://www.faqs.org/rfcs/rfc2068.html
[4] http://www.mnot.net/cache_docs/
[5] http://www.seoconsultants.com/tools/headers.asp
[6] http://www.stepforth.com/resources/server-header-checker-tool
[7] http://www.posizionamento-web.com/spidex.asp

[...] Prova a navigarlo, a dare uno sguardo al codice statico e a quello in elaborazione (usa Firebug). Imparare dal lavoro degli altri, soprattutto se compententi, è sempre una grande [...]