Geolocalizzazione dei contenuti in Ruby on Rails

Nella realizzazione di questo sito, ci siamo prefissati l’obiettivo di realizzare un blog bilingue, onde poterci affacciare anche all’utenza extra-italiana.
Rails ha integrata una interfaccia per la localizzazione dei contenuti in grado di gestire le traduzioni attraverso dei file in formato yml; nel nostro caso, per rendere ancora
più semplice la gestione delle traduzioni dei contenuti semistatici, abbiamo deciso di utilizzare l’ottimo localeapp.
Oltre alla traduzione dei contenuti semistatici, gestiamo anche la traduzione dei contenuti dinamici (gli articoli del blog) utilizzando due diversi campi nel database.
Attraverso questa infrastruttura, un visitatore può decidere se vedere il sito localizzato in italiano oppure in inglese semplicemente
accedendo all’indirizzo corretto oppure scegliendolo dal menu popup in alto a sinistra (il simbolo della bandiera).
Tutto ciò premesso, quale lingua vede il visitatore che accede all’indirizzo standard www.azns.it?
Inizialmente abbiamo optato per una impostazione statica del “default locale” in italiano, dopodichè abbiamo deciso di intraprendere una strada diversa: proporre i contenuti del
sito localizzati in italiano, solo per i visitatori provenienti dalla rete italiana.
Ecco come abbiamo fatto:

Installazione delle estensioni necessarie

Per gestire la geolocalizzazione, abbiamo usato la gemma GeoIP
Abbiamo installato la gemma aggiungendo la seguente riga al file gemfile

gem 'geoip'

Quindi abbiamo scaricato i database degli indirizzi IP da maxmind e lo abbiamo scompattato
all’interno della directory /public

Codice per la geolocalizzazione

Tutto il codice necessario per la localizzazione si trova all’interno del file application-controller.rb

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class ApplicationController < ActionController::Base
  protect_from_forgery

  before_filter :set_locale

  def set_locale
    I18n.locale = extract_locale_from_subdomain || geolocalization #I18n.default_locale
  end

  # Get locale code from request subdomain (like http://it.application.local:3000)
  # You have to put something like:
  #   127.0.0.1 gr.application.local
  # in your /etc/hosts file to try this out locally
  def extract_locale_from_subdomain
    parsed_locale = request.subdomains.first
    unless parsed_locale.nil?
      I18n.available_locales.include?(parsed_locale.to_sym) ? parsed_locale : nil
    else
      nil
    end
  end

  def geolocalization
    c = GeoIP.new('public/GeoIP.dat').country(request.remote_ip)
    if c.country_code3=='ITA'
      'it'
    else
      'en'
    end
  end
end

Commentiamo insieme il codice qui sopra
Ad ogni visualizzazione, viene lanciata la funzione set_locale.

Questa funzione setta la variabile di sistema I18n.locale che è quella che viene utilizzata per capire qual è la lingua di visualizzazione del sito: lo fa lanciando la funzione
extract_locale_from_subdomain che ritorna “it” oppure “en” se l’utente ha scelto una particolare visualizzazione, oppure nil se l’utente ha scelto una lingua non supportata
oppure se sta accendendo alla URL standard “www” (oppure al dominio di secondo livello).

Nel caso in cui questa seconda funzione restituisca nil, normalmente si usa ||I18n.default_locale per settare il locale al valore standard dichiarato nel file di
configurazione dell’applicazione Rails; noi invece lanciamo una terza funzione, geolocalization.

Questa funzione estrae tutti i dati relativi allo stato di appartenenza dell’IP del visitatore con c = GeoIP.new('public/GeoIP.dat').country(request.remote_ip) e restituisce
“it” se si trova in Italia, “en” se si trova all’estero.

La funzione, al momento, è compatibile solo con indirizzi IPv4, in quanto il database pubblico di IPv6 è attualmente incompatibile con la gemma geoip. Pertanto, se state
navigando attraverso un indirizzo IPv6, vedrete questo sito in inglese.

