Le miniature generate da PHP vengono caricate lentamente


179

Domanda Parte A ▉ (100 premi, assegnati)
La domanda principale era come rendere questo sito, caricare più velocemente. Per prima cosa dovevamo leggere queste cascate. Grazie a tutti per i suggerimenti sull'analisi della lettura a cascata. Evidente dai vari grafici a cascata mostrati qui è il principale collo di bottiglia: le miniature generate da PHP. Il caricamento jquery senza protocollo da CDN consigliato da David ha ottenuto la mia ricompensa, sebbene abbia reso il mio sito solo il 3% più veloce in generale e pur non rispondendo al principale collo di bottiglia del sito. È tempo di chiarire la mia domanda e, un'altra grazia:

Domanda Parte B ▉ (100 premi assegnati)
Il nuovo obiettivo era ora quello di risolvere il problema che avevano le 6 immagini jpg, che stanno causando la maggior parte del ritardo di caricamento. Queste 6 immagini sono miniature generate da PHP, minuscole e solo 3 ~ 5 kb, ma si caricano in modo relativamente molto lento. Notare il " tempo al primo byte " sui vari grafici. Il problema rimase irrisolto, ma una ricompensa andò a James, che riparò l'errore di intestazione sottolineato da RedBot : "Una richiesta condizionale If-Modified-Since ha restituito il contenuto completo invariato". .

Domanda Parte C ▉ (la mia ultima ricompensa: 250 punti)
Sfortunatamente, dopo che è stato corretto anche l'errore di intestazione di REdbot.org, il ritardo causato dalle immagini generate da PHP è rimasto intatto. Cosa diavolo stanno pensando queste minuscole miniature da 3 ~ 5Kb? Tutte queste informazioni di intestazione possono inviare un razzo sulla luna e ritorno. Qualsiasi suggerimento su questo collo di bottiglia è molto apprezzato e trattato come una possibile risposta, dal momento che sono bloccato su questo problema di collo di bottiglia già da sette mesi. Grazie in anticipo.

[Alcune informazioni di base sul mio sito: CSS è in alto. JS in basso (Jquery, JQuery UI, ha acquistato i motori menu awm / menu.js, le schede js engine, il video swfobject.js) Le linee nere sulla seconda immagine mostrano cosa sta iniziando cosa caricare. Il robot arrabbiato è il mio animale domestico "ZAM". È innocuo e spesso più felice.]


Carica cascata: cronologica | http://webpagetest.org inserisci qui la descrizione dell'immagine


Domini paralleli raggruppati | http://webpagetest.org inserisci qui la descrizione dell'immagine


Cascata Site-Perf | http://site-perf.com inserisci qui la descrizione dell'immagine


Cascata degli strumenti di Pingdom | http://tools.pingdom.com

inserisci qui la descrizione dell'immagine


Cascata GTmetrix | http://gtmetrix.com

inserisci qui la descrizione dell'immagine



11
Penso che la maggior parte dei browser effettui solo 20 connessioni alla volta, quindi dopo le 20 la prima deve terminare prima dell'inizio successivo, quindi il rallentamento dopo le 20

1
Penso che ti sia dimenticato di redarre la prima istanza del tuo dominio. Almeno hai il resto però: D
tredici

2
Non riesci a combinare alcune di quelle immagini in sprite?
Marcel Korpel,

1
@Dagon, tieni presente che HTTP 1.1 RFC richiede ( SHOULD) ai client HTTP 1.1 di utilizzare al massimo 2 connessioni ai server HTTP 1.1; HTTP 1.0 ovviamente è molto più aperto.
sarnold

1
I browser @Dagon effettueranno anche solo 2 connessioni simultanee a un determinato dominio.
Endofago il

Risposte:


61

Innanzitutto, l'utilizzo di più domini richiede diverse ricerche DNS. Faresti meglio a combinare molte di quelle immagini in uno sprite invece di diffondere le richieste.

In secondo luogo, quando carico la tua pagina, vedo la maggior parte dei blocchi (~ 1.25s) su all.js. Vedo che inizia con (una vecchia versione di) jQuery. Dovresti fare riferimento a questo da Google CDN, non solo per ridurre i tempi di caricamento , ma potenzialmente evitare una richiesta HTTP per esso interamente.

In particolare, le librerie dell'interfaccia utente jQuery e jQuery più recenti possono essere referenziate a questi URL (vedi questo post se sei interessato al motivo per cui ho omesso http:):

//ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js

//ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/jquery-ui.min.js

Se stai utilizzando uno dei temi dell'interfaccia utente jQuery predefiniti, puoi anche estrarre il CSS e le immagini dalla CDN di Google .

