Le miniature generate in cache generate in PHP vengono caricate lentamente




performance .htaccess (13)

Domanda Parte A ▉ (100 taglie, assegnate)
La domanda principale era come rendere questo sito, caricare più velocemente. Per prima cosa dovevamo leggere queste cascate. Grazie a tutti per i vostri suggerimenti sull'analisi delle letture a cascata. Evidente dai vari grafici a cascata mostrati qui è il collo di bottiglia principale: le miniature generate da PHP. Il caricamento jquery senza protocollo da CDN consigliato da David ha ottenuto la mia taglia, anche se il mio sito è stato solo il 3% più veloce nel complesso e pur non rispondendo al collo di bottiglia principale del sito. Tempo per chiarire la mia domanda, e un'altra taglia:

Domanda parte B ▉ (100 taglie, assegnate)
Il nuovo obiettivo era ora di risolvere il problema delle 6 immagini jpg, che causano la maggior parte del ritardo di caricamento. Queste 6 immagini sono miniature generate da PHP, minuscole e solo 3 ~ 5 kb, ma caricano relativamente molto lentamente. Si noti il ​​" time to first byte " sui vari grafici. Il problema è rimasto irrisolto, ma una donazione è andata a James, che ha corretto l'errore di intestazione underlined RedBot: "Una richiesta condizionale If-Modified-Since ha restituito l'intero contenuto invariato". .