L’architettura di Instagram

Ecco il primo vero articolo del nuovo blog, online in maniera definitiva da oggi pomeriggio!

In realtà sono stato sollecitato da un amico a valutare un articolo interessante da lui scovato riguardante la descrizione dell’infrastruttura utilizzata da instagram. Dopo averlo letto con attenzione, gli ho riposto via email commentandolo punto per punto, alchè mi ha proposto di pubblicare i miei commenti sul mio blog.Lo faccio volentieri, anonimizzando le parti sensibili che riguardano il progetto che sta realizzando.

Lessons learned:
  1. Keep it very simple
  2. Don’t re-invent the wheel
  3. Go with proven and solid technologies when you can.

Nessun commento, corretto.

3 Engineers.

Nel senso che non ne servono 3000 come per Facebook: ne bastano 3 per far girare tutto instagram… Io guardo le cose dal basso e la mia opinione è che 3 è una quantità corretta, 2 resta comunque un numero adeguato per molti progetti, 1 solo amministratore di sistema è troppo poco. In tutte le situazioni in cui lavoro cerco sempre di coinvolgere una persona interna all’azienda in modo che ci sia almeno “un mio backup” in caso di forza maggiore.

Amazon shop. They use many of Amazon’s services. With only 3 engineers so don’t have the time to look at self hosting.

Qui sono dubbioso, ma solo per motivi puramente economici. In USA la tecnologia cloud è molto competitiva perchè hanno costi per la banda Internet molto bassi mentre i costi per il consumo energetico sono identici a quelli Europei, quindi in proporzione molto elevati; in Europa non abbiamo la stessa qualità di banda e i costi per questo componente sono più elevati, quindi la proporzione tra banda e costo dell’energia elettrica è molto inferiore. Questo porta ad avere una maggiore economicità per le offerte cloud americane rispetto alle corrispondenti offerte di housing; al contrario, in Europa, le offerte di housing sono più allettanti rispetto ad un cloud anche se la qualità di banda non è paragonabile, per cui questa è una regola certamente valida per le startup che hanno base/utenze in USA, mentre per noi deve essere valutata attentamente.
Resta il fatto che tutte le ex-startup americane, Twitter e Facebook per citare un paio di nomi, una volta giunte ad una dimensione importante, hanno deciso di abbandonare Amazon e migrare verso ambienti self-hosting, segno che l’economicità del cloud si ha solo sotto una soglia di utilizzo ben determinata.

100+ EC2 instances total for various purposes.

Giusto: meglio tante piccoli istanze che due grossi serveroni con tutto dentro. La separazione delle istanze è il metodo migliore per separare gli ambienti ed essere sicuri che tutti convivano felicemente (diciamolo anche agli Israeliani e ai Palestinesi…)

Ubuntu Linux 11.04 (“Natty Narwhal”). Solid, other Ubuntu versions froze on them.

