Risorse Web suggerimenti per un'organizzazione e prestazioni migliori

Ricordi quando dovevamo dedicare molto tempo all'ottimizzazione delle risorse del nostro progetto (immagini, CSS, ecc ...)? Bene oggi, gli utenti hanno una connessione Internet molto più veloce e sembra che possiamo permetterci di usare immagini più grandi o file flash più grandi con un sacco di video e immagini all'interno. Tuttavia, con l'aumento dello sviluppo mobile, siamo di nuovo nella stessa situazione. È estremamente importante creare siti ottimizzati, in modo da avere applicazioni più veloci, che scaricano meno contenuti e rispondono immediatamente.


immagini

Servire la dimensione corretta

Spesso utilizziamo le stesse immagini per diverse parti dei nostri siti web. Ad esempio, in un negozio online, tutti i prodotti hanno una visione d'insieme. Diciamo che abbiamo tre pagine in cui dobbiamo mostrare quelle immagini: una pagina per elencare i prodotti, un'altra per i dettagli del prodotto e una terza pagina che mostra solo l'immagine nella sua dimensione originale.

Quindi, abbiamo bisogno di tre diverse dimensioni di immagine e se usiamo lo stesso file per tutte e tre le diverse posizioni, il browser scaricherà l'immagine a dimensione intera anche per la pagina di elenco, dove in realtà potremmo aver bisogno solo di un'immagine 200x200. Se il file originale è di circa 1 MB e abbiamo dieci prodotti per pagina, l'utente scaricherà 10 MB. Questa non è una buona idea. Se puoi, prova a generare immagini diverse per le diverse parti del tuo sito, questo salverà molti KB per i tuoi utenti. È una buona idea avere in mente l'attuale risoluzione dello schermo. Ad esempio, se qualcuno apre il tuo sito sul proprio iPhone, non è necessario servire l'immagine dell'intestazione gigante, che normalmente usi. Utilizzando le query multimediali CSS sei in grado di inviare un'immagine con una dimensione più piccola:

@media solo schermo e (min-device-width: 320px) e (max-device-width: 480px) .header background-image: url (... /images/background_400x200.jpg); 

Compressione

L'invio di un'immagine con le dimensioni appropriate non è sempre sufficiente. Alcuni formati di file possono essere compressi molto senza perdere la loro qualità. Ci sono molti programmi che possono aiutarti. Ad esempio, Photoshop fornisce una bella funzionalità chiamata Salva per Web e dispositivi:


Ci sono molte opzioni in questa finestra di dialogo, ma una delle più importanti è Qualità. Impostarlo su qualcosa come 80% potrebbe ridurre notevolmente le dimensioni del file.

Certo, puoi usare il codice per comprimere i file, ma personalmente preferisco Photoshop e lo sto usando ogni volta che è possibile. Ecco un semplice esempio scritto in PHP:

function compressImage ($ source, $ destination, $ quality) $ info = getimagesize ($ source); switch ($ info ['mime']) case "image / jpeg": $ image = imagecreatefromjpeg ($ source); imagejpeg ($ image, $ destination, $ quality); rompere; case "image / gif": $ image = imagecreatefromgif ($ source); imagegif ($ immagine, $ destinazione, $ qualità); rompere; case "image / png": $ image = imagecreatefrompng ($ source); imagepng ($ immagine, $ destinazione, $ qualità); rompere;  compressImage ('source.png', 'destination.png', 85);

sprites

Una delle cose che puoi fare per aumentare le prestazioni della tua applicazione è ridurre il numero di richieste al server. Quindi, ogni nuova immagine indica una nuova richiesta. È una buona idea combinare le tue immagini in una sola. L'immagine risultante è chiamata a folletto e con cambiare il background-position Stile CSS, puoi mostrare solo la parte dell'immagine di cui hai bisogno. Ad esempio, Twitter Bootstrap utilizza gli sprite per le sue icone interne:


Quindi, nel CSS, puoi fare qualcosa del genere, per mostrare qualsiasi porzione dello sprite che desideri:

.icon-edit background-image: url ("... /img/glyphicons-halflings-white.png"); background-position: -96px -72px; 

caching