Con l'hosting jQuery ottimizzato, dovresti anche combinare awmlib2.js e tooltiplib.jsin un singolo file.

Se affronti queste cose, dovresti vedere un miglioramento significativo.


1
Ottimo commento Dave! il vecchio 1.3 JQuery era molto più piccolo, quindi ho pensato che mentre funzionava poteva essere più veloce. Ma mi piacciono i tuoi consigli: quale dei link CDN di Google mi consigliate di utilizzare come Jqyuery? Posso usare lo stesso modo JQ UI JavaScript? +1 grazie mille
Sam

2
Consiglio vivamente di utilizzare l'ultima versione di jQuery (attualmente la 1.4.4). Se minimizzato e decompresso, c'è solo una differenza di pochi byte tra di loro. Ho aggiornato la risposta con un paio di collegamenti alle ultime versioni dell'interfaccia utente jQuery e jQuery su Google CDN, che consiglierei di utilizzare.
Dave Ward,

1
Buon consiglio con lo sprite, che dovrebbe ridurre il numero di connessioni aperte al server
JamesHalsall,

attualmente sta lavorando per ridurre le connessioni aperte (è passato da 40 orso a ora 30 orso ... la spinta finale è la più difficile in quanto alcune immagini stanno riscrivendo gli sfondi e non possono andare in uno sprite (o ???)
Sam

Grado di velocità della pagina di aggiornamento : (96%) Grado YSlow: (90%) ... e ancora le anteprime sono più lente che mai!
Sam

17

Ho avuto un problema simile a pochi giorni fa e ho trovato head.js . È un plug-in Javascript che ti consente di caricare tutti i file JS in parallelo. Spero che aiuti.


Incredibile! Come posso averlo ignorato? +1 Ho intenzione di testare ora questo. Odora di una notte fruttuosa.Grazie Schattenbaum!
Sam

1
Posso chiederti se sei Schattenbaum di schattenbaum.net?
Pekka,

12

Sono tutt'altro che un esperto ma ...

A questo proposito: "Una richiesta condizionale If-Modified-Since ha restituito il contenuto completo invariato." e i miei commenti.

Il codice utilizzato per generare le anteprime dovrebbe verificare quanto segue:

  1. Esiste una versione cache dell'anteprima.
  2. La versione memorizzata nella cache è più recente dell'immagine originale?

Se uno di questi è falso, l'anteprima deve essere generata e restituita, qualunque cosa accada. Se sono entrambi veri, è necessario effettuare il seguente controllo:

  1. Esiste un'intestazione HTTP_IF_MODIFIED_SINCE
  2. L'ultima modifica della versione cache è la stessa di HTTP_IF_MODIFIED_SINCE

Se uno di questi è falso, è necessario restituire la miniatura memorizzata nella cache.

Se entrambi sono veri, dovrebbe essere restituito uno stato di 304 http. Non sono sicuro che sia necessario, ma restituisco personalmente anche le intestazioni Cache-Control, Expires e Last-Modified insieme al 304.

Per quanto riguarda GZipping, sono stato informato che non è necessario GZip per le immagini, quindi ignora quella parte del mio commento.

Modifica: non ho notato la tua aggiunta al tuo post.

session_cache_limiter('public');
header("Content-type: " . $this->_mime);
header("Expires: " . gmdate("D, d M Y H:i:s", time() + 2419200) . " GMT");
// I'm sure Last-Modified should be a static value. not dynamic as you have it here.
header("Last-Modified: " . gmdate("D, d M Y H:i:s",time() - 404800000) . " GMT");

Sono anche sicuro che il tuo codice deve verificare l'intestazione HTTP_IF_MODIFIED_SINCE e reagire ad esso. Basta impostare queste intestazioni e il tuo file .htaccess non fornirà il risultato richiesto.

Penso che tu abbia bisogno di qualcosa del genere:

$date = 'D, d M Y H:i:s T'; // DATE_RFC850
$modified = filemtime($filename);
$expires = strtotime('1 year'); // 1 Year

header(sprintf('Cache-Control: %s, max-age=%s', 'public', $expires - time()));
header(sprintf('Expires: %s', date($date, $expires)));
header(sprintf('Last-Modified: %s', date($date, $modified)));
header(sprintf('Content-Type: %s', $mime));

if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
    if(strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) === $modified) {
        header('HTTP/1.1 304 Not Modified', true, 304);
        // Should have been an exit not a return. After sending the not modified http
        // code, the script should end and return no content.
        exit();
    }
}
// Render image data