Nessuna guerra di religione sulle distribuzioni: ciascuna ha le sue caratteristiche e bisogna conoscerle per scegliere quella più adatta:
– le RedHat based (tra cui CentOS e Fedora), sono “vecchie per scelta”: si sceglie una versione master (ad es. CentOS 6 in questo momento) e si saprà che in tutte le release successive (6.1, 6.2, 6.3…) si avrà sempre la stessa versione di ogni pacchetto (ad es. PHP 5.3.3) e saranno applicate solo delle patch create da RedHat per correggere eventuali errori. Quindi si ha una grande solidità in fase di gestione del sistema (aggiornamenti ecc.), ma se si vuole “qualcosa di più” si è con le mani legate. Anche un aggiornamento di master version (passare dalla CentOS 5 alla 6) è praticamente impossibile.
– le Debian based (tra cui la citata Ubuntu) sono solide, hanno un gestore dei pacchetti maglifico (aptitude), ma bisogna prestare moltissima attenzione in fase di aggiornamento perchè sono legate solo alla versione del pacchetto e gli aggiornamenti di sistema seguono quelli del pacchetto senza un sistema di patch interno. Ad esempio su Debian 6 ora si ha PHP 5.3.4, ma con il passare del tempo sarà aggiornato alla versione 5.3.5 poi 5.3.6 e così via. Non si passerà mai alla versione 5.4 a meno di un cambio di versione di Debian (dalla 6 alla futura 7) cosa che, al contrario delle RedHat based, è possibile fare. Normalmente, per esperienza, le Debian based hanno anche meno overhead rispetto alle RedHat based. Personalmente, sui miei server, uso Debian wheezing che è la versione “testing” di Debian su cui si basa Ubuntu: Debian è magari un po’ più ruvida rispetto ad Ubuntu ma qui è solo una questione di gusti personali: i pacchetti sono identici.
– le rolling release (Gentoo, Arch, Debian sid) sono distribuzioni senza versione perchè seguono costantemente gli aggiornamenti di un pacchetto. Quindi è possibile che un aggiornamento di sistema porti PHP dalla versione 5.3 alla 5.4 ma anche alla 6.0! Bello per chi vuole avere sempre l’ultima versione ma poco adatte per i server: personalmente sul mio PC uso Arch Linux nella versione testing, ben conscio che se dopo un aggiornamento non mi parte più il PC me la sono cercata (ma non è mai successo).

Amazon’s Elastic Load Balancer routes requests and 3 nginx instances sit behind the ELB.

Ritengo utile provare nginx al posto di apache come web server per i contenuti statici: io mi trovo benissimo! Nel caso di una realtà che non utilizza i servizi Amazon, non si potrà avere ELB di fronte alle istanze di Nginx, anche perchè nella maggior parte dei casi dubito fortemente che saranno necessarie più istanze di nginx; in qualsiasi caso nulla vieterà in futuro di usare una istanza dedicata di Nginx o di HAproxy per avere le stesse funzionalità di ELB (ELB è basato su HAproxy) di fronte ad X istanze di Nginx.

SSL terminates at the ELB, which lessens the CPU load on nginx.

Giusto: le istanze di ELB sono create su server con schede hardware dedicate alla gestione del criptaggio SSL, quindi delegare ad ELB la gestione del protocollo HTTPs scarica notevolmente i server che stanno alla base e permette di ottenere prestazioni più elevate.

Amazon’s Route53 for the DNS.

Non è possibile migrare indirizzi IP tra diverse zone di Amazon, per cui è come se fossero fornitori separati (ma se Amazon non paga la bolletta della corrente, va giù tutto e fine del film) ed è necessario un sistema in grado di gestire l’alta affidabilità tramite DNS.

25+ Django application servers on High-CPU Extra-Large machines.

Loro usano Phyton con Framework Django, in molti casi italiani si usa PHP. PHP, ad onor del vero, è un linguaggio di scripting molto semplice però non ha prestazioni elevatissime; personalmente Python mi fa venire l’orticaria, ma è una questione di gusti perchè in realtà è un linguaggio molto diffuso: ad esempio tutti gli script di RedHat sono realizzati in Python. Personalmente qualche anno fa mi sono avvicinato al mondo Ruby che è davvero affascinate: prestazioni paragonabili a Python, ma un linguaggio estremamente orientato agli oggetti (ad esempio un semplice ciclo “for i=1 to 20” si traduce in “(1..20).each do |i|” dove (1..20) è un oggetto ed each è un metodo dell’oggetto!) e un framework (Rails) che impone la metodologia MVC (Model View Controller) in modo da avere un codice ordinato e mantenibile facilmente in un team di persone.
Sinceramente, se ora dovessi decidere quale linguaggio studiare per sostituire PHP, mi metterei a lavorare su Scala con il framework Lift: è un linguaggio derivato da Java, quindi il codice viene compilato ed eseguito direttamente e non compilato “in diretta” dal WSGI server: tutto ciò a beneficio delle prestazioni. Inoltre, cosa che mi attira, oltre alla programmazione procedurale e a quella ad oggetti, supporta la programmazione funzionale che permette di sfruttare in maniera pesante il multithreading delle CPU più moderne parallelizzando i processi.