Il meccanismo di memorizzazione nella cache del browser è tuo amico. Sì, a volte durante lo sviluppo potrebbe portare ad alcuni molto divertente situazioni, ma aiuta davvero a migliorare le prestazioni del tuo sito. Ogni browser memorizza contenuti come immagini, JavaScript o CSS. Esistono diversi modi per controllare la memorizzazione nella cache e ti suggerisco di consultare questo fantastico articolo per una revisione dettagliata. In generale, puoi controllare il processo impostando le intestazioni, in questo modo:

$ expire = 60 * 60 * 24 * 1; // secondi, minuti, ore, intestazione giorni ('Cache-Control: maxage = ". $ expire); header (" Scade:' .gmdate ('D, d MYH: i: s ', time () + $ expire).' GMT '); intestazione ('Ultima modifica:' .gmdate ('D, d M Y H: i: s'). 'GMT');

prefetching

HTML5 sta andando avanti ogni giorno. C'è una bella funzione chiamata prefetching che dice al browser che nel prossimo futuro avrai bisogno di qualche risorsa e che dovrebbe essere scaricato ora, in anticipo. Per esempio:

Schema URI dati / Immagini in linea

Un paio di anni fa ho dovuto sviluppare una semplice pagina web, che doveva essere solo un file HTML. Naturalmente c'erano diverse immagini, che dovevo includere. Gli schemi di URI dei dati mi hanno aiutato a risolvere il problema. L'idea è di convertire le tue immagini in una stringa codificata in base64 e metterla nel src attributo del img etichetta. Per esempio:

punto Rosso

Utilizzando questo approccio, l'immagine è in realtà nel codice HTML e si salva una richiesta HTTP. Certo, se hai una grande immagine la stringa sarà davvero lunga. Ecco un semplice script PHP che converte le immagini in stringhe base64:

$ picture = fread ($ fp, filesize ($ file)); fclose ($ fp); // base64 codifica i dati binari, quindi li spezza // in blocchi secondo la semantica RFC 2045 $ base64 = base64_encode ($ picture); $ tag = ''; $ css = 'url (data: image / jpg; base64,'. str_replace ("\ n", "", $ base64). '); ';

Potresti trovarlo utile in alcuni casi, ma tieni presente che non funziona molto bene in IE.


CSS

Mi piace pensare che scrivere CSS sia come scrivere codice. Devi ancora organizzare i tuoi stili, definire diversi blocchi e la relazione tra loro. Ecco perché penso che la gestione dei CSS sia davvero importante. Ogni parte dell'applicazione dovrebbe avere i propri stili e dovrebbero essere ben separati. Mantenere tutto in file diversi offre una buona organizzazione, ma ha anche i suoi problemi.

Sappiamo tutti che l'uso del @importare la dichiarazione non è una buona idea. Questo perché ogni nuovo @importare indica una nuova richiesta al server. E se ne hai, per esempio, 20 diversi .css file significa che il browser farà 20 richieste. E il browser non mostra / mostra la pagina prima di scaricare tutti gli stili. Se alcuni dei tuoi .css i file sono mancanti o sono molto grandi, si otterrà un grande ritardo prima di vedere qualcosa sullo schermo.

Usa preprogrammi CSS

I preprocessori CSS risolvono tutti i problemi di cui sopra. Tu dividi ancora i tuoi stili in file diversi, ma alla fine, il preprocessore compila tutto in un singolo .css file. In realtà offrono un sacco di funzioni interessanti come variabili, blocchi nidificati, mixin ed ereditarietà. Il codice sembra ancora CSS, ma è ben formattato / strutturato. Esistono pochi preprocessori popolari che vale la pena controllare: Sass, LESS e Stylus. Ecco un semplice esempio scritto in LESS:

.position (@top: 0, @left: 0) position: absolute; top: @top; a sinistra: @left; allineamento del testo: a sinistra; font-size: 24px;  .header .position (20px, 30px); .tips .position (10px, -20px);  .logo .position (10px, 20px); 

produrrà

.header position: absolute; sopra: 20px; a sinistra: 30 px; allineamento del testo: a sinistra; font-size: 24px;  .header .tips position: absolute; inizio: 10px; a sinistra: -20px; allineamento del testo: a sinistra; font-size: 24px;  .header .logo position: absolute; inizio: 10px; a sinistra: 20px; allineamento del testo: a sinistra; font-size: 24px; 

Oppure, ad esempio se hai uno stile per un pulsante e vuoi produrre lo stesso pulsante ma con un altro colore per il testo, puoi farlo:

.button border: solid 1px # 000; imbottitura: 10px; sfondo: # 9f0; colore: # 0029FF;  .active-button .button (); colore: #FFF; 

CSS efficiente

Normalmente, la maggior parte degli sviluppatori non pensa a CSS efficienti. L'efficienza del CSS si riflette sul rendering della pagina e se i tuoi stili sono inefficienti la tua applicazione sarà resa lentamente dai browser. Un fatto interessante è che i browser analizzano i selettori CSS da destra a sinistra. Il che significa che il seguente codice:

corpo ul li a colore: # F000; decorazione del testo: nessuna; 

... non è affatto efficiente Questo perché il motore otterrà tutto il tag e dovrà valutare ciascuno degli elementi genitore per raccogliere finalmente lo stile necessario. Dovresti anche sapere che in termini di efficienza, i selettori sono classificati secondo il seguente ordine: ID, classe, tag e universale. Ciò significa che un elemento con un id set sarà reso più veloce di un elemento con un semplice selettore di tag. Ovviamente, non ha senso aggiungere id su tutti gli elementi dell'albero DOM, ma dovresti sicuramente controllare il tuo codice e migliorarlo laddove possibile. Ad esempio, se hai qualcosa di simile:

ul #navigation li background: # ff0232; 

Dovresti rimuovere il ul parte, perché ne hai solo uno #navigazione elemento sulla pagina. O nel seguente selettore:

body .content p font-size: 20px; 

È chiaro che il .soddisfare elemento è un figlio di corpo etichetta. Tutti gli elementi sono in realtà figli di questo elemento.

Ecco due link utili su questo argomento: developers.google.com e css-tricks.com

Dimensione del file

Come accennato sopra, è bene avere il minor numero possibile di codice, perché il browser non esegue il rendering della pagina prima di scaricare il CSS. Ecco alcuni suggerimenti per ridurre le dimensioni del file.

Combina stili simili:

.header font-size: 24px;  .content font-size: 24px; 

... si trasforma in:

.header, .content font-size: 24px; 

Utilizzare le stenografie. Invece di:

.header background-color: # 999999; background-image: url (... /images/header.jpg); posizione di sfondo: in alto a destra; 

Scrivilo in questo modo:

.header background: # 999 url (... /images/header.jpg) in alto a destra; 

Minimizza il tuo codice CSS. Puoi farlo usando uno strumento che generalmente rimuove tutti gli spazi e le nuove linee. Ad esempio CSSOptimiser o Minifycss. È prassi comune utilizzare tali strumenti sul lato server dell'applicazione, ad esempio qualcosa scritto nella lingua del back-end. Normalmente questi componenti riducono il tuo codice e lo servono all'utente.

Metti i tuoi file CSS nel Etichetta

È buona norma includere il tuo .css file nel capo tag, in questo modo il browser lo scaricherà prima.


JavaScript

Ridurre il numero di richieste HTTP

Come con il tuo CSS, è bene ridurre il numero di richieste da inviare al server. Nella maggior parte dei casi, il caricamento dei file JavaScript non interrompe il rendering della pagina, ma renderà alcune parti della pagina non funzionali.

Minimizza il tuo codice

Ci sono un sacco di librerie che eseguono la minifrazione di JavaScript. È qualcosa che ridurrà la dimensione dei file, ma tieni presente che in un ambiente di sviluppo è bene mantenere pulito il tuo codice. La maggior parte di questi strumenti modifica il nome delle variabili e converte tutto in una stringa di una riga, rendendo quasi impossibile il processo di debug.

CommonJS, AMD, RequireJS - Provalo

JavaScript in modo nativo non ha un meccanismo per la gestione dei moduli. Quindi, tutte queste cose sono inventate per risolvere questo problema. Forniscono un'API che è possibile utilizzare per definire e utilizzare i moduli. Ad esempio, ecco un esempio tratto da http://requirejs.org/:

   Il mio progetto di esempio     

Il mio progetto di esempio

All'interno di main.js, Puoi usare richiedere() per caricare qualsiasi altro script che ti serve:

require (["helper / util"], function (util) // Questa funzione viene chiamata quando vengono caricati script / helper / util.js. // Se util.js chiama define (), questa funzione non viene attivata fino a // sono state caricate le dipendenze di util e l'argomento util terrà // il valore del modulo per "helper / util".);

Usa Namespace

Se stiamo parlando di organizzazione del codice, non possiamo saltare la parte sui namespace. Nativamente, non esiste una funzione simile in JavaScript, ma è comunque possibile ottenere la stessa cosa con un piccolo codice. Ad esempio, se vuoi creare il tuo framework MVC, probabilmente avrai le seguenti classi:

var model = function () ...; var view = function () ...; var controller = function () ...;

Se lasci le cose come sono nel codice sopra, diventano pubbliche e c'è una maggiore possibilità di produrre conflitti con altre librerie nel tuo progetto. Quindi raggrupparli in un oggetto indipendente (spazio dei nomi) rende il framework protetto:

var MyAwesomeFramework = model: function () ..., view: function () ..., controller: function () ...

Segui i modelli di progettazione

Non è necessario reinventare la ruota. JavasScript è diventato molto popolare e ci sono molte buone pratiche là fuori. I modelli di progettazione sono soluzioni riutilizzabili per problemi comuni nella programmazione. Di seguito alcuni di essi ti aiuteranno a costruire una buona applicazione. Tuttavia, se provassi a coprirli tutti qui, dovrei scrivere un libro, quindi eccone alcuni:

Modello del costruttore

Utilizzare questo modello per creare un'istanza di un tipo di oggetto specifico. Ecco un esempio:

var Class = function (param1, param2) this.var1 = param1; this.var2 = param2;  Class.prototype = method: function () alert (this.var1 + "/" + this.var2); ;

Oppure puoi provare questo:

function Class (param1, param2) this.var1 = param1; this.var2 = param2; this.method = function () alert (param1 + "/" + param2); ; ; var instance = new Class ("valore1", "valore2");

Modello del modulo

Il modello del modulo ci dà la possibilità di creare metodi pubblici e privati. Ad esempio, nel codice seguente, la variabile _indice e il metodo privateMethod sono privati. incremento e getIndex sono pubblici.

var Module = (function () var _index = 0; var privateMethod = function () return _index * 10; return increment: function () _index + = 1;, getIndex: function () return _index; ;) ();

Modello di osservatore

Ovunque tu veda la sottoscrizione o la spedizione di eventi, probabilmente vedrai questo schema. Ci sono osservatori interessati a qualcosa relativo a un oggetto specifico. Una volta che l'azione si verifica, l'oggetto notifica agli osservatori. L'esempio sotto mostra come possiamo aggiungere un osservatore al utenti oggetto:

var Users = list: [], listener: , aggiungi: function (name) this.list.push (name: name); this.dispatch ( "user-aggiunto"); , on: function (eventName, listener) if (! this.listeners [eventName]) this.listeners [eventName] = []; this.listeners [eventName] .push (ascoltatore); , dispatch: function (eventName) if (this.listeners [eventName]) for (var i = 0; i 

Modello di concatenazione di funzioni

Questo modello è un buon modo per organizzare l'interfaccia pubblica del tuo modulo. Risparmia tempo e migliora la leggibilità:

var User = profile: , name: function (value) this.profile.name = value; restituiscilo; , job: function (value) this.profile.job = value; restituiscilo; , getProfile: function () return this.profile; ; var profile = User.name ("Krasimir Tsonev"). job ("sviluppatore web"). getProfile (); console.log (profilo);

Consiglio vivamente di dare un'occhiata a questo libro di Addy Osmani. È una delle migliori risorse che puoi trovare sui modelli di progettazione in JavaScript.


Attivo-Pack

Ora che ci avviciniamo alla fine di questo articolo, voglio condividere alcune considerazioni sulla gestione dei codici CSS e JavaScript sul server. È una tecnica molto comune aggiungere fusioni, minificazioni e compilazioni nella logica dell'applicazione. Spesso esiste una sorta di meccanismo di memorizzazione nella cache, ma tutte le cose accadono durante il runtime. Quindi probabilmente hai una logica di codice, che gestisce la richiesta .js o .css file e serve il contenuto corretto. Dietro a questo processo c'è la compilazione, la minificazione o qualsiasi altra cosa tu stia usando per impacchettare le tue risorse.

Nei miei ultimi progetti ho usato uno strumento chiamato asset-pack. È davvero utile e ti spiegherò in dettaglio che cosa fa esattamente, ma la parte più interessante è come l'ho usata. Questa libreria è pensata per essere utilizzata solo in modalità sviluppo, non è qualcosa che rimane nella base di codice e non è qualcosa che dovresti implementare sul tuo server di produzione.

L'idea è di usare il packer solo mentre lavori sugli asset (CSS, JS). In realtà controlla le modifiche in directory specifiche e compila / impacchetta il codice in un singolo file. Utilizzando questo approccio non è necessario pensare al minification o alla compilation. Tutto quello che devi fare è semplicemente inviare il file statico compilato all'utente. Ciò aumenta le prestazioni della tua applicazione, perché serve solo file statici e, naturalmente, rende le cose più semplici. Non è necessario impostare nulla sul server o implementare una logica non necessaria.

Ecco come è possibile impostare e utilizzare asset-pack.

Installazione

Questo strumento è un modulo Nodejs, quindi dovresti avere già installato Node. Se non lo fai, vai su nodejs.org/download e prendi il pacchetto per il tuo sistema operativo. Dopo di che:

npm install -g assetspack

uso

Il modulo funziona con la configurazione JSON. Quando viene utilizzato tramite la riga di comando, è necessario posizionare le impostazioni in a .jSON file.

Tramite la riga di comando

Creare un assets.json file ed esegui il seguente comando nella stessa directory:

assetspack

Se il file di configurazione utilizza un altro nome o si trova in un'altra directory, utilizzare:

assetspack --config [percorso al file json]

Nel codice

var AssetsPack = require ("assetpack"); var config = [type: "css", watch: ["css / src"], output: "tests / packed / styles.css", minify: true, exclude: ["custom.css"]]; var pack = new AssetsPack (config, function () console.log ("AssetsPack sta guardando");); pack.onPack (function () console.log ("AssetsPack ha fatto il lavoro"););

Configurazione

La configurazione dovrebbe essere un file / oggetto JSON valido. È solo una serie di oggetti:

[(oggetto asset), (oggetto asset), (oggetto asset), ...]

Oggetto del bene

La struttura di base dell'oggetto asset è così:

tipo: (tipo di file / stringa, potrebbe essere css, js o meno per esempio), guarda: (directory o directory per guardare / string o array di stringhe /), pacchetto: (directory o directory per il packing / stringa o array di stringhe /.), output: (percorso del file di output / stringa /), minify: / boolean /, exclude: (matrice di nomi file)

Il pacco la proprietà non è obbligatoria Se ti manca, allora il suo valore è uguale a orologio. minify di default è falso.

Ecco alcuni esempi:

Confezione CSS

type: "css", watch: ["tests / data / css", "tests / data / css2"], pacchetto: ["test / data / css", "test / data / css2"], output: " tests / packed / styles.css ", minify: true, exclude: [" header.css "]

Imballaggio JavaScript

type: "js", watch: "tests / data / js", pacchetto: ["tests / data / js"], output: "tests / packed / scripts.js", minify: true, exclude: ["A .js "]

Imballaggio .Di meno File

L'imballaggio di .Di meno i file sono un po 'diversi. Il pacco la proprietà è obbligatoria ed è fondamentalmente il tuo punto di ingresso. Dovresti importare tutti gli altri .Di meno file lì. Il escludere la proprietà non è disponibile qui.

type: "less", watch: ["tests / data / less"], pacchetto: "tests / data / less / index.less", output: "tests / packed / styles-less.css", minify: true 

Se trovi qualche problema, per favore controlla il test / packing-less.spec.js del repository in GitHub.

Imballaggio di altri formati di file

asset-pack funziona con qualsiasi formato di file. Ad esempio, possiamo combinare template HTML in un singolo file facendo qualcosa del genere:

type: "html", watch: ["tests / data / tpl"], output: "tests / packed / template.html", escludi: ["admin.html"]

L'unica cosa che dovresti sapere qui è che non c'è minimizzazione.


Conclusione

Come sviluppatori web front-end, dovremmo cercare di offrire le migliori prestazioni possibili per i nostri utenti. I suggerimenti di cui sopra non dovrebbero coprire tutti gli aspetti dell'asset management e delle prestazioni, ma sono quelli che ho affrontato personalmente durante il mio lavoro quotidiano. Non esitate a condividere alcuni dei vostri suggerimenti qui sotto, nei commenti.