James, hai risolto l'essenza del problema dopo la modifica nella tua risposta! il If Modified Sinceproblema sembra funzionare ora! Tuttavia, le lunghe intestazioni / i tempi di attesa per i minuscoli pollici non sono ancora risolti ...
Sam

@James PS REdbot.org afferma che l'intestazione Expires ha un valore errato. Penso che debba essere GMT e non CET?
Sam,

@Sam Siamo spiacenti, il mio server è nel Regno Unito, quindi genera automaticamente le date GMT. Basta usare la funzione PHP gmdate invece se la data. Questo dovrebbe produrre una data GMT relativa all'ora del tuo server.
James,

1
@ Sam, il tempo di attesa è il tempo di esecuzione dello script. O impiegare molto tempo per passare attraverso il codice al punto in cui invii le intestazioni o quando non esci dopo aver inviato le intestazioni.
James,

@James, capisco ... Ma a parte quel generatore di miniature php, ci sono molti altri script ugualmente lunghi che fanno varie altre cose (traduzioni, caricamento di menu ecc.) Il tutto in una frazione di tempo ... LORO non sembra essere un collo di bottiglia ... questo indirizza SOLO il problema al generatore di miniature php?
Sam,

6

Wow, è difficile spiegare le cose usando quell'immagine .. Ma qui, alcuni tentativi:

  • i file 33-36 vengono caricati in ritardo, poiché vengono caricati in modo dinamico all'interno di swf e swf (25) viene caricato prima completamente prima di caricare qualsiasi contenuto aggiuntivo
  • i file 20 e 21 sono forse (non lo so, perché non conosco il tuo codice) librerie caricate da all.js (11), ma per l'esecuzione di 11, attende l'intera pagina (e risorse) caricare (dovresti cambiarlo in domready)
  • i file 22-32 vengono caricati da queste due librerie, dopo che sono stati caricati completamente

Punto interessante Immagino che non ci sia nulla intorno alla SWF ... Come posso cambiare cosa da domready? Ho un'idea di cosa intendi. Riguarda quando javascript è pronto e dice sul documento pronto questo o quello? quel documento dovrebbe già essere sostituito da dom.ready?
Sam,

@Sam se stai utilizzando la memorizzazione nella cache lato client (e dovresti esserlo), puoi caricare le risorse utilizzate da swf in js o div nascosti sulla tua pagina in modo che quando swf li richieda siano già sul client.
Endofago il

4

Una semplice ipotesi perché questo tipo di analisi richiede molti test A / B: il tuo dominio .ch sembra essere difficile da raggiungere (lunghe bande verdi prima dell'arrivo del primo byte).

Ciò significherebbe che il sito Web .ch è scarsamente ospitato o che l'ISP non ha una buona strada per raggiungerli.

Dati i diagrammi, questo potrebbe spiegare un grande successo in termini di prestazioni.

Una nota a margine , c'è questo fantastico strumento che può aiutarti a risolvere le cose in base all'ordinamento del caricamento delle risorse.


4

Prova a eseguire i test Y! Slow e Page Speed ​​sul tuo sito / pagina e segui le linee guida per risolvere i possibili colli di bottiglia nelle prestazioni. Dovresti ottenere enormi miglioramenti delle prestazioni una volta ottenuto un punteggio più alto in Y! Slow o Page Speed.

Questi test ti diranno cosa c'è che non va e cosa cambiare.


Grazie! i punteggi sono: 92 su Page Speed ​​e 93 su Ylow. Quello che manca sono: KEEP ALIVE = off e non utilizza CDN.
Sam,

AGGIORNAMENTO: 96 e 90 rispettivamente attualmente
Sam

4

Quindi il tuo script PHP sta generando le anteprime ad ogni caricamento della pagina? Prima di tutto, se le immagini che vengono visualizzate in anteprima non cambiano così spesso, potresti impostare una cache in modo tale che non debbano essere analizzate ogni volta che la pagina viene caricata? In secondo luogo, il tuo script PHP sta usando qualcosa di simile imagecopyresampled()per creare le miniature? Questo è un downsample non banale e lo script PHP non restituirà nulla fino a quando non sarà fatto restringere le cose. L'uso imagecopymerged()invece ridurrà la qualità dell'immagine, ma accelererà il processo. E quanta riduzione stai facendo? Queste miniature hanno il 5% delle dimensioni dell'immagine originale o il 50%? Una dimensione maggiore dell'immagine originale probabilmente sta portando a un rallentamento poiché lo script PHP deve salvare l'immagine originale in memoria prima che possa ridurla e produrre una miniatura più piccola.


Grazie MidnightLightning! Esiste una cartella cache in cui vengono creati e riutilizzati miniature JPG, anche se ho la sensazione che qui si trovi il problema dello script che ho acquistato (e sembra funzionare bene per gli altri)
Sam

2
Se le anteprime sono memorizzate nella cache, assicurati che lo script che le sta estraendo dalla cache sia in uso readfile()anziché file_get_contents()seguito da un'eco, che attende di produrre qualsiasi cosa fino a quando l'intero file non viene spostato nella memoria dello script PHP.
MidnightLightning

Meglio ancora: se i file sono memorizzati nella cache, genera l'HTML in un modo che tira direttamente l'immagine memorizzata nella cache dal disco senza passare attraverso PHP. Questo è quello che faccio nei miei script per videodb.net
andig

"Esiste una cartella cache in cui ..." e con quale rapidità vengono indicati? Il tuo URL punta direttamente al file memorizzato nella cache o a uno script PHP? Reindirizzi o usi readfile ()? Lo stesso script PHP contiene il codice di generazione delle miniature o rinvii il caricamento della maggior parte del codice usando include / erquire?
symcbean

4

Ho trovato l'URL del tuo sito Web e controllato un singolo file jpg dalla homepage. Mentre il tempo di caricamento è ragionevole ora (161ms), è in attesa di 126ms, che è troppo.

Le tue ultime intestazioni modificate sono tutte impostate su Sab, 01 gen 2011 12:00:00 GMT, che sembra troppo "rotondo" per essere la vera data della generazione ;-)

