Cos’è la pipeline di asset
Obiettivi
- Comprendere le 4 caratteristiche principali della pipeline di asset.
- Identificare i percorsi delle risorse
- Sapere come i manifesti delle risorse forniscono la concatenazione di CSS e JS.
- Usa linguaggi di pre-elaborazione come SASS o CoffeeScript
- Define Asset Fingerprinting
Outline
Per molto tempo, abbiamo trattato JavaScript e CSS come un ripensamento nello sviluppo di applicazioni web. Tutto il nostro codice di asset – cose come immagini, fogli di stile e JavaScript — è stato conservato in una cartella enorme chiamata public
e servito al di fuori del contesto della nostra applicazione Rails. Come il web si è evoluto, che non aveva più senso.
La pipeline di asset è la risposta di Rails alla gestione di fogli di stile, JavaScript e immagini.
Percorsi delle risorse
Molti file vanno nella creazione di applicazioni web. I file CSS e JavaScript da soli possono essere difficili da organizzare. Quali cartelle creiamo? Quali file vanno dove? La pipeline di asset fornisce una risposta a questo problema. Dobbiamo mantenere le cose molto organizzate nella nostra applicazione, ma, mantenendo file e cartelle separati per ogni concetto o unità di codice, abbiamo 2 problemi.
- Come fa Rails a sapere dove sono le cose? Il file JS del calendario è in
app/assets/javascripts/calendar.js
ovendor/javascripts/calendar.js
? - Non vogliamo servire ogni file separatamente in quanto ciò renderà il caricamento della nostra pagina molto lento. Ha senso per noi mantenere piccoli file separati per leggibilità e organizzazione, ma, per il browser, preferiamo distruggere tutti quei piccoli file insieme e caricare 1 file JS e 1 file CSS. Questo processo è chiamato concatenazione.
Parliamo del nostro primo problema: come fa Rails a sapere dove guardare? La pipeline di asset ha un concetto chiamato Percorsi di asset per la gestione di questo. Proprio come in BASH dove abbiamo una variabile di ambiente PATH che è una combinazione di percorsi di cartelle, il percorso delle risorse è una combinazione di percorsi di cartelle per le rotaie in cui cercare le risorse. Diamo un’occhiata a un esempio di come è configurato il nostro percorso di Asset.
Rails.application.config.assets.paths =>
Se inseriamo una risorsa in una di queste cartelle, possiamo accedervi tramite l’URL ‘/assets’ nella nostra applicazione. Se si dispone di cartelle aggiuntive per le rotaie per la ricerca, è possibile aggiungere le cartelle al percorso delle risorse. Questo viene fatto nel file config/initializers/assets.rb
.
Rails.application.config.assets.paths << "New Path"
Possiamo mettere le risorse ovunque, configurare il nostro percorso delle risorse e accedervi tramite un singolo URL ‘/assets’.
Manifesti e concatenazione
Ora che possiamo mettere i file ovunque, come possiamo farli includere nelle nostre pagine web? La pipeline Asset utilizza un file manifest per indicare a Rails cosa caricare. Questo file manifest è una posizione centrale in cui possiamo elencare tutti i file CSS e JS di cui la nostra applicazione ha bisogno. Questa non è una funzionalità di JS o CSS, ma piuttosto la pipeline di asset. Ecco un esempio di come appare il nostro file manifest JS:
File: app/assets/javascripts / application.js
//= require jquery//= require calendar
Quando si include il file manifest nel layout con javascript_include_tag
, la pipeline asset cercherà tutti i file elencati nel percorso Asset. Si noti come abbiamo bisogno di calendario. Questo file vive in app/assets/javascripts/calendar.js
, tuttavia abbiamo specificato solo il nome e non il percorso completo. La pipeline di asset cercherà tutti i percorsi configurati per un file con il nome che abbiamo fornito.
Ora che abbiamo risolto la questione della reperibilità, parliamo di concatenazione. Come abbiamo discusso in precedenza, non vogliamo caricare i nostri file nel browser uno per uno. È meglio eseguire un download rispetto a un gruppo di piccoli download dal nostro browser. I file manifest che configuriamo in Rails concateneranno automaticamente i file elencati in essi in un unico file in produzione. Questa potrebbe non essere l’opzione migliore quando stiamo sviluppando la nostra applicazione poiché può rendere difficile il debug. Tuttavia, Rails effettivamente servire ogni file separatamente quando siamo in esecuzione in modalità di sviluppo. Non c’è bisogno di fare nulla.
Infine, le direttive pignone che alimentano i nostri manifesti di asset saranno trattate in dettaglio in seguito.
Preprocessing
Essere in grado di combinare file e caricarli da un insieme di posizioni predefinite nella nostra applicazione è un grande vantaggio della pipeline di Asset. Questo è solo l’inizio. Poiché stiamo caricando le risorse tramite Rails, possiamo pre-elaborare i file utilizzando linguaggi popolari come SCSS per scrivere CSS migliori e Coffeescript per JS più puliti. Se si effettua una risorsa denominata tema.CSS.scss, stai dicendo alla pipeline di asset di eseguire il file tramite il preprocessore SCSS prima di servire il tema.css al browser. Il preprocessore SCSS compila il file in CSS. L’unica cosa che dovevamo fare era fornire l’estensione del file corretta, .scss
, al file e la pipeline di asset sa eseguirlo tramite il preprocessore SCSS.
Fingerprinting
L’ultimo vantaggio di cui parleremo è il Fingerprinting, ma prima parliamo del problema che ci aiuta a risolvere. Quando serviamo i file al browser, è probabile che vengano memorizzati nella cache per evitare di scaricarli di nuovo in futuro. Che cosa è caching si potrebbe chiedere?
Memorizzare nella cache qualcosa significa mantenere una copia di un’operazione che richiede tempo localmente in modo da non dover ripetere nuovamente l’operazione costosa se gli input e gli output saranno esattamente gli stessi. Le cache sono solitamente negozi di valori chiave, in cui il valore è la risposta all’operazione costosa e la chiave è qualcosa che è unico per quell’elemento. Se si richiede una pagina dal server e quindi si richiede nuovamente la stessa pagina dal server, il modo più rapido per ottenere tale richiesta è mantenere effettivamente una copia di ciò che si è ottenuto l’ultima volta localmente. I browser memorizzano nella cache molte delle risposte che ricevono alle richieste che hanno effettuato utilizzando le intestazioni che vengono inviate con la risposta. Le intestazioni indicano al browser per quanto tempo la pagina rimane “fresca” prima che “scada”.’Una volta che la pagina è scaduta, il browser farà una nuova richiesta per la pagina per aggiornare la sua cache. Diciamo che la richiesta più veloce è la richiesta che non è stata fatta. Si dice anche spesso che l’invalidazione della cache è uno dei due problemi difficili nell’informatica, quindi pensa attentamente quando inizi a memorizzare nella cache le cose! Caching consente di risparmiare larghezza di banda per noi e fornisce un aumento di velocità per l’utente. Questo è grande fino a quando si modifica il file e si desidera che tutti gli utenti per ottenere quello nuovo al posto della vecchia versione che hanno memorizzato nella cache del browser. Ma come facciamo a far sapere al browser che abbiamo modificato il file? Se la nuova versione ha lo stesso nome della vecchia versione, il browser continuerà a utilizzare il vecchio file dalla sua cache. Abbiamo bisogno di un modo per cambiare il nome del file quando i contenuti cambiano in modo che i browser non continuino a servire il vecchio file.
From the Rails Guides Primer
“Fingerprinting è una tecnica che rende il nome di un nome di file dipendente dal contenuto del file. Quando il contenuto del file cambia, viene modificato anche il nome del file. Per i contenuti statici o modificati raramente, questo fornisce un modo semplice per stabilire se due versioni di un file sono identiche, anche su server diversi o date di distribuzione.
Quando un nome di file è univoco e basato sul suo contenuto, le intestazioni HTTP possono essere impostate per incoraggiare le cache ovunque (sia nelle CDN, negli ISP, nelle apparecchiature di rete o nei browser Web) a mantenere la propria copia del contenuto. Quando il contenuto viene aggiornato, l’impronta digitale cambierà. Ciò farà sì che i client remoti richiedano una nuova copia del contenuto. Questo è noto come cache busting.
La tecnica che sprockets utilizza per il fingerprinting consiste nell’aggiungere un hash del contenuto alla fine del nome del file. Ad esempio, prendi un file CSS denominato global.css
. Pignoni aggiungerà l’hash 908e25f4bf641868d8683022a5b62f54
alla fine del nome del file in questo modo:
global-908e25f4bf641868d8683022a5b62f54.css
Se si utilizza una versione precedente di Rails (Rails 2.x), la strategia era quella di aggiungere una stringa di query basata sulla data a ogni risorsa collegata a un helper integrato. Questo sembrava così:
global.css?1309495796
La strategia della stringa di query presenta diversi svantaggi:
- Non tutte le cache memorizzeranno in modo affidabile il contenuto in cui il nome del file differisce solo dai parametri della query.
- Steve Souders raccomanda ” evitare una querystring per le risorse memorizzabili nella cache.”Il 5-20% delle tue richieste non verrà memorizzato nella cache. Le stringhe di query in particolare non funzionano affatto con alcuni CDN per l’invalidazione della cache.
- Il nome del file può cambiare tra i nodi in ambienti multi-server.
- La stringa di query predefinita in Rails 2.x si basa sul tempo di modifica dei file. Quando le risorse vengono distribuite in un cluster, non vi è alcuna garanzia che i timestamp saranno gli stessi, con conseguente utilizzo di valori diversi a seconda del server che gestisce la richiesta.
- Troppa invalidazione della cache.
- Quando le risorse statiche vengono distribuite con ogni nuova versione di codice, l’mtime (ora dell’ultima modifica) di tutti questi file cambia, costringendo tutti i client remoti a recuperarli di nuovo, anche se il contenuto di tali risorse non è cambiato.
Fingerprinting risolve tutti questi problemi assicurando che i nomi dei file siano coerenti in base al loro contenuto.
Il fingerprinting è abilitato per impostazione predefinita per la produzione e disabilitato per tutti gli altri ambienti. È possibile abilitare o disabilitare nella configurazione tramite l’opzione config.assets.digest
.”
Conclusione
La pipeline delle risorse è decisamente più complessa quindi serve solo risorse da una cartella pubblica e può essere difficile eseguire il debug. Imparare a usarlo pagherà nel lungo periodo salvandoci tempo e mal di testa. Pensa a tutti i problemi che risolve per noi.
- Percorsi degli asset
- Manifesti e concatenazione
- Pre-elaborazione
- Fingerprinting
Infine, controlla sicuramente il keynote in cui DHH introduce la pipeline degli asset.