Mod_pagespeed è un modulo di Apache Open Source realizzato da Google che permette di automatizzare le operazioni di miglioramento delle Web Performance delle pagine web. Tramite la configurazione dei vari filtri disponibili è possibile agire su vari elementi della pagina e sul settaggio dell'erogazione risorse.

Oltre alla sua utilità pratica questo modulo ha anche un grande valore formativo in quanto il suo studio permette di apprendere tecniche interessanti di ottimizzazione delle pagine.

Indice

Premessa sulla velocità dei siti

High Performance Web Sites

Come molti studi hanno dimostrato, in passato e oggi, la velocità di risposta rappresenta un elemento cruciale nel campo dell'interazione uomo-macchina (HCI). Prima Yahoo! e poi Google (anche grazie al passaggio di Steve Souders presso l'azienda di Mountain View) hanno evangelizzato e spinto per la diffusione della cultura delle web performance fornendo tantissime risorse e strumenti utili ai frontend developer.

Nel 2007 infatti proprio Souders con il suo libro "High Performance Websites" ha formulato le 14 regole per ottenere dei siti veloci. Queste regole sono sopravvissute alla sfida del tempo e sono tutt'oggi ancora in larga parte valide anche se di recente sono state affinate e rivolte maggiormente verso il miglioramento del tempo di rendering.

Le 14 regole per un sito veloce

  • Regola 1 - Ridurre il numero di richieste HTTP
  • Regola 2 - Usare una Content Delivery Network
  • Regola 3 - Aggiungere un Expires Header
  • Regola 4 - Gzip delle risorse
  • Regola 5 - Mettere i fogli di stile in alto
  • Regola 6 - Mettere gli script in fondo
  • Regola 7 - Evitare CSS Expressions
  • Regola 8 - Rendere i JavaScript e i CSS esterni
  • Regola 9 - Ridurre DNS Lookup
  • Regola 10 - Minificare JavaScript
  • Regola 11 - Evitare Redirect
  • Regola 12 - Rimuovere Script Duplicati
  • Regola 13 - Configurare ETags
  • Regola 14 - Rendere AJAX Cachabile

L'avvento del mobile e gli annunci di Google

L'avvento della rivoluzione mobile ha riposto nuova enfasi verso l'elemento page speed, rinvigorita anche dagli annunci ufficiali di Google relativamente al tempo di caricamento come uno dei 200+ fattori di ranking risalente ad Aprile 2010.

Tutto questo ha spinto gli ingegneri di Google a pensare ad un sistema di automazione dell'ottimizzazione Open-Source con l'obiettivo di rendere il web più veloce e alla portata di molti. Il sito dedicato al progetto è https://developers.google.com/speed/pagespeed/module

La presentazione di Apache mod_pagespeed

Installare mod_pagespeed

Per installare mod_pagespeed è necessario scaricare i sorgenti da questa pagina https://developers.google.com/speed/docs/mod_pagespeed/download