Traffic is CPU-bound rather than memory-bound, so High-CPU Extra-Large machines are a good balance of memory and CPU.

Questa è una caratteristica del progetto Instagram: i filtri per le foto fanno la maggior parte del lavoro e stressano più la CPU che la RAM. Resta inteso che ogni processo ha le sue caratteristiche e quindi questi aspetti devono essere valutati caso per caso.

Gunicorn as their WSGI server. Apache harder to configure and more CPU intensive.

Come per tutti i web server, Apache server può servire nativamente solo i contenuti statici, però Apache ha la caratteristica “unica” di poter usare un suo sistema di moduli interni per lanciare gli script esterni (ad es. mod_php, mod_python e mod_ruby per altri linguaggi); in alternativa può lavorare come tutti gli gli altri web server (ad es. il già citato Nginx) reindirizzando ad un socket esterno ciò che non riesce a servire direttamente. Qui entra in gioco il server WSGI (che è gunicorn per Instagram), cioè quel pezzo di software che fa da “tramite” tra il web server ed il codice Python. Nel caso di ruby, il server WSGI più veloce è Unicorn, mentre per PHP possiamo decidere se usare ilo “vecchio” FastCGI oppure SuPHP oppure, infine, PHP-FPM che è un componente interno di PHP (dalla versione 5.3 in poi) e quindi è quello qualitativamente migliore e più efficiente.

Fabric is used to execute commands in parallel on all machines. A deploy takes only seconds.

Fabric è un sistema per eseguire processi in background per Python usando una connessione SSH; ha la possibilità di lanciare lo stesso comando in contemporanea su più server permettendo il parallel processing. Per Ruby esistono soluzioni analoghe, ma mi piace citare EventMachine in cui non si usa SSH per inviare un comando ad un server remoto, ma si ragiona ad “eventi”. Per PHP sinceramente non è necessario un modulo come fabric: si può arrivare allo stesso risultato con il comado exec “ssh server -c comando”, però si può usare RabbitMQ per avere un sistema di code e comunicazione tra server analogo a quello di EventMachine.

PostgreSQL (users, photo metadata, tags, etc) runs on 12 Quadruple Extra-Large memory instances.

Ok loro usano PostgreSQL per gestire i dati, non MySQL. Loro usano 12 server in replica: le basi dati relazionali si dimostrano sempre uno dei componenti più complessi e pesanti di un sistema.

Twelve PostgreSQL replicas run in a different availability zone.

Anche con MySQL è possibile portare repliche al di fuori del datacenter. Certo che il numero di 12 coincide in entrambi i punti precedenti, quindi immagino che stiamo parlando degli stessi server e quindi che Instagram abbia un totale di 12 server ciascuno istanziato in una istanza 4xExtra-Large sparsi di differenti availability zone.

PostgreSQL instances run in a master-replica setup using Streaming Replication. EBS is used for snapshotting, to take frequent backups.

Sia PostgreSQL sia MySQL possono avere repliche in modalità master-slave, però in entrambi i casi non sono autonomi a gestire eventuali guasti. Ci vuole un software esterno che controlli la funzionalità dei server, che escluda eventuali nodi morti o fuori sincronia e che promuova a master un nodo slave in caso di morte del master. Nel caso di Instagram, hanno usato repmgr per gestire questa cosa, nel caso di MySQL si può usare mysql-mmm.

EBS is deployed in a software RAID configuration. Uses mdadm to get decent IO.

Immagino, poveretti… EBS non è proprio un mostro di velocità I/O per cui usano due dischi in mirror software su ciascuna VM per parallelizzare l’output locale dei dati.

All of their working set is stored memory. EBS doesn’t support enough disk seeks per second.

Ecco la riprova: cache di tutto il database in RAM usando il sistema di cache e buffering interno a Linux perchè EBS non raggiunge velocità di I/O adeguate.