Poiché il controllo della cache è "pubblico, età massima = 14515200", le intestazioni arbitrarie dell'ultima modifica potrebbero causare problemi dopo 168 giorni.

Comunque, questa non è la vera ragione dei ritardi.

Devi controllare cosa fa il tuo generatore di miniature quando la miniatura esiste già e cosa potrebbe richiedere così tanto tempo per controllare e consegnare l'immagine.

È possibile installare xdebug per profilare lo script e vedere dove si trovano i colli di bottiglia.

Forse il tutto usa un framework o si connette a qualche database per niente. Ho visto mysql_connect () molto lento su alcuni server, principalmente perché si stavano connettendo usando TCP e non socket, a volte con alcuni problemi DNS.

Capisco che non puoi pubblicare qui il tuo generatore di pagamenti, ma temo che ci siano troppi problemi possibili ...


Grazie per il tuo detective e punto sugli indizi Capsule! Per prima cosa: non esiste un database. Le tue scoperte sono le mie: è in attesa del 90% delle volte? Piccoli pollici pazzi. Pensieri interessanti sulle intestazioni modificate per ultima, perché secondo il post di James qui, ho dovuto impostare quelle intestazioni Ultima modifica su un tempo STATICO (fisso), non dinamico / cambiando sempre il tempo impostato dai generatori php gmdate. O forse vuoi dire qualcos'altro qui? (Nominato per generosità)
Sam,

1
Per essere perfetto, dovrebbe riflettere la data di generazione reale, ad esempio ottenendo il filemtime () della miniatura memorizzata nella cache. Ciò che sarebbe interessante testare è accedere a un file PHP vuoto o a un file PHP che fa eco "test" e vedere quanta attesa hai su questo. Forse l'intero server è solo lento e ha un impatto su ogni singolo script PHP, qualunque cosa faccia.
Capsule

1
Vedo anche un ritardo relativamente lungo su file statici puri (ad esempio le immagini collegate ai pollici), come 36ms. Su uno dei server che sto amministrando (che non è una bestia ... dual core con 2Gb di RAL), ottengo quasi la metà di questo, come 20ms su file statici.
Capsule

Interessante ... 1. quale software / strumento online usi per misurare? 2. Le tue misurazioni più veloci di 20 ms sono coerenti (quanti ± xx%) ritieni che i tuoi risultati possano variare? Nel mio caso, varia molto a seconda dello strumento di test che utilizzo. alcuni sono molto coerenti ( gtmetrix.com ) alcuni sono davvero variabili ( pingdom.com ) ed è difficile dare tempi in XX ms poiché cambiano ogni volta ...
Sam

Sto usando la scheda NET di Firebug. 20ms è il tempismo più veloce che sto ricevendo. Va da 20 a 28. Naturalmente anche i 36ms che ho misurato sul tuo server sono stati i più veloci.
Capsule

4

Se non c'è un motivo davvero valido (di solito non esiste) le tue immagini non dovrebbero invocare l'interprete PHP.