Una volta raggiunta questa pagina sulla destra (freccia rossa nell'immagine) è possibile trovate l'elenco dei file da prelevare.

Dove scaricare i file di installazione mod_pagespeed


Passando sopra ai vari pacchetti è possibile estrarre l'URL di download da utilizzare poi fare la wget dalle nostre macchine.


Recuperare l'URL per il download

Scaricare il pacchetto

Una volta copiato aprire la shell del server, scrivere wget al prompt e clicchiamo con il tasto destro per incollare l'URL del sorgente. Troveremo incollato vicino a wget l'url del pacchetto da scaricare e dunque facendo invio partirà il download.

Scaricare il pacchetto tramite wget


Tempo 6-7 secondi e il pacchetto di mod_pagespeed sarà pronto per essere installato all'interno della cartella di lancio del comando wget. Facendo un ls è possibile vedere il file in rosso.


Verifichiamo che il pacchetto sia stato scaricato

Eseguire il pacchetto

Ora che il pacchetto è sulla nostra macchina è possibile proseguire con l'installazione dello stesso come spiegato nella documentazione.

In questo caso stiamo usando Centos e quindi procederemo come segue

yum install at # se non avete ancora installato 'at'
rpm -U mod-pagespeed-*.rpm
Installiamo il pacchetto con rpm


Potrebbe tornare un warning, ma non è importante. Il pacchetto verrà installato lo stesso e lo sarà aggiornabile in futuro con yum in quanto i repository vengono aggiunti automaticamente. Per prevenire il warning basterà eseguire prima il seguente comando

rpm --import http://dl.google.com/linux/linux_signing_key.pub

Scaricare i file di esempio

Una volta scaricato e installato mod_pagespeed è possibile scaricare il pacchetto di esempi che si trova anche su modpagespeed.com come segue sempre usando la wget e poi decomprimendo l'archivio.

wget https://dl-ssl.google.com/page-speed/mod-pagespeed/mod_pagespeed_examples.tar.gz 
tar -zxvf mod_pagespeed_examples.tar.gz
Scarichiamo i file di esempio per i test


Dopo il download dei file di esempio e dopo l'installazione di mod_pagespeed è necessario verificare nella cartella /etc/httpd/conf.d che siano presenti i file di mod_pagespeed

Verifichiamo che mod_pagespeed sia stato installato correttamente


Se ci sono siamo già a metà dell'opera. Riavviamo Apache

service httpd restart

e visitiamo uno dei qualsiasi siti che girano sulla nostra macchina.

Mod_pagespeed dovrebbe già funzionare con le impostazioni di default.


Verificare che mod_pagespeed funzioni

Provate a fare un controllo tramite curl -D- per vedere se effettivamente gira

Facciamo un CURL per controllare che giri mod_pagespeed


Per verificare il corretto funzionamento del modulo è possibile testare tramite curl le URL appendendo dei parametri e controllando le differenze.

Useremo il parametro

?ModPagespeed=off

per forzare la pagina senza mod_pagespeed.

Disabilitiamo tramite parametro URL il modulo pagespeed.


Facendo una curl senza parametri appesi all'URL invece si può osservare che che mod_pagespeed è effettivamente funzionante.

Controlliamo invece senza parametri che sia attivo.

Testare i filtri rapidamente

Se mod_pagespeed è abilitato possiamo testare tutti i filtri semplicemente usando i parametri

http://www.scienze-naturali.com/?ModPagespeedFilters=lazyload_images

Usando ad esempio il filtro qui sopra potremo testare sulle nostre pagine l'effetto del singolo lazy_load direttamente via browser.

http://www.scienze-naturali.com/?ModPagespeedFilters=defer_javascript

Usando ad esempio il filtro qui sopra potremo testare sulle nostre pagine l'effetto del singolo defer_javascript direttamente via browser.

Le impostazioni di default sono abbastanza “safe” quindi non danno solitamente problemi di alcun tipo, ma per sperimentare e spingere sull'acceleratore allora è importante andare a configurare minuziosamente i punti di esclusione allora i test tramite query string sono uno strumento utilissimo che ci offre un'anteprima di ciò che funziona e ciò che non funziona correttamente.

Esempio

Possiamo escludere mod_pagespeed in determinate cartelle come quelle di amministrazione se notiamo malfunzionamenti o qualsiasi altra cartella su cui vogliamo che non agiscano i suoi filtri.

Configurare mod_pagespeed

CoreFilters - L'impostazione di default

L'impostazione di default è la CoreFilters

ModPagespeedRewriteLevel CoreFilters

che abilita i seguenti filtri:

add_head
combine_css
convert_jpeg_to_progressive
convert_meta_tags
extend_cache
flatten_css_imports
inline_css
inline_import_to_link
inline_javascript
rewrite_css
rewrite_images
rewrite_javascript
rewrite_style_attributes_with_url

PassThrough - L'impostazione personalizzata

Se vogliamo andare a personalizzare i filtri dobbiamo semplicemente cambiare la CoreFilters come segue

ModPagespeedRewriteLevel PassThrough

e specificare tutti i filtri manualmente.

È anche possibile utilizzare l'impostazione di default e disabilitare alcuni filtri tramite ModPagespeedDisableFilters e specificando il relativo filtro da escludere.

Esiste poi anche una direttiva che permette all'amministratore di sistema di proibire l'uso di alcuni filtri ai livelli più bassi che è ModPagespeedForbidFilters.

Tutte queste informazioni sono comunque reperibili qui https://developers.google.com/speed/docs/mod_pagespeed/config_filters

Personalizzare il modulo

È possibile personalizzare le intestazioni HTTP che mostrano Mod_pagespeed come segue

ModPagespeedXHeaderValue "Potenziato da Website Nightmares"

Disabilitare per host o .htaccess

ModPagespeed Off

Esempio in wp-admin o sezioni amministrative.

<IfModule pagespeed_module>
ModPagespeed off
ModPagespeedStatistics off
</IfModule>

Configurare per host

vim miovirtualhost.com.vhost
<Directory /home/miovirtualhost/public_html>
Options -Indexes +FollowSymLinks
allow from all
AllowOverride All
ModPagespeedDomain *.miovirtualhost.com
</Directory>

I filtri

ModPagespeedRewriteLevel PassThrough

##  CACHE
ModPagespeedEnableFilters extend_cache
ModPagespeedEnableFilters extend_cache_images
ModPagespeedEnableFilters extend_cache_scripts
ModPagespeedEnableFilters extend_cache_css
ModPagespeedEnableFilters extend_cache_pdfs

##  ANALYTICS
ModPagespeedEnableFilters insert_ga
ModPagespeedAnalyticsID <Analytics ID>
ModPagespeedEnableFilters make_google_analytics_async

##  IMAGES
ModPagespeedEnableFilters inline_preview_images
ModPagespeedEnableFilters resize_mobile_images
ModPagespeedMaxInlinedPreviewImagesIndex IndexNumber
ModPagespeedMinImageSizeLowResolutionBytes MinBytes
ModPagespeedEnableFilters rewrite_images
ModPagespeedEnableFilters inline_images
ModPagespeedEnableFilters recompress_images
ModPagespeedEnableFilters resize_images
ModPagespeedEnableFilters convert_gif_to_png
ModPagespeedEnableFilters convert_jpeg_to_progressive
ModPagespeedEnableFilters jpeg_subsampling
ModPagespeedEnableFilters recompress_jpeg
ModPagespeedEnableFilters recompress_png
ModPagespeedEnableFilters recompress_webp
ModPagespeedEnableFilters strip_image_color_profile
ModPagespeedEnableFilters strip_image_meta_data
ModPagespeedEnableFilters convert_png_to_jpeg
ModPagespeedEnableFilters convert_jpeg_to_webp
ModPagespeedEnableFilters convert_to_webp_lossless
ModPagespeedEnableFilters strip_image_color_profile
ModPagespeedEnableFilters strip_image_meta_data
ModPagespeedEnableFilters jpeg_subsampling
ModPagespeedEnableFilters insert_image_dimensions
ModPagespeedCssImageInlineMaxBytes MaxBytes
ModPagespeedImageInlineMaxBytes MaxBytes
ModPagespeedImageRecompressionQuality Quality
ModPagespeedJpegRecompressionQuality Quality
ModPagespeedWebpRecompressionQuality Quality
ModPagespeedImageLimitOptimizedPercent Percent
ModPagespeedImageLimitResizeAreaPercent Percent
ModPagespeedEnableFilters convert_jpeg_to_progressive
ModPagespeedImageMaxRewritesAtOnce NumImages

##  COMBINE
ModPagespeedEnableFilters combine_heads

##  CSS SECTION
ModPagespeedEnableFilters combine_css
ModPagespeedEnableFilters outline_css
ModPagespeedCssOutlineMinBytes         3000
ModPagespeedEnableFilters rewrite_css
ModPagespeedEnableFilters rewrite_css,sprite_images
ModPagespeedEnableFilters flatten_css_imports
ModPagespeedCssFlattenMaxBytes bytes
ModPagespeedEnableFilters inline_import_to_link
ModPagespeedEnableFilters inline_css
ModPagespeedCssInlineMaxBytes bytes
ModPagespeedEnableFilters move_css_above_scripts
ModPagespeedEnableFilters move_css_to_head

##  JS SECTION
ModPagespeedEnableFilters combine_javascript
ModPagespeedEnableFilters outline_javascript
ModPagespeedJsOutlineMinBytes         3000
ModPagespeedEnableFilters defer_javascript
ModPagespeedEnableFilters local_storage_cache
ModPagespeedEnableFilters rewrite_javascript
ModPagespeedEnableFilters inline_javascript
ModPagespeedJsInlineMaxBytes bytes
ModPagespeedEnableFilters lazyload_images

##  PREFETCHING
ModPagespeedEnableFilters insert_dns_prefetch

##  BYTE SAVING
ModPagespeedEnableFilters collapse_whitespace
ModPagespeedEnableFilters remove_comments
ModPagespeedRetainComment " google_ad_section*"
ModPagespeedEnableFilters remove_quotes
ModPagespeedEnableFilters trim_urls
ModPagespeedEnableFilters elide_attributes

##  ALTRO
ModPagespeedEnableFilters rewrite_domains
ModPagespeedEnableFilters rewrite_style_attributes
ModPagespeedEnableFilters rewrite_style_attributes_with_url

ModPagespeedEnableFilters convert_meta_tags
ModPagespeedEnableFilters pedantic

Le statistiche

È importante che settiate correttamente i permessi per l'accesso alle statistiche per poterle visualizzare da browser.

    ModPagespeedEnableFilters add_instrumentation
    <Location /mod_pagespeed_beacon>
          SetHandler mod_pagespeed_beacon
    </Location>
    ModPagespeedBeaconUrl "http://109.233.120.71/mod_pagespeed_beacon"
    # Uncomment the following line if you want to disable statistics entirely.
    #
    # ModPagespeedStatistics on

    # This page lets you view statistics about the mod_pagespeed module.
    <Location /mod_pagespeed_statistics>
        Order allow,deny
        # You may insert other "Allow from" lines to add hosts you want to
        # allow to look at generated statistics.  Another possibility is
        # to comment out the "Order" and "Allow" options from the config
        # file, to allow any client that can reach your server to examine
        # statistics.  This might be appropriate in an experimental setup or
        # if the Apache server is protected by a reverse proxy that will
        # filter URLs in some fashion.
        Allow from localhost
        Allow from 127.0.0.1
        Allow from 93.39.
        SetHandler mod_pagespeed_statistics
    </Location>
    <Location /mod_pagespeed_console>
        Order allow,deny
        # This can be configured similarly to mod_pagespeed_statistics above.
        Allow from localhost
        Allow from 127.0.0.1
        Allow from 93.39.
        SetHandler mod_pagespeed_console
    </Location>

    # Page /mod_pagespeed_message lets you view the latest messages from
    # mod_pagespeed, regardless of log-level in your httpd.conf
    # ModPagespeedMessageBufferSize is the maximum number of bytes you would
    # like to dump to your /mod_pagespeed_message page at one time,
    # its default value is 100k bytes.
    # Set it to 0 if you want to disable this feature.
    ModPagespeedMessageBufferSize 100000

    <Location /mod_pagespeed_message>
        Allow from localhost
        Allow from 127.0.0.1
        Allow from 93.39.
        SetHandler mod_pagespeed_message
    </Location>
    <Location /mod_pagespeed_referer_statistics>
        Allow from localhost
        Allow from 127.0.0.1
        Allow from 93.39.
        SetHandler mod_pagespeed_referer_statistics
    </Location>

Le statistiche sono ancora in una fase primordiale, ma con un po' di lavoro si possono ottenere dati interessanti.

Alcune delle statistiche che si possono visualizzare velocemente sono

  • resource_url_domain_rejections: 6105: questo significa che dal momento di riavvio del server mod_pagespeed 6105 risorse che non riscriverà perché i domini da dove vengono recuperate non sono autorizzati per il rewrite con la direttiva ModPagespeedDomain. Questo è abbastanza frequente perché avviene ad esempio ogni volta che una pagina contenente i widget di twitter, facebook o google+ viene ricaricata.
  • rewrite_cached_output_missed_deadline: 4801: quando una risorsa (es. un'immagine JPEG) viene ottimizzata, questo avviene in background, e il risultato viene cachato in modo che le visualizzazioni successive siano più veloci. Per prevenire il rallentamento della prima visualizzazione si può usare un timer di 10 millisecondi per evitare di rallentare il time-to-first byte. Questa statistica ci indica quante volte la deadline è stata superata, e dunque in quali casi la risorsa è rimasta inalterata per quella visualizzazione, ma l'ottimizzazione avviene in background e dunque la cache viene scritta.
  • rewrite_cached_output_hits: 116004: conta il numero di volte che una risorsa ottimizzata viene servita dalla cache per evitare di ri-ottimizzarla.
  • rewrite_cached_output_misses: 934: conta il numero di volte che una risorsa viene cercata nella cache, ma non viene trovata obbligandoci a riscriverla. Notare bene che la risorsa deve essere rigenerata anche quando l'expiration-time è scaduto. Es. se l'immagine ha un cache-control:max-age=600 allora dovremo controllarla ogni 10 minuti per vedere se è cambiata e di conseguenza se è cambiata ri-ottimizzarla.
  • num_flushes: 947: conta il numero di volte che viene chiamata la funzione di Apache ap_flush(), che causa il flush lato browser utente. Questo è importante perché ci mostra quanto mod_pagespeed viene limitato nelle ottimizzazioni che potrebbe fare (Es: mod_pagespeed non può combinare due CSS separati da un Flush).
  • cache_time_us: 572878 - il tempo totale, in microsecondi, attesi aspettando HTTP Cache (file + memory) di mod_pagespeed per rispondere ad una richiesta di lookup, da quando il server è stato avviato.

Ad esempio per avere il dato di caricamento della pagina è possibile fare

total_page_load_ms / page_load_count 

quindi ad esempio

1388261/271 = 5122 millisecondi =5,122 secondi

Documentazionde dei vari filtri

Add Head

Configurazione

Il filtro 'Add Head' si abilita specificando: ModPagespeedEnableFilters add_head nel file pagespeed.conf, ma può essere abilitato automaticamente da altri filtri che lo richiedono (come dipendenza) tra cui combine_heads, move_css_to_head, and add_instrumentation.

Descrizione

Il filtro 'Add Head' è molto semplice. In sostanza aggiunge il tag head se trova un <body> prima di un <head>. Per fare un esempio, se l'HTML è come il seguente:

<html>
 <body>
  <div class="blue yellow big bold">
   Hello, world!
  </div>
 </body>
</html>

Allora mod_pagespeed lo riscriverà come segue:

<html>
 <head>
 </head>
 <body>
  <div class="blue yellow big bold">
   Hello, world!
  </div>
 </body>
</html>

Note

L'utilità principale di questo filtro è relativa agli altri filtri in quanto questo assicura che i filtri che necessitano l'inserimento di elementi nell'head lo trovino per eseguire le loro operazioni correttamente.

Rischi

Rischio minimo.


Add Instrumentation

Configurazione

Il filtro 'Add Instrumentation' si abilita specificando:

ModPagespeedEnableFilters add_instrumentation
<Location /mod_pagespeed_beacon>
	SetHandler mod_pagespeed_beacon
</Location>

nel file pagespeed.conf.

Descrizione

Il filtro 'Add Instrumentation' inietta due piccoli blocchi di JavaScript in ogni pagina HTML. Questi blocchi servono a misurare il tempo che un utente trascorre nello scaricamento e rendering della pagina. Una volta ricevuti questi dati vengono inviati al server e si possono utilizzare per monitorare le performance delle pagine. Operazioni Il risultato che genera questo filtro è in pratica il seguente ipotizzando che il nostro file HTML sia vuoto:

<html>
 <head>
  <script type='text/javascript'>
   window.mod_pagespeed_start = Number(new Date());
 </script>
 </head>
 <body>
  <script type='text/javascript'>
   function g(){
    new Image().src = '/mod_pagespeed_beacon?ets=load:'
     + (Number(new Date())-window.mod_pagespeed_start);
   };
   var f = window.addEventListener;
   if (f) {
    f('load',g,false);
   } else {
    f=window.attachEvent;
    if (f) {
     f('onload',g);
    }
   }
  </script>
 </body>
</html>

Operazione

Il primo tag script viene inserito all'inizio dell'<head> del documento. Questo script registra semplicemente il tempo attuale in una variabile globale e viene piazzato prima possibile nel documento per approssimare al meglio l'inizio del caricamento della pagina.

Il secondo tag script viene inserito alla fine del <body> in modo da interferire il meno possibile con il rendering della pagina. Il tutto funziona registrando un listener per l'evento onLoad della pagina. Questo listener calcola il tempo totale dal caricamento del primo tag script e invia il risultato al server in modo asincrono usando un finto oggetto immagine. Questa tecnica funziona su tutti i moderni browser.

Il filtro add_instrumentation invia un beacon dopo che l'handler onload della pagina viene chiamato. L'utente potrebbe navigare verso un'altra pagina prima che questo venga scatenato. Abilitando la sequente direttiva invece si può forzare il beacon ad essere inviato come parte di un handler onbeforeunload per le pagine dove la navigazione avviene prima dell'evento onload.

ModPagespeedReportUnloadTime on

Di base la destinazione della chiamata asincrona di callback è la URL relativa "/mod_pagespeed_beacon". mod_pagespeed gestisce da solo i risultati includendo all'interno del file di configurazione la seguente direttiva:

<Location /mod_pagespeed_beacon>
   SetHandler mod_pagespeed_beacon
</Location>

Questo handler non fa altro che ritornare un "204 No Content" che non dovrebbe comportare un grosso disturbo al richiedente. Questo registra anche il numero di callbacks e il totale del loro tempo di onLoad nella statistica "page_load_count" e "total_page_load_ms". Questi numeri sono visibili all'URL "/mod_pagespeed_statistics" (che di base è visibile solamente da localhost). Per conoscere il tempo medio di onLoad del proprio sito è sufficiente dividere total_page_load_ms per il page_load_count.

È anche possibile cambiare il percorso del beacon (anche su di un server differente) usando la direttiva ModPagespeedBeaconUrl. Per fare un esempio la sintassi è quella che segue:

<Location /mio/percorso/al/beacon>
	SetHandler mod_pagespeed_beacon
</Location>
ModPagespeedBeaconUrl "/mio/percorso/al/beacon" 

Oppure se si vuole far puntare il beacon ad un URL di un server esterno basta impostare il percorso come segue:

ModPagespeedBeaconUrl "http://mio.server.diverso/mio_beacon"

Se si vuole impostare un beacon https diverso da quello http (per esempio su macchine differenti come mostrato sotto o su porte non standard) è possibile separare le URL http e https con uno spazio.

ModPagespeedBeaconUrl "http://insecure.server/my_beacon https://secure.server/my_beacon"

Se si vogliono delle informazioni più dettagliata sui tempi di caricamento lato utente come

  • medie per le varie pagine
  • browser diversi
  • median times
  • comportamento storico
  • etc.

è possibile farlo utilizzando il log del server in quanto su Apache ogni chiamata di /mod_pagespeed_beacon verrà registrata nel file access.log con timestamp, referer, indirizzo IP, e user-agent – che ci permettono di sapere quando, dove e da chi la misurazione dell'onLoad è stata presa. Ci sono alcuni strumenti che consentono di collezionare e analizzare questi dati come Jiffy.

Requisiti

Il filtro "Add Instrumentation" necessita del filtro “Add Head" e qualora non fosse abilitato lo abiliterà automaticamente. Abilitare l'handler del /mod_pagespeed_beacon nel file di configurazione non è obbligatorio, ma è fortemente consigliato. Senza di esso infatti l'utente otterrà un 404 nel tentativo di comunicare i suoi valori di latenza, il file errors.log si riempirà di errori e non si otterranno i dati nella pagina /mod_pagespeed_statistics.

Rischi

Questo filtro può corrompere la pagina se include JavaScript che si basano sulla conoscenza del primo figlio dell'<head> o l'ultimo figlio del <body>. Il JavaScript iniettato è molto leggero e non dovrebbe causare nessun significato carico extra per il client.

Se si usano già degli strumenti client-side per la misurazione della latenza come Jiffy, Episodes o Boomerang molto probabilmente questo filtro è superfluo.

È importante far notare che i dati riportati in questo modo sono approssimativi e non includono il tempo di risoluzione del dominio, di apertura della connessione e tantomeno il tempo di attesa per il First Byte.


Canonicalize JavaScript Libraries

Configurazione

Il filtro 'Canonicalize JavaScript Libraries' si abilita specificando nel file pagespeed.conf ModPagespeedEnableFilters canonicalize_javascript_libraries

Descrizione

Questo filtro consente di rimpiazzare versioni locali delle più popolari librerie JavaScript con quelle hostate sulle CDN gratuite.

Ci sono varie teorie in merito e la scelta va ponderata in base alle esigenze, ma i maggiori benefici che vengono attribuiti all'uso di queste librerie dai servizi gratuiti sono:

  • il visitatore che atterra per la prima volta sul sito può beneficiare del fatto che visitando altri siti ha già scaricato la stessa libreria e dunque la troverà in cache nel suo browser.
  • I servizi di hosting delle librerie JavaScript fungono da CDN e quindi aiutano a ridurre il carico del nostro server e velocizzare il tempo di caricamento del browser.
  • Non ci sono tariffe nell'uso della banda.

Solitamente la versione hostata dalle CDN dei poveri è ottimizzata con strumenti di minificazione di terze parti e in questo modo sono potenzialmente più ottimizzate della versione che possiamo offrire noi usando mod_pagespeed.

Il set di librerie di base può essere trovato nel file pagespeed_libraries.conf, che viene caricato con pagespeed.conf all'avvio di Apache.

Nella stragrande maggioranza dei casi non è necessario modificare questo file e ad ogni aggiornamento di mod_pagespeed questo verrà aggiornato automaticamente e di conseguenza il modo migliore di aggiungere librerie è sicuramente quello di aggiungerle a pagespeed.conf usando una linea tipo la seguente:

ModPagespeedLibrary 43 1o978_K0_LNE5_ystNklf //www.modpagespeed.com/rewrite_javascript.js

Dove i valori in colonna stanno per:

ModPagespeedLibrary bytes MD5 canonical_url

Il valore bytes è la dimensione in bytes della libreria dopo la minificazione con mod_pagespeed, e MD5 è l'hash MD5 della libreria dopo la minificazione. La minificazione verifica le differenze negli spazi bianchi che possono presentarsi quando lo stesso script viene richiamata da sorgenti diversi.

Il canonical_url è l'URL del servizio di hosting che vogliamo faccia da rimpiazzo per le occorrenze dello script che usiamo. L'URL canonica nel caso d'esempio è protocol-relative e questo significa che i dati verranno richiesti usando lo stesso protocollo (http or https) della pagina che li contiene. A causa di alcuni vecchi browser che non gestiscono le URL protocol-relative in modo corretto, mod_pagespeed risolve la URL protocol-relative sulla base della pagina contenitrice. Non usare canonical URL http nella configurazione che può servire contenuti https altrimenti le pagine riscritte potrebbero esporre il sito ad attacchi e warning del browser. Allo stesso modo è meglio non usare URL https se non si ha la certezza che la libreria verrà caricata da una pagina sicura in quanto la negoziazione SSL aggiunge overhead alla richiesta iniziale.

I dati aggiuntivi di configurazione possono essere generati con l'aiuto di pagespeed_js_minify che è un'utilità installata con mod_pagespeed che permette a partire da una copia locale del JavaScript di generare bytes e MD5 come segue:

pagespeed_js_minify --print_size_and_hash library.js

Operazione

Per poter identificare la libreria e canonicalizzarne l'URL, mod_pagespeed deve ovviamente essere in grado di estrapolare l'URL dalla pagina originale. Proprio perché la canonicalizzazione della libreria si basa sull'identificazione della stessa tramite dimensione e firma Hash non è necessario autorizzare mod_pagespeed al fetch dei contenuti del dominio ospitante la libreria. Quindi in sostanza questo rende più sicura la nostra configurazione di mod_pagespeed. Il browser quindi scaricherà la risorsa dall'URL canonica senza che mod_pagespeed debba effettivamente richiederla.

Esempi

Il filtro in azione si comporta come segue. Qualora il documento originale fosse il seguente:

<html>
	<head>
		<script src="jquery_1_8.js"></script>
		<script src="a.js"></script>
		<script src="b.js"></script>
	</head>
	<body>
		...
	</body>
</html>

Ipotizzando che jquery_1_8.js fosse una versione non minificata della libreria e a.js e b.js contengano codice specifico del sito che usa jquery la pagina verrebbe riscritta come segue:

<html>
	<head>
		<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
		<script src="a.js"></script>
		<script src="b.js"></script>
	</head>
	<body>
	...
	</body>
</html>

L'URL della libreria viene rimpiazzato dal file ospitato su ajax.googleapis.com. È bene notare che la libreria canonicalizzata non viene considerata dalle direttive e filtri relativi all'ottimizzazione dei JavaScript e dunque qualora nell'esempio precedente avessimo il filtro di combine e minify dei file otterremmo una situazione come la seguente:

<html>
	<head>
	<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
	<script src="http://www.example.com/a.js+b.js.pagespeed.jc.zYiUaxFS8I.js"></script>
	</head>
	<body>
	...
	</body>
</html>

In pratica la libreria canonical non viene combinata assieme agli altri due file per evitare di perdere i benefici che l'uso della libreria offre.

Requisiti

Solo le librerie complete e non modificate richiamate da tag <script> nell'HTML vengono riscritte. Le librerie che sono caricate da altri (ad esempio iniettando un loader) e che sono state modificate non vegono canonicalizzate.

Rischi

Bisogna sempre assicurarsi di aver compreso il termini di servizio dei fornitori di librerie. Inoltre le canonical URL fanno riferimento a domini di terze parti e quindi si deve essere consapevoli che la nostra pagina avrà un'ulteriore ricerca DNS alla prima richiesta della libreria anche se questo viene mitigato dal fatto che le librerie dalle URL canoniche sono molto usate e diffuse. La richiesta iniziale dell'URL canonica contiene un header Referer: con l'URL della pagina richiedente. Questo permette all'host del contenuto canonico di vedere un sottoinsieme del traffico al tuo sito (se un browser richiede come prima volta la libreria dal nostro sito). Il provider deve fornire informazioni su come questi dati verranno usati nei termini di servizio. Sempre per lo stesso motivo di cui sopra questo fenomeno viene mitigato dal fatto che con buona probabilità la libreria è già nella cache del nostro visitatore. Può succedere che i dati del nostro JavaScript locale non corrispondano alla versione canonica causando così malfunzionamenti dei nostri script.


Collapse Whitespace

Configurazione

Il filtro 'Collapse Whitespace' si abilita specificando nel pagespeed.conf la direttiva

ModPagespeedEnableFilters collapse_whitespace

Descrizione

Il filtro 'Collapse Whitespace' riduce i byte trasmessi nel file HTML rimuovendo gli spazi bianchi superflui.

Operazione

Il filtro riduce la dimensione dei file HTML rimpiazzando gli spazi bianchi contigui con un solo carattere di spaziatura. Proprio perché le pagine HTML sono spesso formattate con spazi bianchi non necessari, ma utili per la leggibilità questa tecnica riduce in modo automatico la dimensione del file che viene inviato al richiedente.

Per fare un esempio quello che fa il filtro è qualcosa che a partire dal seguente file:

<html>
 <head>
 <title>   Hello, world!   </title>
 <script> var x = 'Hello,  world!';</script>
 </head>
 <body>
  Hello, World!
  < pre >
   Hello,
    World!
  < / pre>
 </body>
</html>

lo converte nel seguente:

<html><head><title>Hello, world!</title><script> var x = 'Hello,  world!';</script></head><body>Hello, World!
< pre >Hello, 
           World!
< / pre ></body></html>

Requisiti

Il filtro 'Collapse Whitespace' non modifica gli spazi bianchi che appaiono tra < pre >, <textarea>, <script> e <style>. Gli spazi bianchi superflui presenti negli script e stili inline possono essere rimossi usando i filtri JS Minify e CSS Minify.

Rischi

L'unico caso in cui il filtro potrebbe dare risultati inattesi è quando viene usata la proprietà "white-space: pre".


Combine CSS

Configurazione

Il filtro 'Combine CSS' si abilita specificando nel file pagespeed.conf la seguente direttiva

ModPagespeedEnableFilters combine_css

Descrizione

'Combine CSS' consente di ridurre il numero di richieste HTTP fatte dal browser durante il refresh della pagina rimpiazzando più file CSS distinti con un singolo file CSS contenente tutto il contenuto dei file distinti. Questo tipo di tecnica è particolarmente efficace con i vecchi browser, che sono limitati a due connessioni per dominio. In aggiunta alla riduzione deil'overhead negli header HTTP e in fase di comunicazione questo approccio offre benefici riducendo il numero di round-trip times.

Operazione

Il filtro "CSS Combine" trova tutti i tag <link> CSS. Se trova più di uno di questi allora rimuove ogni occorrenza e le rimpiazza con una singola chiamata <link> contenente i documenti combinati all'altezza del primo tag trovato. Per fare un esempio, il codice HTML iniziale è il seguente:

<html>
  <head>
    <link rel="stylesheet" type="text/css" href="styles/yellow.css">
    <link rel="stylesheet" type="text/css" href="styles/blue.css">
    <link rel="stylesheet" type="text/css" href="styles/big.css">
    <link rel="stylesheet" type="text/css" href="styles/bold.css">
  </head>
  <body>
    <div class="blue yellow big bold">
      Hello, world!
    </div>
  </body>
</html>

E quello dato in pasto a mod_pagespeed e risputato il seguente:

<html>
  <head>
    <link rel="stylesheet" type="text/css" href="styles/yellow.css+blue.css+big.css+bold.css.pagespeed.cc.xo4He3_gYf.css">
  </head>
  <body>
    <div class="blue yellow big bold">
      Hello, world!
    </div>
  </body>
</html>

Limitazioni

Il filtro CSS Combine opera nello scope di un "flush window". Nel caso specifico alcuni file larghi o generati dinamicamente possono essere “flushati” dal generatore prima che siano completati. Quando il CSS combiner trova un flush, questo emetterà tutte le combinazioni che a visto fino al flush e poi dopo il flush inizierà a collezionare nuove combinazioni CSS. Il filtro genera URL che sono essenzialmente concatenazioni di tutti i file CSS che vengono combinati e questo può portare al superamento del limite di caratteri su IE. Solitamente i server Apache impongono un limite di 250 caratteri per segmento di URL (testo tra slash), ma mod_pagespeed raggira questo limite. È anche possibile forzare la lunghezza di questo valore tramite la seguente direttiva.

ModPagespeedMaxSegmentLength 250

Requisiti

Il filtro 'Combine CSS' necessita di rendere le URL relative assolute e ci sono casi in cui il filtro non unirà le risorse proveniente da URL differenti a meno che queste non vengano esplicitamente autorizzate e dichiarate tramite ModPagespeedDomain. Inoltre questo unirà le varie risorse da domini diversi se sono state mappate tramite ModPagespeedMapRewriteDomain.

Di base il filtro combina insieme file CSS da percorsi diversi mettendoli al livello più basso in comune tra i vari file. Per disabilitare questo comportamente basta settare la seguente direttiva:

ModPagespeedCombineAcrossPaths off

Il filtro manterrà l'ordine dei CSS in quanto l'ordine nei fogli di stile è importante.

Rischi

Il filtro è a basso richio anche se in alcuni casi alcuni JavaScript possono essere scritti per cercare nel DOM riferimenti a <link>.


Combine JavaScript

Configurazione

Il filtro 'Combine JavaScript' si abilita specificando nel file pagespeed.conf la seguente direttiva: ModPagespeedEnableFilters combine_javascript

Descrizione

'Combine JavaScript' consente di ridurre il numero di richieste HTTP fatte dal browser durante il refresh di pagina rimpiazzando più occorrenza di JavaScript distinti con una singola.

Limitazioni

Il filtro JavaScript Combine opera nello scope del "flush window". Nel caso specifico alcuni file larghi o generati dinamicamente possono essere “flushati” dal generatore prima che siano completati. Quando il JS combiner trova un flush, questo emetterà tutte le combinazioni che a visto fino al flush e poi dopo il flush inizierà a collezionare nuove combinazioni JS. Il filtro genera URL che sono essenzialmente concatenazioni di tutti i file JS che vengono combinati e questo può portare al superamento del limite di caratteri su IE. Solitamente i server Apache impongono un limite di 250 caratteri per segmento di URL (testo tra slash), ma mod_pagespeed raggira questo limite. È anche possibile forzare la lunghezza di questo valore tramite la seguente direttiva.

ModPagespeedMaxSegmentLength 250

Requisiti

Di base, il filtro combina insieme script da percorsi differenti piazzando il file generato al livello più basso in comune tra i vari file. Se si vuole disattivare tale comportamente basta usare la seguente direttiva:

ModPagespeedCombineAcrossPaths off

Rischi

Questo filtro è a rischio moderato. I motivi sono molteplici e tra i principali elementi di fastidio ci sono quegli script che cercano i tag <script> nel DOM e il fatto che questo filtro usa l'eval' per decidere il corretto posizionamento nel DOM. Queste cose possono causare comportamenti insapettati su browser differenti e non è stato completamente testato.


Combine Heads

Configurazione

Il filtro 'Combine Heads' si abilita specificando nel file pagespeed.conf la seguente direttiva

ModPagespeedEnableFilters combine_heads

Descrizione

'Combine Heads' accorpa più occorrenze di intestazioni in una sola. Tecnicamente i documenti HTML non possono contenere più occorrenze di sezioni <head>, ma i siti che aggregano contenuti da molteplici sorgenti possono a volte contenere questo problema. Questo filtro sposta il contenuto del secondo <head> all'interno della prima occorrenza. Questo filtro può alterare l'ordine dei contenuti del secondo <head> (es. CSS e JS) che intervengono nel <body>.

Operazione

Il filtro 'Combine Heads' opera spostando il contenuto di tutti gli <head> nella prima occorrenza di <head>. Un esempio di file HTML con questo problema può essere il seguente:

<html>
  <head>
    <link rel="stylesheet" type="text/css" href="styles/yellow.css">
    <link rel="stylesheet" type="text/css" href="styles/blue.css">
  </head>
  <body>
    <div class="blue yellow big bold">
      Hello, world!
    </div>
  </body>
  <head>
    <link rel="stylesheet" type="text/css" href="styles/big.css">
    <link rel="stylesheet" type="text/css" href="styles/bold.css">
  </head>
</html>

mod_pagespeed lo riscriverà come segue con questo filtro:

<html>
  <head>
    <link rel="stylesheet" type="text/css" href="styles/yellow.css">
    <link rel="stylesheet" type="text/css" href="styles/blue.css">
    <link rel="stylesheet" type="text/css" href="styles/big.css">
    <link rel="stylesheet" type="text/css" href="styles/bold.css">
  </head>
  <body>
    <div class="blue yellow big bold">
      Hello, world!
    </div>
  </body>
</html>

Limitazioni

Il filtro 'Combine Heads' opera nello scope del "flush window". Nello specifico alcuni file HTML grnadi o generati dinamicamente possono fare "flush" prima che vengano completati. Se ad esempio il CSS combiner becca un Flush prima della fine del primo <head>, il seguente <head> non verrà unito.

Rischi

Questo filtro è a rischio medio. Se ci sono stili o script nel body tra i due head allora la riscrittura potrebbe invertire l'ordine di essi. Il rischio dunque è che il layout possa subire delle alterazioni causate da queste inversioni.


Convert Meta Tags

Configurazione

Il filtro 'Convert Meta Tags' si abilita specificando nel file pagespeed.conf la seguente direttiva:

ModPagespeedEnableFilters convert_meta_tags

Descrizione

Il filtro 'Convert Meta Tags' aggiunge un response header per ogni meta tag con un attributo http-equiv.

Per fare un esempio

<meta http-eqiv="Content-Language" content="fr">

viene convertito in

Content-Language: fr

negli header. Il tag originale viene lasciato intatto.

Alcuni meta tag http-equiv, soprattutto quelli che specificano il content-type, costringono il browser a riparsare il documento HTML se non fanno match con gli header e in questo modo assicurandosi che questi combacino si previene il reparsing evitando ritardi inutili.

Rischi

Il filtro è a rischio minimo.


Defer JavaScript

Configurazione

Il filtro 'Defer JavaScript' viene abilitato specificando la direttiva seguente nel file pagespeed.conf ModPagespeedEnableFilters defer_javascript

Descrizione

defer_javascript tenta di rimandare l'esecuzione dei JavaScript finché la pagina non è stata caricata completamente. Il defer viene implementato cambiando gli attributi type e src dell'elemento <script> all'interno della pagina HTML in rispettivamente pagespeed_orig_type e pagespeed_orig_src. Oltre a questo aggiunge anche un nuovo tipo di attributo type il cui valore è text/psajs. A seguito di questo un handler di window.onload viene aggiunto all'HTML che esegue gli script rimandati. In alcuni casi non possono essere rimandati alcuni script e proprio per questo defer_javascript tramite l'attributo pagespeed_no_defer esclude questo script dal defering. In questo caso basta una cosa simile

<script pagespeed_no_defer="">...</script>

Limitazioni

Le variabili genitrici accedute da un iframe possono risultare undefined quando viene usato defer_javascript. Tutto il codice JavaScript viene eseguito in modo seriale mentre senza il defer_javascript il browser per quanto possibile cerca di parallelizzare.

Requisiti

defer_javascript è supportato dalle versioni di chrome 15+, safari5+, Firefox3.6+ and IE9+ e per questo il filtro viene disabilitato in automatico se lo User Agent non passa questo test.

Rischi

Questo filtro è ad alto rischio in quanto per quei JavaScript la cui logica dipende dallo stato del DOM possono mutare il loro comportamento a causa del defer_javascript. Se ad esempio il JavaScript è stato scritto per consentire l'azione all'utente prima che la pagina sia stata completamente caricata allora si potrebbero avere dei problemi. Per esempio se un alert viene messo all'inizio della pagina questo con il defer apparirà solamente dopo che il documento sarà completato. Tutte le azioni dunque che necessitano un evento tipo onclick onkeypress non verranno gestiti finché il documento non sarà completo. Altro problema può essere causato se ci sono script inline che dipendo dai JavaScript e dunque facendone il defer questi non possono più funzionare.


Elide Attributes

Configurazione

Il filtro 'Elide Attributes' viene abilitato specificando la direttiva seguente nel file pagespeed.conf

ModPagespeedEnableFilters elide_attributes

Descrizione

Il filtro 'Elide Attributes' consente di ridurre la dimensione dei file HTML eliminando gli attributi dai tag laddove questi non sono necessari in quanto comparabili al comportamento di default. Questo consente di risparmiare un buon numero di byte.

Operazione

Ci sono 2 casi dove un attributo può essere rimosso. Il primo è quanto gli attributi sono "single-valued" o "booleani", e dunque il valore specificato diventa superfluo e la sola presenza è sufficiente. In questi casi il filtro non farà altro che rimuovere il valore lasciando solo il nome dell'attributo. Per esempio il seguente tag:

<button name="ok" disabled="disabled">

viene riscritto in:

<button name="ok" disabled>

Il secondo caso è un campo opzionale con un valore di default e dunque se questo viene specificato allora il filtro lo rimuove perché il browser riesce comunque ad ereditarlo dal valore di default.

Un esempio è il seguente:

<input name="email" type="text">

che viene riscritto in:

<input name="email">

Requisiti

Il filtro 'Elide Attributes' deve essere cauto in quanto alcuni elementi con un particolare doctyoe XHTML potrebbero invalidare il codice e dunque il filtro cerca di riconoscere il doctype e agire di conseguenza.

Rischi

Il filtro è a rischio medio in quanto a volte può creare problemi con il CSS in quanto è possibile a volte dichiarare alcune regole basandosi ad esempio sul type come segue: input[type="text"] { ... } Questa regola infatti controlla il match cone <input> che contiene l'attributo type il cui valore è "text." Stesso può avvenire quando ci sono JS che ispezionano il DOM alla ricerca di particolari attributi.


Extend Cache

Configurazione

Il filtro 'Extend Cache' si abilita con

ModPagespeedEnableFilters extend_cache

ed equivale a specificare i tre filtri singoli

ModPagespeedEnableFilters extend_cache_images
ModPagespeedEnableFilters extend_cache_scripts
ModPagespeedEnableFilters extend_cache_css

Descrizione

'Extend Cache' cerca di migliorare il processo di caching senza compromettere la possibilità del webmaster di cambiare le risorse e modificarle a suo piacimento senza generare disservizi all'utente. Il filtro si basa sulla best practice di ottimizzare la cache lato browser.

Operazione

Il filtro 'Extend Cache' non fa altro che riscrivere il riferimento URL nella pagina HTML aggiungendo un hash al nome della risorsa. In questo modo quando il file originale verrà modificato mod_pagespeed cambierà l'hash e il browser dell'utente riscaricherà la risorsa aggiornata. Il filtro può agire anche sulle immagini nei CSS e JS.

Il filtro 'Extend Cache' riscrive anche gli header HTTP per estendere il valore max-age della risorsa cachabile a 31536000 secondi che equivalgono a un anno.

Per fare un esempio esplicativo della coppia HTML tag e header HTTP:

HTML tag : <img src="images/logo.gif">
HTTP header: Cache-Control:public, max-age=300

mod_pagespeed riscriverà nel seguente modo:

HTML tag : <img src="images/logo.gif.pagespeed.ce.xo4He3_gYf.gif">
HTTP header: Cache-Control:public, max-age=31536000

mod_pagespeed usa il time-to-live (TTL) originale, in questo caso 300 secondi, per riesaminare periodicamente la risorsa e vedere se questa è cambiata. Se la risorsa cambia ovviamente l'hash appeso alla risorsa nella pagina HTML viene aggiornato e per questo è senza controindicazioni aggiungere alla risorsa hashata un valore altissimo di 1 anno.

Se il proprietario del sito cambia ad esempio il logo allora mod_pagespeed se ne accorgerà e servirà un URL nuova all'utente, ma se il contenuto non è variato allora l'utente non avrà bisogno di riscaricare la risorsa in quanto cachata nel suo browser.

In questo modo il proprietario del sito ha il pieno controllo delle risorse e delle scelte di caching senza inficiare sulla capacità del browser di cachare. Diminuire il TTL delle risorse influisce dunque solamente sulla quantità di volte che mod_pagespeed controllerà lo stato della risorsa.

Altri filtri operano allo stesso modo impostando la cache a 1 anno e questo filtro forza tutte le altre risorse che non sono già state "hashate".

Limitazioni

L'estensione della cache non funziona sulle risorse che hanno cache-control:private o cache-control:nocache.

Ma può essere sovrascritto usando il flag seguente in pagespeed.conf:

ModPagespeedForceCaching on

Questo flag è però pensato solo per scopi sperimentali e non va usato su macchine di produzione. La seguente porzione di codice è un esempio di come vanno configurati in Apache gli header di cache.

<Directory /var/www/mod_pagespeed_example>
  <FilesMatch "\.(html|htm)$">
    Header unset Etag
    Header set Cache-control "max-age=0, no-cache"
  </FilesMatch>
  <FilesMatch "\.(jpg|jpeg|gif|png|js|css)$">
    Header unset Etag
    Header set Cache-control "public, max-age=600"
  </FilesMatch>
</Directory>

Rischi

Il filtro è considerato a rischio basso. Un possibile rischio è relativo ai JavaScript che controllano il nome della risorsa, che cambiando nome, potrebbe generare risultati inaspettati. Il filtro applicato ai JavaScript come document.getElementsByTagName('script')non viene esteso a livello di cache.


Extend Cache PDFs

Configurazione

Il filtro 'Extend Cache PDFs' si abilita specificando la seguente direttiva nel file pagespeed.conf

ModPagespeedEnableFilters extend_cache_pdfs

Descrizione

'Extend Cache PDFs' è una vesione particolare di Extend Cache che agisce sui PDF. A differenza infatti di 'Extend Cache' questo filtro non si applica solamente alle risorse, ma anche ai link come <a href="example.pdf">.

Operazione

Valgono le stesse regole viste in precedenza.

Limitazioni

Le risorse che non terminano con PDF non vengono prese in esame dal filtro.

Rischi

Stessi rischi del precedente.


Flatten CSS Imports

Configurazione

Il filtro 'Flatten CSS Imports' si abilita specificando la direttiva seguente nel file pagespeed.conf

ModPagespeedEnableFilters flatten_css_imports

Una volta abilitato il filtro possono essere specificati anche dei parametri aggiuntivi che rappresentano la dimensione massima di un file CSS flattened e dunque se si eccede questo numero il file verrà lasciato intatto.

ModPagespeedCssFlattenMaxBytes bytes

L'obiettivo del filtro è quello di ridurre il numero di richieste HTTP rcombinando più CSS in uno solo e evitando di usare l'@import nei CSS.

Descrizione

flatten_css_imports parsa i CSS linkati e inline e li accorpa in uno rimpiazzando le regole @import e agendo in modo ricorsivo. Il filtro funziona anche sui blocchi inline tra <style> e <link>.

Operazione

flatten_css_imports come già detto agisce in modo ricorsivo e in caso di fallimento dell'operazione tutto viene lasciato intatto.

Il CSS viene processato come segue:

  • Il CSS viene parsato; se ci sono errori durante il parsing di regole @import questo passo fallisce.
  • Il CSS viene controllato per ogni regola @charset; se non viene specificato il set di caratteri o questo è diverso da quello in uso il processo fallisce.
  • Tutte le regole @import vengono rimosse e i file specificati vengono scaricati e processati ricorsivamente per l'inclusione nel file flattened; se uno qualsiasi dei file non può essere recuperato per qualsiasi motivo questo step fallisce.
  • Ogni set di regole che segue @import viene appeso.
  • Il CSS finale viene minificato; se il file non può essere minificato questo step fallisce.
  • La dimensione del CSS finale viene controllata rispetto alla dimensione massima specificata per i flattened CSS; se questa è troppo grande allora lo step fallisce.
  • Come passo finale i css tra <style> o <link> sono rimpiazzati nel CSS minificato.
  • Il charset iniziale viene determinato sulla base delle regole HTTP e quindi dalle intestazioni di risposta dell HTML se ci sono oppure dall'attributo charset nell'elemento <link> o <script>, se presenti e in alternativa finale prendendo il default ISO-8859-1.

Requisiti

Deve essere abilitato il filtro Rewrite CSS per permettere a questo di funzionare.

Limitazioni

Solo i riferimenti a CSS nei tag <style> e <link> vengono riscritti mentre gli attributi style negli elementi HTML no. Non tutti i costrutti CSS3 o quelli proprietari vengono riconosciuti e dunque in questi casi l'operazione fallisce.

Rischi

flatten_css_imports è considerato a medio rischio perché compie tutte le operazioni descritte sopra.


Inline @import to Link

Configurazione

Il filtro 'Inline @import to Link' si abilita con

ModPagespeedEnableFilters inline_import_to_link

Descrizione

Il filtro "Inline @import to Link" converte i tag <style> che usano solamente @import nel corrispettivo tag <link>. Questa conversione non porta nessun particolare beneficio, ma è funzionale agli altri filtri che agiscono proprio sul tag <link> come combine_css, rewrite_css, inline_css, and extend_cache filters.

Operazione

Il filtro ispezione il contenuto di tutti i tag <style> e converte il tag se soddisfa le seguenti condizioni:

  • Nei casi in cui il tag <style> non ha l'attributo type o l'attributo type ha il valore "text/css".
  • I contenuti comprendono uno o più dichiarazioni valide di @import e nessun altra dichiarazione.
  • Nessuna delle URL importate è vuota.
  • Il tag <style> tag non ha un href e nemmeno un attributo rel (che lo renderebbe invalido in ogni caso).
  • Se il tag <style> ha un attributo media e la dichiarazione di @import specifica il media dopo l'URL, allora il tipo di media listato deve essere lo stesso. Questi non devono essere nello stesso ordine e i media type non definiti vengono ignorati.
  • Se tutte le condizioni sono soddisfatte, il tag <style> e i suoi contenuti vengono rimpiazzati con un tag <link> per ogni @import
  • Gli attributi dal tag <style> vengono copiati nel tag <link>.
  • Un attributo href con valore dell'URL importata.
  • Un attributo rel con il valore "stylesheet".
  • Se il tag <style> non ha l'attributo media, ma l'@import specifica il media dopo l'URL allora l'attributo media viene estrapolato da quello dopo l'URL.

Per fare un esempio se lo <style> è il seguente:

<style type="text/css" media="screen">@import url(http://www.example.com/style.css);</style>

Allora mod_pagespeed lo convertirà in

<link type="text/css" media="screen" rel="stylesheet" href="http://www.example.com/style.css"/>

Rischio

Rischio minimo.


Inline CSS

Configurazione

Il filtro 'Inline CSS' si abilita come segue

ModPagespeedEnableFilters inline_css

Una volta abilitato è possibile specificarne le impostazioni per definire il limite di byte tale per cui la risorsa può essere messa inline

ModPagespeedCssInlineMaxBytes bytes

Descrizione

Il filtro "Inline CSS" riduce il numero di richieste HTTP fatte dalla pagina mettendo piccole porzioni di CSS direttamente nel file HTML. Questo in certi casi può ridurre il tempo necessario a mostrare il contenuto soprattutto nei browser datati.

Operazione

Quando il filtro 'Inline CSS' è abilitato il contenuto dei piccoli CSS esterni viene inglobato nella pagina HTML e dunque il browser non richiede la risorsa. Per fare un esempio di cosa succede:

<html>
  <head>
    <link rel="stylesheet" href="small.css">
  </head>
  <body>
    <div class="blue yellow big bold">
      Hello, world!
    </div>
  </body>
</html>

Con il file small.css contentente:

.yellow {background-color: yellow;}
.blue {color: blue;}
.big { font-size: 8em; }
.bold { font-weight: bold; }

E mod_pagespeed lo riscriverà come segue:

<html>
  <head>
    <style>
      .yellow {background-color: yellow;}
      .blue {color: blue;}
      .big { font-size: 8em; }
      .bold { font-weight: bold; }
    </style>
    </head>
  <body>
    <div class="blue yellow big bold">
      Hello, world!
    </div>
  </body>
</html>

Questo riduce le richieste del browser eliminado la chiamata a small.css e mettendolo inline. Note Il CSS potrebbe contenere URL relative all'interno del CSS e mettendole inline il filtro le riscriverà in assoluta quando fa l'inlining.

Requisiti

Mettere inline il CSS non è il massimo nel senso che è sempre preferibile tenere esterne le dichiarazioni CSS per aumentare la cachabilità, ma in alcuni rari casi dove il CSS è davvero piccolo può avere senso usare questa tecnica sempre che non abbia senso combinare questo piccolo file con altri. mod_pagespeed può mettere inline solo file serviti dallo stesso dominio che eroga le pagine HTML.

Rischi

Il filtro 'Inline CSS' è a rischio moderato. Come altri filtri l'unico problema può essere dettato dalgli script che analizzano la DOM cercando i tag <link> o <style>.


Inline JavaScript

Configurazione

Il filtro 'Inline JavaScript' si attiva come segue

ModPagespeedEnableFilters inline_javascript

Quando si attiva è possibile settarlo tramite una direttiva per specificare il limite in byte dei JS da mettere inline:

ModPagespeedJsInlineMaxBytes bytes

Descrizione

Il filtro "Inline JavaScript" riduce il numero di richieste HTTP inserendo le piccole porzioni esterne di JS inline nella pagina HTML. Questo specialmente per i browser vecchi può velocizzare il tempo di visualizzazione della pagina.

Operazione

Quando il filtro è abilitato il codice esterno JS viene iniettato nel file HTML e si risparmia la chiamata. Per fare un esempio a partire dal seguente file:

<html>
  <head>
    <script type="text/javascript" src="small.js"></script>
  </head>
  <body>
    <div>
      Hello, world!
    </div>
  </body>
</html>

Con small.js come segue /* contents of a small JavaScript file */ mod_pagespeed lo riscrive in

<html>
  <head>
    <script type="text/javascript">
      /* contenuto del picolo JavaScript */
    </script>
  </head>
  <body>
    <div class="blue yellow big bold">
      Hello, world!
    </div>
  </body>
</html>

E questo elimina la richiesta a small.js piazzando il js inline nel documento HTML.

Requisiti

Vale lo stesso discorso fatto per l'inlining dei CSS , ma per i JS spesso i vantaggi possono essere maggiori in quanto gli script JS inline possono essere spesso delle porzioni di codice asincrono e dunque non influiscono sul rendering della pagina.

Rischi

JavaScript inlining è a rischio moderato sempre per gli stessi motivi già espressi in precedenza.


Inline Preview Images

Configurazione

Il filtro 'Inline Preview Images' si attiva con

ModPagespeedEnableFilters inline_preview_images

Mentre il 'Resize Mobile Images' come segue

ModPagespeedEnableFilters resize_mobile_images

Descrizione

Il filtro 'Inline Preview Images' genera una versione di qualità più bassa dell'immagine che viene inclusa inline nell'HTML. L'utente in questo modo percepisce una maggiore velocità in quanto le immagini sono più piccole, ma non appena il documento viene completato (onload) vengono ricaricate le immagini originali. Il filtro funziona se trova tag <img>. Il filtro 'Resize Mobile Images' funziona allo stesso modo dell'Inline Preview Images, ma viene utilizzato solo per i browser mobile perché riduce la dimensione dell'immagine segnaposto per adeguarsi alle dimensioni del dispositivo. Se Inline Preview Images è attiva e Resize Mobile Images no allora verrà fornita agli utenti mobile la stessa versione desktop. L'uso ottimale è dunque quello combinato con l'aggiunta di insert_image_dimensions per prevenire il reflow al caricamento dell'immagine.

Operazione

Il filtro 'Inline Preview Images' cambia l'attributo src dell'elemento <img> in pagespeed_high_res_src basato su alcuni parametri descritti in seguito. Questo genera delle versioni di bassa qualità delle immagini e rimpiazza il valore di src con queste che poi vengono sostituite dalle originali all'evento onload. Parametri che influiscono sull'ottimizzazione

ModPagespeedMaxInlinedPreviewImagesIndex IndexNumber

Le prime IndexNumber immagini nella pagina vengono rimpiazzate con immagini di più bassa qualità. Mettendo un numero negativo si otterrà il risultato di far riscrivere tutte le immagini. Usando invece lo Zero nessuna immagine verrà riscritta. Il valore di default è 5.

ModPagespeedMinImageSizeLowResolutionBytes MinBytes

MinBytes, un intero positivo, è la dimensione minima in byte di ogni immagine per cui la versione alternativa di qualità più bassa deve essere generata. Se si inserisce 0 oppure un valore negativo nessuna immagine viene rigenerata.

Rischi

Il filtro è a rischio moderato. Il principale rischio è che il file HTML si ingrandisce in quanto vengono embeddate le immagini di bassa qualità e per questo è importante settare correttamente il valore di .ModPagespeedMaxInlinedPreviewImagesIndex in quanto se le immagini sotto la piega vengono messe inline non i ottiene un vantaggio percepibile e la pagina può impiegare di più a caricare a causa dei byte aggiuntivi nell'HTML. Bisogna anche notare che ModPagespeedMaxInlinedPreviewImagesIndex o ModPagespeedMinImageSizeLowResolutionBytes snon vanno usati per disabilitare inlining of preview images (mettendo ad esempio il parametro a 0). Per disabilitarli bisogna disattivare entrambi i filtri inline_preview_images e resize_mobile_images.


Lazyload Images

Configurazione

Il filtro 'Lazyload images' si attiva con ModPagespeedEnableFilters lazyload_images

Descrizione

Il filtro "Lazyload Images" non fa altro che cambiare l'attributo src di un elemento <img> su ogni pagina HTML con pagespeed_lazy_src. Aggiunge poi un handler onload  a questi elementi per determinare se sono nel viewport dell'utente e se è così li carica. Questo filtro aggiunge anche un handler onscroll che carica le immagini che diventano visibili.

Rischi

Questo filtro è a rischio moderato. Il principale rischio è il consumo di CPU lato client che avviene per il calcolo della posizione dell'immagine.


Local Storage Cache

Configurazione

Il filtro 'Local Storage Cache' si abilita specificando nel file pagespeed.conf:

ModPagespeedEnableFilters local_storage_cache

Descrizione

Il filtro salva le risorse inline nel local storage del browser (HTML5) alla prima visualizzazione della pagina e la carica dal local storage alle seguenti richieste invece di richiamarla di nuovo. È in sostanza una sorta di expires per il codice inline. Il beneficio è lo stesso del caching delle risorse lato browser e dunque evita che quella porzione di risorsa venga sempre rielaborata.

Operazione

Il filtro fa le seguenti cose: Aggiunge una funzione JavaScript all'HTML riscritto nella sezione head. Per ogni CSS inline o immagine che il browser non ha ancora nel local storage, questo le mette inlinea e le tagga con un nuovo attributo speciale. Per ogni CSS inline o immagine che il browser ha nel local storage la rimpiazza con uno snippet di codice JavasScript che carica la risorsa dal local storage. Alla fine aggiunge l'handler onload che processa ogni risorsa inline taggata. Il filtro determina quali risorse sono nel local storage ispezionando i cookie del browser che sono stati settati durante l'ultimo step dell'handler onload. Il nome del cookie è _GPSLSC e il suo valore è una lista di hash delle URL salvate nel local storage. I JavaScript inline non vengono salvati nel local storage perché non è possibile avere la certezza che caricandoli dallo storage questi vengano eseguito comportandosi allo stesso modo di quando sono eseguiti inline.

Gli attributi aggiunti alle risorse inline sono:

pagespeed_lsc_expiry: quando la risorsa scade. Se la risorsa viene acceduta dopo che è scaduta non verrà usata e rimossa dal cookie. pagespeed_lsc_hash: un hash dell'URL della risorsa (prima dell'inlining). È usata per rappresentare la risorsa in forma breve e salvarla nel cookie. pagespeed_lsc_url: URL della risorsa. È usata dallo snippet di codice JavaScript per richiedere la risorsa direttamente se l'hash della risorsa è nel cookie, ma non viene trovata nel local storage.

Requisiti

Il filtro CSS inline e JS Inline devono essere abilitati per far si che questo abbia qualche effetto.

Rischi

Il filtro è considerato a rischio alto-moderato in quanto aggiunte un extra carico mettendo ulteriore JavaScript. Considerato che molti browser non lo supportano e che porta beneficio solo alle visite ripetute allo stato attuale è sconsigliato.


Minify JavaScript

Configurazione

Il filtro 'Minify JavaScript' si abilita con

ModPagespeedEnableFilters rewrite_javascript

Descrizione

Questo filtro minifica il codice JavaScript usando un algoritmo simile al Jsmin di Douglas Crockford's. Ad oggi il filtro elimina i commenti e la maggior parte degli spazi bianchi. Il filtro agisce solo sui JavaScript trovati nei blocchi <script>. La minificazione può ridurre in modo notevole la dimensione dei file trasferiti e in questo modo può essere automatizzata.

Operazione

Il filtro 'Minify JavaScript' rimuove i byte in eccesso che vengono solitamente trasferiti perché ovviamente da un punto di vista di leggibilità per il programmatore avere le indentazioni e spaziature aiuta nella produttività, ma costringe il browser a parsare cose non necessarie. Per fare un esempio a partire dal seguente file HTML:

<html>
  <head>
  </head>
  <body>
    <script>
      // Questo commento verrà rimosso
      document.write("Howdy");
      state = 1
    </script>
    <script src="extScript.js" type="text/javascript">
    </script>
    <script src="extScript1.js">
    /* Il contenuto di un blocco script con src non viene alterato */
    document.write("Internal script; state = " + state);
    state = 42
  </script>
  </body>
</html>

Con il seguente codice in extScript.js:

  /* Inserisci lo stato nel documento */
  document.write("External " + state);
  state += 1;  // Poi aggiornalo.

Allora mod_pagespeed lo riscriverà in:

<html>
  <head>
  </head>
  <body>
    <script>document.write("Howdy");state=1</script>
    <script src=".../extScript.js.pagespeed.jm.HASH.js"></script>
    <script src=".../extScript1.js.pagespeed.jm.HASH.js" type="text/javascript">
    /* Il contenuto di un blocco script con src non viene alterato */
    document.write("Internal script; state = " + state);
    state = 42
  </script>
  </body>
</html>

E il file extScript.js.pagespeed.jm.HASH.js riscritto conterrà:

document.write("External "+state);state+=1;

Requisiti

Solo i JavaScript che sono referenziati da tag <script> vengono riscritti. I frammenti di codice che occorrono altrove non vengono alterati.

Rischi

Qualche porzione di codice JavaScript può dipendere dalla formattazione dello script nella pagina. Per esempio se lo script usa dei commenti allora il JS passando per il DOM e estrapolando queste porzioni compie delle azioni, con la minificazione può non funzionare più.


Move CSS Above Scripts

Configurazione

Il filtro 'Move CSS Above Scripts' si attiva con

ModPagespeedEnableFilters move_css_above_scripts

Descrizione

'Move CSS Above Scripts' cerca di evitare che gli script blocchino il caricamento dei CSS.

Operazione

Il filtro 'Move CSS Above Scripts' opera solo sui CSS con tag <link> e <style> che trova dopo il primo tag <script> e sposta questi tag prima del primo <script>. Per fare un esempio a partire dall'HTML seguente:

<html>
  <head>
  </head>
  <body>
    <script src="script.js" type="text/javascript"></script>
    <div class="blue yellow big bold">
      Hello, world!
    </div>
    <style type="text/css">
      .foo { color: red; }
    </style>
    <link rel="stylesheet" type="text/css" href="styles/all_styles.css">
  </body>
</html>

mod_pagespeed lo convertirà in

<html>
  <head>
  </head>
  <body>
    <style type="text/css">
      .foo { color: red; }
    </style>
    <link rel="stylesheet" type="text/css" href="styles/all_styles.css">
    <script src="script.js" type="text/javascript"></script>
    <div class="blue yellow big bold">
      Hello, world!
    </div>
  </body>
</html>

Limitazioni

Questo filtro opera nello scope del "flush window". Nello specifico file HTML molto grandi o dinamicamente generati possono essere “flushati” dal generatore prima di essere completati e dunque in questo caso il filtro non riesce a riordinare le chiamate.

Rischi

Questo filtro è a basso rischio e può causare problemi solo qualora i JS controllino il DOM come nei casi precedenti.


Move CSS to Head

Configurazione

Il filtro 'Move CSS to head' si attiva con

ModPagespeedEnableFilters move_css_to_head

Descrizione

'Move CSS to head' permette di ridurre il numero di volte che il browser deve fare re-flow del documento assicurandosi che tutti i CSS vengano parsati nell'head prima di ogni altro elemeno body.

Operazione

Il filtro 'Move CSS to head' operate solo sui CSS con tag <link> e <style> che trova dopo </head> e li sposta tra <head>...</head>. Per esempio a partire dal seguente HTML:

<html>
  <head>
  </head>
  <body>
    <script src="script.js" type="text/javascript"></script>
    <div class="blue yellow big bold">
      Hello, world!
    </div>
    <style type="text/css">
      .foo { color: red; }
    </style>
    <link rel="stylesheet" type="text/css" href="styles/all_styles.css">
  </body>
</html>

mod_pagespeed lo riscrive in:

<html>
  <head>
    <style type="text/css">
      .foo { color: red; }
    </style>
    <link rel="stylesheet" type="text/css" href="styles/all_styles.css">
  </head>
  <body>
    <script src="script.js" type="text/javascript"></script>
    <div class="blue yellow big bold">
      Hello, world!
    </div>
  </body>
</html>

Limitazioni

Il filtro opera nello scope del "flush window". Nello specifico file HTML molto grandi o dinamicamente generati possono essere “flushati” dal generatore prima di essere completati e dunque in questo caso il filtro non riesce a ricollocare i CSS nell'head.

Rischi

Il filtro è considerato a basso rischio sempre per i problemi relativi ai JS che controllano il DOM.

Configurazione di Downstream Cache (Reverse Proxy)

PageSpeed serve file HTML con Cache-Control: no-cache, max-age=0 in modo che i cambiamenti alle pagine possano essere erogati sempre correttamente. Questo serve ovviamente per far funzionare tutti i filtri come Extend Cache, che si basa proprio sull'aggiornamento dell'hash per capire se la risorsa è cambiata. Con la downstream cache è possibile accelerare l'erogazione delle risorse già riscritte da PageSpeed e questo senza il bisogno di far scadere queste risorse ad un anno, ma ovviamente a causa del no-cache è impossibile cachare l'HTML riscritto.

Proprio per questo vista la diffusione dei reverse proxy (Nginx proxy_cache e Varnish) per rendere le macchine più performanti ora PageSpeed può essere configurato anche per servire in modo corretto le risorse HTML riscritte. Questo si ottiene utilizzando una richiesta di purge al livello di caching e dunque si può comunicare con il layer di reverse proxy per fornire direttamente la risorsa già elaborata senza ributtarla al mittente per l'elaborazione. La seguente immagine estrapolata dalla documentazione ufficiale è molto esplicativa e per le configurazioni specifiche di Nginx o Varnish è possibile consultare la sezione Configuring Downstream Caches.

Downstream caching e mod_pagespeed

Versioni per vari WebServer e Sistemi Operativi

Dato il suo successo il modulo per l'automazione delle performance ideato da Google è stato replicato anche per altri web server e sistemi operativi. Per Linux ovviamente è disponibile sia per Apache che Nginx mentre per quanto riguarda Windows questo è disponibile anche per IIS.

mod_pagespeed per Nginx

La repository per la versione Nginx di PageSpeed è su GitHub all'indirizzo https://github.com/pagespeed/ngx_pagespeed. Il modulo va compilato in fase di installazione di Nginx.

mod_pagespeed per IIS

La versione dedicata a Windows IIS è invece IIS Speed ed è scaricabile da http://www.iispeed.com/ anche se ha un costo di 99$.

mod_pagespeed per Apache

Come già discusso precedentemente la versione per Apache (quella originaria) è scaricabile da https://developers.google.com/speed/pagespeed/module

--Andrea Pernici (discussioni) 15:50, 28 Agosto 2013 (CEST)


  • Questa pagina è stata modificata per l'ultima volta il 2 set 2013 alle 14:08.
  • Questa pagina è stata letta 5 748 volte.