Vmtouch (portable file system cache diagnostics) is used to manage what data is in memory, especially when failing over from one machine to another, where there is no active memory profile already.

Vmtouch è un tool per gestire la cache di linux usata al punto precedente.

XFS as the file system. Used to get consistent snapshots by freezing and unfreezing the RAID arrays when snapshotting.

Aia, qui non mi trovo d’accordo. XFS è il Filesystem più veloce che abbia mai provato, ma ho sperimentato anche blocchi, perdite di dati, incoerenze… No: se parto dal presupposto che uso la cache per tutto, mi “paro il c…” con un filesystem più stabile anche se un po’ più lento come ext4.

Pgbouncer is used pool connections to PostgreSQL.

E per MySQL esiste mysql-proxy.

Several terabytes of photos are stored on Amazon S3.

Ok, le foto non stanno su filesystem locale ma su S3. Penso che alla fine, concettualmente, sia il classico esempio in cui è corretto non reinventare la ruota. Non gestire direttamente lo storage dei file ma tenerli “sul cloud” semplifica notevolmente la vita.

Amazon CloudFront as the CDN.

Certo, questa è l’interfaccia tra S3 e il web.

Redis powers their main feed, activity feed, sessions system, and other services.
Redis runs on several Quadruple Extra-Large Memory instances. Occasionally shard across instances.
Redis runs in a master-replica setup. Replicas constantly save to disk. EBS snapshots backup the DB dumps. Dumping on the DB on the master was too taxing.

Loro usano Redis che è uno storage “noSQL” per i contenuti che cambiano velocemente, in quanto la struttura dati di Postgres non riuscirebbe a stargli dietro. Questa è un’ulteriore testimonianza che tutto non può fare tutto e intestardirsi con una base dati SQL per contenuti che cambiano velocemente (ma anche il contrario come mettersi a creare un gestionale su una base dati Redis o MongoDB solo perchè va di moda) non è una scelta corretta.

Apache Solr powers the geo-search API. Like the simple JSON interface.

Solr è un motore di ricerca interno, probabilmente lo integrano con Apache Hadoop in modo che il secondo acquisisca i dati e crei gli indici che utilizza Solr: i due prodotti sono complementari e spesso sono usati in combinazione.

6 memcached instances for caching. Connect using pylibmc & libmemcached. Amazon Elastic Cache service isn’t any cheaper.

memcached è un sistema di cache condiviso tra più server; è compatibile con tutti i linguaggi di programmazione, anche PHP. Loro dicono che AEC non è economico, a mio avviso nemmeno EBS ed EC2 lo sono…

Gearman is used to: asynchronously share photos to Twitter, Facebook, etc; notifying real-time subscribers of a new photo posted; feed fan-out.

Francamente non capisco perchè usino gearman che è un doppione di fabric, a maggior ragione se hanno pure un sistema Hadoop alla base di Solr (ma questa è solo una mia congettura). Sicuramente hanno reputato che è preferibile isolare ciascuna funzionalità in diversi gruppi di istanze e quindi, a quel punto, tanto vale utilizzare il sistema che più si avvicina a risolvere ciascuna specifica funzione.

200 Python workers consume tasks off the Gearman task queue.

Beve, però questo Gearman!

Pyapns (Apple Push Notification Service) handles over a billion push notifications. Rock solid.

Per comunicare direttamente con i client Apple

Munin to graph metrics across the system and alert on problems. Write many custom plugins using Python-Munin to graph, signups per minute, photos posted per second, etc.

Munin è un tool di monitoraggio e generazione di grafici come cacti o nagios (che preferisco)

Pingdom for external monitoring of the service.

Giusto, lo uso anch’io: è inutile controllare che dentro alla rete funzioni tutto se poi cade il gateway che ti collega ad Internet 🙂

PagerDuty for handling notifications and incidents.

Questo è un servizio di alert che si integra con Pingdom, ma anche con munin e nagios: se si rompe qualcosa, oltre all’email può arrivare un SMS o una telefonata. Francamente ce ne sono molti, ma questo sembra davvero facile da integrare per cui lo valuterò.