Crea una regola di riscrittura per il tuo server web che server l'immagine direttamente se viene trovata sul file system. In caso contrario, reindirizza allo script PHP per generare l'immagine. Quando si modifica l'immagine, modificare il nome file delle immagini per forzare gli utenti che dispongono di una versione cache a recuperare l'immagine appena modificata.

Se almeno non funziona, ora non ha nulla a che fare con il modo in cui le immagini vengono create e controllate.


Grazie Goran, tuttavia questa non è l'elegante soluzione che desidero: penso che ci sia qualcosa di sospetto nel mio caso, e che normalmente non ci vuole molto tempo perché uno script php sappia se passare un'intestazione 304 o cuocere il immagine ecc. grazie comunque per il tuo suggerimento in quanto indirizza il problema da una prospettiva completamente nuova! Che è prezioso da solo +1
Sam

3

Analizza l'utilizzo dei dati della sessione da parte di PHP. Forse (solo forse), lo script PHP che genera immagini è in attesa di ottenere un blocco sui dati della sessione, che è bloccato dalla pagina principale di rendering ancora o da altri script di rendering di immagini. Ciò renderebbe quasi irrilevanti tutte le ottimizzazioni JavaScript / browser, poiché il browser è in attesa del server.

PHP blocca i dati della sessione per ogni script in esecuzione, dal momento in cui inizia la gestione della sessione, al momento in cui termina lo script o quando viene chiamato session_write_close (). Questo serializza efficacemente le cose. Dai un'occhiata alla pagina PHP sulle sessioni, in particolare i commenti, come questo .


Grazie per il suggerimento Ricardo! Sembra che Alix stia suggerendo lo stesso di te (giusto?). In termini pratici, cosa mi consigliate di inserire / rimuovere dal codice, quindi testare nuovamente i grafici e riportare indietro? Molto apprezzato.
Sam

1
Penso di sì. Ti suggerisco di cambiare gli script generatori di immagini in modo che non dipendano dai dati $ _SESSION o simili (forse non lo fanno già). Quindi utilizzare session_write_close () il più presto possibile , o, ancora meglio, evitare di usare sessioni su quegli script. Dai
Ricardo Pardini

3

Questa è solo un'ipotesi selvaggia poiché non ho esaminato il tuo codice ma sospetto che le sessioni possano svolgere un ruolo qui, quanto segue dalla voce del Manuale PHP su session_write_close():

I dati della sessione vengono in genere archiviati dopo la chiusura dello script senza la necessità di chiamare session_write_close (), ma poiché i dati della sessione sono bloccati per impedire scritture simultanee, solo uno script può operare su una sessione in qualsiasi momento. Quando si utilizzano i set di frame insieme alle sessioni, i frame si caricheranno uno alla volta a causa di questo blocco. È possibile ridurre il tempo necessario per caricare tutti i frame terminando la sessione non appena vengono apportate tutte le modifiche alle variabili di sessione.

Come ho detto, non so cosa stia facendo il tuo codice ma quei grafici sembrano stranamente sospetti. Ho avuto un problema simile quando ho codificato una funzione di servizio di file multipart e ho avuto lo stesso problema. Durante la pubblicazione di un file di grandi dimensioni non sono riuscito a far funzionare la funzionalità multipart né ho potuto aprire un'altra pagina fino al completamento del download. Chiamare session_write_close()risolto entrambi i miei problemi.


Grazie Alix per il tuo suggerimento. Una domanda: la exit();funzione è in linee simili alla session_write_close();? attualmente, lo scrittore originale del codice sta studiando il problema, ma sembra che sia anche un po 'al buio, poiché è generoso aggiornamento del codice con una migliore gestione If-Modified-Since sembra avere gli stessi ritardi (nuova cascata i grafici producevano gli stessi grafici, anche se i risultati dei veri problemi apparivano / avvertivano caricamenti più rapidi! È un problema molto strano ...
Sam

1
@Sam: Non posso darti alcuna fonte in questo momento, ma credo che exit () prima chiami tutti i distruttori e / o le funzioni registrate per lo spegnimento e solo allora la sessione è chiusa. Comunque, scommetto che probabilmente il tuo problema risiede prima della tua chiamata exit (). Vedi anche: stackoverflow.com/questions/1674314/…
Alix Axel

2

Hai provato a sostituire i thumnails generati da php con immagini regolari per vedere se c'è qualche differenza? Il problema potrebbe sorgere - un bug nel tuo codice php che porta a una rigenerazione della miniatura su ogni chiamata del server - un ritardo nel tuo codice (sleep ()?) Associato a un problema di clock - un problema hardrive che causa una pessima condizione di gara poiché tutte le anteprime vengono caricate / generate contemporaneamente.