Domanda Parte C ▉ (mia ultima taglia: 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 pensano queste piccole e minuscole miniature da 3 ~ 5Kb? Tutte quelle informazioni di intestazione possono inviare un razzo alla luna e ritorno. Qualche suggerimento su questo collo di bottiglia è molto apprezzato e trattato come possibile risposta, dal momento che sono bloccato da questo problema di bottiglia da ormai sette mesi. Grazie in anticipo.

[Alcune informazioni di base sul mio sito: i CSS sono al top. JS nella parte inferiore (Jquery, interfaccia utente JQuery, menu compresso awm / menu.js, schede js engine, video swfobject.js) Le linee nere sulla seconda immagine mostrano che cosa inizia a caricare. Il robot arrabbiato è il mio animale domestico "ZAM". È innocuo e spesso più felice.]

Carico Cascata: cronologico | http://webpagetest.org

Domini paralleli raggruppati | http://webpagetest.org

Site-Perf Waterfall | http://site-perf.com

Pingdom Tools Waterfall | http://tools.pingdom.com

Cascata di GTmetrix | http://gtmetrix.com


Analizza l'utilizzo di PHP dei dati di sessione. 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 stabile o da altri script di rendering delle immagini. Ciò renderebbe quasi irrilevanti tutte le ottimizzazioni JavaScript / browser, dal momento che 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 lo script termina o quando viene chiamato session_write_close (). Questo serializza efficacemente le cose. Controlla la pagina PHP sulle sessioni, specialmente i commenti, come questo .


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


Ho avuto un problema simile qualche giorno fa e ho trovato head.js. È un plugin Javascript che ti permette di caricare tutti i file JS paralell. Spero possa aiutare.


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

Le intestazioni dell'ultima modifica sono tutte impostate su Sat, 01 gen 2011 12:00:00 GMT, che sembra troppo "tondo" per essere la vera data di generazione ;-)

Dal momento che Cache-control è "public, max-age = 14515200", le intestazioni arbitrarie modificate per ultime potrebbero causare problemi dopo 168 giorni.

Ad ogni modo, questa non è la vera ragione dei ritardi.

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

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

Forse l'intera cosa usa un framework o si connette a qualche database per niente. Ho visto molto lentamente mysql_connect () su alcuni server, soprattutto perché si collegavano usando TCP e non socket, a volte con alcuni problemi DNS.

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


La maggior parte del problema lento è il tuo TTFB (Time to first byte) troppo alto. Questo è difficile da affrontare senza entrare in intimità con i file di configurazione del server, il codice e l'hardware sottostante, ma posso vederlo dilagare su ogni richiesta. Hai troppe barre verdi (cattive) e pochissime barrette blu (buone). Potresti voler smettere di ottimizzare il frontend per un po ', perché credo che tu abbia fatto molto in quell'area. Nonostante il detto che "l' 80% -90% del tempo di risposta dell'utente finale è speso per il frontend ", credo che il tuo si verifichi nel backend.

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

Esegui il tempo dell'esecuzione del codice per trovare cose lente come le query lente del database, l'ora che entra e esce da funzioni / metodi per trovare funzioni lente. Se usi php, prova Firephp . A volte, durante l'avvio o l'inizializzazione vengono eseguite una o due query lente, ad esempio le informazioni sulla sessione o il controllo dell'autenticazione e quali 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 vengano eseguiti su tutto. Altre volte può essere configurato male apache conf e tweaking che salva la giornata.

Cerca loop inefficienti. Cerca le chiamate lente di cache o le operazioni di I / O lente causate da unità disco difettose o dall'utilizzo elevato dello spazio su disco. Cerca gli usi della memoria e cosa viene usato e dove. Esegui un test ripetuto su Webpaget di 10 esecuzioni su un'unica immagine o file utilizzando solo la prima vista da posizioni diverse in tutto il mondo e non dalla stessa posizione. E leggi i registri degli accessi e degli errori, troppi sviluppatori li ignorano e si affidano solo agli errori su schermo emessi. Se il tuo host web ha il supporto, chiedi aiuto, se non lo chiedono forse educatamente, comunque, non farà male.

Puoi provare DNS Prefetching per combattere i numerosi domini e risorse, http://html5boilerplate.com/docs/DNS-Prefetching/

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

In bocca al lupo!

(ps non lavoro per nessuna di queste società, anche il link cloudflight sopra sosterrà che TTFB non è così importante, l'ho buttato lì in modo da poter ottenere un altro take).


Penso che invece di usare quello script di thumbnail-generator devi dare a TinySRC una prova per la generazione rapida di miniature rapide e cloud-hosted. Ha un'API molto semplice e facile da usare, che puoi usare come: -

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

[larghezza] (opzionale): - Questa è una larghezza in pixel (che sostituisce 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. Sostituisce anche il ridimensionamento adattivo o familiare e può essere preceduto da "-" o "x".

Puoi controllare il riepilogo dell'API here

FAQ

Cosa mi costa caroSrc?

Niente.

Quando posso iniziare a utilizzare tinySrc?

Adesso.

Quanto è affidabile il servizio?

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

Quanto è veloce?

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

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


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


Prima di tutto, devi gestire le richieste If-Modified-Since e così appropriatamente, come James ha detto. Questo errore indica che: "Quando chiedo al tuo server se quell'immagine viene 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 dallo script PHP per l'esecuzione. È evidente che qualcosa sta accadendo quando lo script inizia a girare.

  1. Hai preso in considerazione la profilazione? 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 pollici solo se l'immagine originale viene modificata e invia pollici in cache per ogni altra richiesta. Hai controllato che lo script stia generando le immagini inutilmente (ad es. Per ogni richiesta)?

Generare intestazioni appropriate attraverso l'applicazione è un po 'complicato, in più possono essere sovrascritte dal server. E tu sei esposto ad abusi poiché chiunque invii alcune intestazioni di richiesta senza cache farà sì che il tuo generatore di miniature funzioni continuamente (e alza carichi). Quindi, se possibile, prova a salvare quei pollici generati, chiama le immagini salvate direttamente dalle tue pagine e gestisci le intestazioni da .htaccess . In questo caso, non avrai nemmeno bisogno di nulla nel tuo .htaccess se il tuo server è configurato correttamente.

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


Questa è solo un'ipotesi da non aver guardato il tuo codice, ma sospetto che le sessioni possano svolgere un ruolo qui, il seguente è dalla voce PHP Manual su session_write_close() :

I dati di sessione vengono solitamente memorizzati dopo che lo script è stato terminato senza la necessità di chiamare session_write_close (), ma poiché i dati di sessione sono bloccati per impedire la scrittura simultanea, solo uno script può operare in una sessione in qualsiasi momento. Quando si utilizzano i set di cornici insieme alle sessioni, i frame verranno caricati uno a uno a causa di questo blocco. È possibile ridurre il tempo necessario per caricare tutti i frame terminando la sessione non appena tutte le modifiche alle variabili di sessione vengono eseguite.

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 pubblicazione di file multipart e ho avuto lo stesso problema. Quando servivo un file di grandi dimensioni non riuscivo a far funzionare la funzionalità multipart, né avrei potuto aprire un'altra pagina fino al completamento del download. La chiamata a session_write_close() risolto entrambi i miei problemi.


Quindi lo script PHP sta generando le miniature su ogni caricamento della pagina? Innanzitutto, se le immagini che vengono ridotte a icona non cambiano spesso, potresti impostare una cache in modo che non debbano essere analizzate ogni volta che viene caricata la pagina? In secondo luogo, il tuo script PHP usa qualcosa come imagecopyresampled() per creare le miniature? Questo è un downsample non banale e lo script PHP non restituirà nulla fino a quando non sarà ridotto. L'uso di imagecopymerged() ridurrà invece la qualità dell'immagine, ma accelera il processo. E quanta riduzione stai facendo? Queste miniature sono il 5% delle dimensioni dell'immagine originale o il 50%? Una dimensione maggiore dell'immagine originale probabilmente sta causando un rallentamento poiché lo script PHP deve ottenere l'immagine originale in memoria prima che possa ridurla e generare una miniatura più piccola.


Solo una semplice ipotesi perché questo tipo di analisi richiede un sacco di test A / B: il tuo dominio .ch sembra essere difficile da raggiungere (lunghe bande verdi prima che arrivi il primo byte).

Ciò significherebbe che il sito Web .ch è scarsamente ospitato o che l'ISP non ha un buon percorso per raggiungerlo.

Dati i diagrammi, questo potrebbe spiegare un grande successo nelle prestazioni.

In una nota a cuzillion , c'è questo interessante strumento che potrebbe aiutarti a risolvere le cose a seconda del tuo ordine di caricamento delle risorse.


Sono lontano da un esperto ma ...

In merito a questo: "Una richiesta condizionale If-Modified-Since ha restituito l'intero contenuto invariato". e i miei commenti

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

  1. Esiste una versione cache della miniatura.
  2. La versione cache è più recente rispetto all'immagine originale.

Se uno di questi è falso, la miniatura dovrebbe essere generata e restituita, a prescindere da cosa. Se sono entrambi veri, è necessario effettuare il seguente controllo:

  1. Esiste un'intestazione HTTP_IF_MODIFIED_SINCE
  2. L'ultima volta modificata della versione cache è uguale a HTTP_IF_MODIFIED_SINCE

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

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

Riguardo a GZipping, sono stato informato che non è necessario gzipare le immagini quindi ignorare 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 debba 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

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

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




cache-control