Sentry for Python error reporting.

Anche questo è un servizio che come Pingdom uso anch’io ($9 mese) e permette di gestire gli errori sul sito: quando ad un utente arriva un errore di qualsiasi tipo, questo sistema raccoglie tutti i dati per cui il programmatore ha una chiara idea di eventuali bug.

Beta del nuovo sito web online

All’indirizzo www2.azns.it troverete la versione beta del nuovo blog realizzato in Ruby on Rails destinato ad ospitare i nuovi articoli. E’ ancora in fase di sviluppo e sarà implementato con ulteriori nuove funzionalità: si accettano molto volentieri commenti e suggerimenti per migliorarlo!

Blog in WordPress: cambiamo?

Sia ben chiaro, è ormai da quasi tre anni che utilizzo Wordpress per gestire il mio blog e non posso dire che non faccia il suo dovere.
Ultimamente, però, mi sto sempre più distaccando dal mondo PHP: sto esplorando linuguaggi di programmazione come Ruby e Scala con i relativi framework Rails e Lift… ogni volta che apro Wordpress e trovo quei 2-300 commenti di spam (bloccati) e quei 4-5 plugin da aggiornare che poi provocano sempre qualche rogna, mi sento come il famoso calzolaio che ha le scarpe rotte.
Ieri sera su Facebook un mio amico e collega, ha reso pubblico il suo pensiero negativo sulla piattaforma Wordpress, motivandolo con questioni di qualità del codice: francamente non mi sono mai messo a guardare il codice PHP di Wordpress, però visto che conosco la persona e la qualità del codice che scrive, non posso che credergli ciecamente.
A questo punto ho fatto qualche ricerca su piattaforme di blogging alternative: ho analizzato le mie esigenze (anzi quelle del mio blog) e, soprattutto, quello che Wordpress mette a disposizione che a me non interessa assolutamente.
Ad esempio, Wordpress è multiutente mentre sul mio blog scrivo solo io, uso un plugin (WPTouch) per rendere il blog fruibile da cellulari, mentre con un CSS responsive si avrebbe un risultato migliore, non uso mai l’editor WYSIWYG ma scrivo i miei articoli in HTML… insomma mi sono convinto che esistano delle alternative più snelle rispetto al pachiderma Wordpress che si adatterebbero meglio alle mie esigenze.
Sono andato alla ricerca di alternative: la maggior parte sono offerte come servizio (vedi blogger), altre sono dei CMS veri e propri (Drupal, Joomla, ecc.)… quello che cercavo io inizialmente è un sistema di weblog scritto in un linguaggio diverso da PHP (non perchè mi faccia schifo, ma perchè così avrei la possibilità di aumentare le esperienze con altri linguaggi) e che non fosse Python per il quale ammetto l’idiosincrasia.
L’ideale per me sarebbe stato un sistema scritto in Ruby on Rails, framework con il quale sto lavorando in questo periodo, e che si potesse adattare ad una base dati non relazionale come MongoDB per una questione di velocità in ambienti cloud.
Purtroppo non ho trovato nulla di già pronto, però ho trovato parecchi tutorial su come usare Rails per creare un blog e, in effetti, mi sono reso conto che la base dati alla base di un Blog è davvero molto semplice e non richiede obbligatoriamente le funzionalità relazionali avanziate dei DB Relazionali (ad es. union e join).
Nella ricerca, però, mi sono imbattuto in un paio di progetti relaizzati in ruby davvero alternativi: octopress e nanoc. La differenza tra questi sistemi e “il resto del mondo” è che si tratta di generatori di blog statici. In pratica, si scrive il codice del post, lo si da in pasto al preprocessore che genera dei contenuti statici html e lo si carica sul server. E’ un po’ più macchinoso da utilizzare, però non si ha alcuna base dati alle spalle del blog, a beneficio della velocità per il visitatore.
A questo punto mi sono levato lo sfizio di aprire uno spazio web sui miei server e caricare un miniblog di un post realizzato con Octopress; quindi ho fatto alcune prove comparative tra la home page del mio blog in Wordpress, la home page del blog in Octopress e la home page di un work in progress realizzato in Rails con base dati MongoDB.
Ecco i risultati che condivido con tutti voi.