Qualcosa che a un certo punto ho pensato di provare +1 per leggere i miei pensieri e rivelare la prima soluzione che ho già fatto. Quello che stavo sperando, era scoprire che le immagini normali si sarebbero anche caricate lentamente, tanto che poteva essere la banda di download con velocità o qualcosa di fisicamente limitante, ma ho scoperto invece che le normali immagini di dump statiche (ho salvato i pollici generati e caricati come statici) questi caricati ESTREMAMENTE veloce. Quindi deve fare ciò che il generatore di miniature php!
Sam

2

Penso che invece di usare quello script del generatore di miniature devi provare TinySRC per una generazione di miniature rapida e ospitata sul cloud. Ha un'API molto semplice e facile da usare, puoi usare come: -

http://i.tinysrc.mobi/ [height] / [width] /http://domain.tld/path_to_img.jpg

[larghezza] (opzionale): - Questa è una larghezza in pixel (che sovrascrive il dimensionamento adattivo o familiare). Se il prefisso è '-' o 'x', verrà sottratto o ridotto a una percentuale della dimensione determinata.

[altezza] (opzionale): - Questa è un'altezza in pixel, se è presente anche la larghezza. Sovrascrive anche il dimensionamento adattivo o familiare e può essere preceduto da "-" o "x".

Puoi controllare il riepilogo API qui


FAQ

Quanto mi costa tinySrc?

Niente.

Quando posso iniziare a usare tinySrc?

Adesso.

Quanto è affidabile il servizio?

Non garantiamo il servizio tinySrc. Tuttavia, funziona su un'importante infrastruttura cloud distribuita , quindi offre elevata disponibilità in tutto il mondo. Dovrebbe essere sufficiente per tutte le tue esigenze.

Quanto è veloce?

tinySrc memorizza nella cache le immagini ridimensionate in memoria e nel nostro archivio dati per un massimo di 24 ore e non recupererà ogni volta l'immagine originale. Questo rende i servizi incredibilmente veloci dal punto di vista dell'utente. (E riduce il carico del server come un piacevole effetto collaterale.)


In bocca al lupo. Solo un suggerimento, dal momento che non ci stai mostrando il codice: p


2

Poiché alcuni browser scaricano solo 2 download paralleli per dominio, non è possibile aggiungere domini aggiuntivi per suddividere le richieste su due o tre nomi host diversi. ad es. 1.imagecdn.com 2.imagecdn.com


+1 per il tuo suggerimento: grazie, ma se guardi più da vicino al mio (ammesso: disegni molto caotici) vedrai che alcuni elementi provengono da ....... alcuni provengono da ........ com .......... de MA, forse che non fa il trucco come fa il tuo suggerimento? (Vedo che suggerisci sottodomini, anziché solo domini diversi.)
Sam

1

Prima di tutto, devi gestire le If-Modified-Sincerichieste e in modo appropriato, come ha detto James. Questo errore indica che: "Quando chiedo al tuo server se quell'immagine è stata modificata dall'ultima volta, invia l'intera immagine invece di un semplice sì / no".

Il tempo tra la connessione e il primo byte è generalmente il tempo impiegato per l'esecuzione dello script PHP. È evidente che qualcosa sta accadendo quando lo script inizia a essere eseguito.

  1. Hai pensato di profilarlo? Potrebbe avere alcuni problemi.
  2. In combinazione con il problema precedente, lo script potrebbe essere in esecuzione molte più volte del necessario. Idealmente, dovrebbe generare i pollici solo se l'immagine originale viene modificata e inviare i pollici memorizzati nella cache per ogni altra richiesta. Hai verificato che lo script generi inutilmente le immagini (ad es. Per ogni richiesta)?

Generare le intestazioni corrette attraverso l'applicazione è un po 'complicato, inoltre possono essere sovrascritti dal server. E sei esposto ad abusi in quanto chiunque invii alcune intestazioni di richiesta senza cache farà funzionare il tuo generatore di miniature continuamente (e aumenterà i carichi). Quindi, se possibile, prova a salvare i pollici generati, chiama le immagini salvate direttamente dalle tue pagine e gestisci le intestazioni .htaccess. In questo caso, non avresti nemmeno bisogno di nulla nel .htaccesstuo server se il tuo server è configurato correttamente.