Google Page Speed:
Wordpress: 83/100
Errori gravi: abilitare la compressione (c’ho provato in tutti i modi con NGINX e W3 Total Cache, ma ogni tanto il browser non riesce a visualizzare la pagina per cui ho disabilitato il plugin) e utilizzo di URL non coerenti (alcuni CSS vengono presi da altri siti)
Errori medi: sfruttare al cache del browser (causa mancanza di W3 TC), combinare le immagini in sprite css, rimanda l’analisi del codice JS e riduci al minimo i reindirizzamenti

Octopress: 91/100
Nessun errore grave o medio

Rail con CSS Twitter Bootstrap: 97/100
Nessun errore grave o medio

Test con Pingdom da Amsterdam
Wordpress: 3,46 Sec – 77% perf. grade
Octopress: 322 ms – 75% perf. grade
Rails con CSS Twitter Bootstrap: 388 ms – 87% perf. grade

In tutti i casi, come frontend, abbiamo nginx (con apache il tempo di download del sito in wordpress mi raddoppia); nel caso di Wordpress il php è gestito con PHP-FPM, nel caso del sito in Rails abbiamo Unicorn (nel sito realizzato con Octopress non c’è nulla in quanto sono pagine statiche).
Il confronto tra i siti Rails e Octopress vs Wordpress è impietoso ma veritiero in quanto in entrambi i casi si tratta di siti ospitati sugli stessi server, con la stessa banda e completi di CSS, javascript ecc. Solo il peso non è analogo, a causa di alcuni contenuti statici presenti sul sito wordpress: abbiamo un peso di circa 800 KB per Wordpress e di circa 350 per gli altri due, ma c’è da dire che un peso doppio non può equivalere ad un tempo di download 10 volte maggiore. Immagino che un “Wordpress Guru” sia in grado di migliorare le performance facendo funzionare la compressione e lavorando sul layout, però difficilmente riuscirà ad abbassare il tempo di download ai livelli di Rails anche se il peso della pagina fosse identico.
Il confronto tra il sito statico generato da Octopress e il sito dinamico in Rails è meno semplice da valutare: i tempi di risposta sono equivalenti e il peso è simile, però sul sito in Octopress troviamo il link ad alcuni CSS esterni che non incidono sul valore di Google Pagespeed ma, al contrario, incidono sul Performance Grade di Pingdom.

Sinceramente, fare un “passo indietro” ed avere una struttura totalmente statica, ha dei vantaggi non trascurabili in termini di portabilità, velocità di download, scalabilità (per quanto possa servire al mio blog) e semplicità di gestione lato server, però bisogna vedere se all’atto pratico scrivere i post in linguaggio Jekyll, lanciare il parser e l’upload sul server sia funzionale come l’utilizzo dell’editor (non WYSIWYG) di Wordpress.
D’altro canto, un weblog scritto da zero con Rails o Lift sarebbe certamente più d’immagine e probabilmente sarebbe “meno base”: difatti, ad esempio, avrei la possibilità di continuare a gestire direttamente i commenti senza affidarmi a servizi esterni come disquss, oppure potrei scrivere il codice per l’autopost sui social network, anche se bene o male quasi tutti hanno la possibilità di essere “agganciati” all’rss feed.

In sostanza, alla fine della prova, di sicuro ha ragione Luigi che ha reso palese una mia idea mai collaudata sul campo. Sicuramente nei prossimi mesi il sito Wordpress sarà migrato su qualcosa d’altro, anche se non so ancora se varrà la pena realizzare una struttura dinamica da zero in Rails/MongoDB oppure se mi affiderò ai preprocessore di Octopost o nanoc.