Oltre a questi, puoi applicare alcune delle brillanti idee di ottimizzazione dalle parti relative alle prestazioni di questa bella domanda SO generale su come fare i siti Web nel modo giusto , come suddividere le tue risorse in sottodomini senza cucina, ecc. Ma in ogni caso, un'immagine 3k non dovrebbe richiedere un secondo per caricare, questo è evidente rispetto ad altri elementi nei grafici. Dovresti provare a individuare il problema prima di ottimizzare.


-1: Rispondere a una richiesta condizionale con "Non modificato" e nessun tempo di scadenza modificato renderà il tuo sito più lento nel 99,9% dei casi (A proposito, AFAIK, non c'è modo di far sì che Apache rilasci informazioni di cache riviste con una risposta 304)
symcbean

E che cosa ha a che fare con la mia risposta?
Halil Özgür

1

Hai provato a configurare diversi sottodomini nel server web NGINX appositamente per servire dati statici come immagini e fogli di stile? Qualcosa di utile potrebbe essere già stato trovato in questo argomento .


Grazie! Dopo alcune ricerche, tuttavia, sembra che la configurazione di sottodomini per i cookie statici del server renda più veloce un sito, quando ci sono molte immagini, a un costo aggiuntivo. Nel mio caso scommetto che le 6 immagini non verranno caricate più velocemente dell'overhead del dominio secondario / extra. Destra?
Sam,

1
NGinx supporta sendfile syscall, che potrebbe inviare file direttamente da HDD. consultare il seguente documento wiki.nginx.org/HttpCoreModule sulle direttive 'sendfile', 'aio'. Questo server web serve file statici come immagini molto più velocemente di apache.
nefo_x,

interessante ... non sapevo che potesse esserci qualcosa di meglio di Apache. A proposito, cosa intendi con straight from hdd. vuoi dire invece straight from DDR3 RAM/ straight from Solid State DiskSo che i dischi rigidi, a differenza della RAM DDR3 o dei dischi a stato solido, hanno un tempo di accesso molto lento. Ma penso che questo non sia il collo di bottiglia qui ...
Sam

1
il punto è che nginx non bufferizza l'output di dati statici, come fa Apache.
nefo_x,

1

Per quanto riguarda le miniature ritardate, prova a mettere una chiamata a flush () immediatamente dopo l'ultima chiamata a header () nello script di generazione delle miniature. Una volta fatto, rigenerare il grafico a cascata e vedere se il ritardo è ora sul corpo anziché sulle intestazioni. In tal caso, è necessario esaminare a lungo la logica che genera e / o genera i dati dell'immagine.

Si spera che lo script che gestisce le anteprime utilizzi una sorta di memorizzazione nella cache in modo che qualsiasi azione intraprenda sulle immagini che servi avverrà solo quando assolutamente necessario. Sembra che si stia svolgendo un'operazione costosa ogni volta che servi le anteprime che ritardano qualsiasi output (comprese le intestazioni) dallo script.


+1 Immagino eccitante provarlo ora! riferirò quando ho fatto scorrere la nuova cascata ...
Sam

Sfortunatamente, dopo aver aggiunto le flush();intestazioni subito dopo, non sembra esserci alcun cambiamento! Cosa potrebbe significare?
Sam

Non sono sicuro. C'è un modo per collegarci allo script PHP in questione? So che hai pagato per questo, ma è incredibilmente difficile dire cosa potrebbe causare il comportamento senza essere in grado di vedere cosa sta facendo.
AR Younce

Le anteprime sono referenziate nei CSS o nei tag <img>?
AR Younce

Cosa intendi con riferimento in css? sono a fianco del corpo html e come segue: <img src="thumbprocessor.php?src=/folder/image.jpg&w=100&h=200" id="thumbnail"/>
Sam

1

La maggior parte del problema lento è che il tuo TTFB (tempo al primo byte) è troppo alto. È difficile da affrontare senza essere intimi con i file di configurazione del server, il codice e l'hardware sottostante, ma posso vedere che dilaga su ogni richiesta. Hai troppe barre verdi (cattive) e pochissime barre blu (buone). Potresti voler smettere di ottimizzare un po 'il frontend, poiché credo che tu abbia fatto molto in quella zona. Nonostante il detto che "l' 80% -90% del tempo di risposta dell'utente finale viene speso nel frontend ", credo che il tuo si stia verificando nel backend.

TTFB è roba back-end, roba server, pre-elaborazione prima dell'output e handshaking.

Calcola il tempo di esecuzione del codice per trovare elementi lenti come le query lente del database, inserire e uscire da funzioni / metodi per trovare funzioni lente. Se usi php, prova Firephp . A volte si tratta di una o due query lente in esecuzione durante l'avvio o l'inizializzazione come estrarre informazioni sulla sessione o controllare l'autenticazione e cosa no. L'ottimizzazione delle query può portare ad alcuni buoni guadagni perf. A volte il codice viene eseguito utilizzando php prepend o spl autoload in modo che funzionino su tutto. Altre volte può essere configurato in modo errato apache conf e tweaking che salva la giornata.

Cerca loop inefficienti. Cercare chiamate a recupero lento di cache o operazioni di I / O lente causate da unità disco guaste o elevato utilizzo dello spazio su disco. Cerca gli usi della memoria e ciò che viene utilizzato e dove. Esegui un test ripetuto webpagetest di 10 esecuzioni su una singola immagine o file utilizzando solo la prima vista da diverse posizioni nel mondo e non dalla stessa posizione. E leggi i tuoi log degli accessi e degli errori, troppi sviluppatori li ignorano e fanno affidamento solo sugli errori visualizzati sullo schermo. Se il tuo host web ha supporto, chiedi aiuto, se non glielo chiedono educatamente, non farà male.

Puoi provare il prefetching DNS per combattere molti domini e risorse, http://html5boilerplate.com/docs/DNS-Prefetching/

Il tuo server è un server buono / decente? A volte un server migliore può risolvere molti problemi. Sono un fan della mentalità ' hardware è economico, i programmatori sono costosi ', se hai la possibilità e il denaro di aggiornare un server. E / O usa un CDN come maxcdn o cloudflare o simili.

In bocca al lupo!

(ps non lavoro per nessuna di queste aziende. Anche il link cloudflare sopra sosterrà che il TTFB non è così importante, l'ho gettato lì in modo da poter avere un altro introito.)


Caro Anthony, grazie mille per questa perspicace conoscenza "di base". Sono d'accordo che a volte l'hardware è il collo di bottiglia e che è meno ovvio da misurare soprattutto quando la società di hosting ospita la parte server in un ambiente di hosting condiviso. Penso che cloudflare sia una buona opzione da provare in combinazione con l'ottimizzazione della configurazione di Apache. Saluti!
Sam,

-1

Mi dispiace dirlo, fornisci pochi dati. E hai già avuto dei buoni suggerimenti.

Come stai servendo quelle immagini? Se trasmetti in streaming tramite PHP stai facendo una cosa molto brutta, anche se sono già generati.

NON STREAM MAI IMMAGINI CON PHP. Rallenterà il tuo server, indipendentemente dal modo in cui lo usi.

Inseriscili in una cartella accessibile, con un URI significativo. Quindi chiamali direttamente con il loro vero URI. Se hai bisogno della generazione al volo dovresti inserire un .htaccess nella directory delle immagini che reindirizza a uno script php del generatore solo se manca l'immagine della richiesta. (questo si chiama strategia cache-on-request).

Ciò risolverà la sessione php, il proxy del browser, la memorizzazione nella cache, ETAGS, qualunque cosa tutto in una volta.

WP-Supercache utilizza questa strategia, se configurato correttamente.

L'ho scritto qualche tempo fa ( http://code.google.com/p/cache-on-request/source/detail?r=8 ), le ultime revisioni sono rotte, ma suppongo che 8 o meno dovrebbero funzionare e tu puoi prendi il .htaccess come esempio solo per testare le cose (anche se ci sono modi migliori per configurare il .htaccess rispetto al modo in cui ero solito).

Ho descritto quella strategia in questo post sul blog ( http://www.stefanoforenza.com/need-for-cache/ ). Probabilmente è scritto male ma può aiutare a chiarire le cose.

Ulteriori letture: http://meta.wikimedia.org/wiki/404_handler_caching


Mente, ErrorDocument non è davvero la cosa migliore che puoi fare, poiché ha generato voci nel registro degli errori di Apache, un reindirizzamento -f sarebbe meglio.
Tacone,

Grazie per il tuo contributo tacone. Stai dicendo che non importa quanto sarà buono lo script php, rallenterà il server o come hai detto nel tuo post "Ucciderà il tuo server, qualunque cosa accada".
Sam

rallenterà il server, non importa quanto sia buono lo script. Per ogni immagine il server dovrà caricare php e fare in modo che l'immagine venga trasmessa byte per byte. Lascia che apache faccia il lavoro senza nemmeno passare dall'interprete php. Di conseguenza, molti altri possibili errori verranno automaticamente evitati, come sessioni, lunghezza dei contenuti, memorizzazione nella cache, mime / tipo ecc. QUANDO le prestazioni sono fondamentali, non dovresti nemmeno caricare php (ma al momento della generazione).
Tacone,

Votanti, potete spiegare perché?
Tacone
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.