La guida avanzata per ottimizzare le prestazioni di WordPress

Pubblicato: 2022-03-11

Oggi WordPress alimenta oltre il 30% di Internet. È facile da usare, incredibilmente popolare e non andrà da nessuna parte presto.

Ma WordPress può essere lento. Allora come lo ottimizzi?

Ci sono un sacco di articoli su come ottimizzare e ottimizzare WordPress. In effetti, lo stesso WordPress fornisce una guida solida sull'ottimizzazione di WordPress.

Per la maggior parte, questi articoli e tutorial trattano concetti piuttosto semplici ma utili, come l'utilizzo di plug-in di cache, l'integrazione con le reti di distribuzione dei contenuti (CDN) e la riduzione al minimo delle richieste. Sebbene questi suggerimenti siano altamente efficaci e persino necessari, alla fine non risolvono il problema di fondo: la maggior parte dei siti WordPress lenti sono il risultato di un codice errato o inefficiente.

La guida avanzata per ottimizzare le prestazioni di WordPress

WordPress può essere lento, ma non deve esserlo.
Twitta

Pertanto, questo articolo mira principalmente a fornire agli sviluppatori e alle società di sviluppo di WordPress alcune linee guida che possono aiutarli ad affrontare le cause alla base di molti problemi di prestazioni di WordPress.

WordPress offre molte funzionalità orientate alle prestazioni che sono spesso trascurate dagli sviluppatori. Il codice che non sfrutta queste funzionalità può rallentare le attività più semplici, come il recupero dei post. Questo articolo descrive in dettaglio quattro possibili soluzioni, che risolvono alcuni dei problemi alla base delle lente prestazioni di WordPress.

Recupero dei messaggi

WordPress offre la possibilità di recuperare qualsiasi tipo di post dal database. Ci sono tre modi fondamentali per farlo:

  • Utilizzo della funzione query_posts() : questo è un approccio molto diretto, ma il problema è che sovrascrive la query principale, il che potrebbe causare inconvenienti. Ad esempio, questo potrebbe essere un problema se volessimo determinare, a un certo punto dopo aver recuperato i post (come inside footer.php ), con che tipo di pagina abbiamo a che fare. In effetti, la documentazione ufficiale ha una nota che sconsiglia l'uso di questa funzione poiché dovrai chiamare una funzione aggiuntiva per ripristinare la query originale. Inoltre, la sostituzione della query principale avrà un impatto negativo sui tempi di caricamento della pagina.

  • Usando la funzione get_posts() : funziona quasi come query_posts() , ma non modifica la query principale. D'altra parte, get_posts() per impostazione predefinita esegue la query con il parametro suppress_filters impostato su true . Ciò potrebbe causare incoerenze, soprattutto se utilizziamo filtri relativi alle query nel nostro codice, poiché i post che non ti aspetti in una pagina potrebbero essere restituiti da questa funzione.

  • Utilizzo della classe WP_Query : a mio parere, questo è il modo migliore per recuperare i post dal database. Non altera la query principale e viene eseguita in modo standard, proprio come qualsiasi altra query di WordPress.

Ma qualunque sia il metodo che utilizziamo per interagire con il database, ci sono altre cose che dobbiamo considerare.

Limitare la domanda

Dovremmo sempre specificare quanti post deve recuperare la nostra query.

Per fare ciò, utilizziamo il parametro posts_per_page .

WordPress ci consente di indicare -1 come possibile valore per quel parametro, nel qual caso il sistema proverà a recuperare tutti i post che soddisfano le condizioni definite.

Questa non è una buona pratica, anche se siamo certi che otterremo solo pochi risultati come risposta.

Per uno, raramente possiamo essere certi di ottenere solo pochi risultati. E anche se possibile, l'impostazione di nessun limite richiederà al motore di database di eseguire la scansione dell'intero database alla ricerca di corrispondenze.

Al contrario, la limitazione dei risultati spesso consente al motore di database di eseguire la scansione solo parziale dei dati, il che si traduce in tempi di elaborazione ridotti e una risposta più rapida.

Un'altra cosa che WordPress fa per impostazione predefinita, che può influire negativamente sulle prestazioni, è che cerca di portare post appiccicosi e calcolare quante righe sono state trovate nella query.

Spesso, però, non abbiamo davvero bisogno di queste informazioni. L'aggiunta di questi due parametri disabiliterà tali funzionalità e accelererà la nostra query:

 $query = new WP_Query( array( 'ignore_sticky_posts' => true, 'no_found_rows' => true ) );

Esclusione di post dalla query

Wordpress Escludi i post dalla query

A volte vogliamo escludere determinati post dalla query. WordPress offre un modo abbastanza diretto per raggiungerlo: utilizzando il parametro post__not_in . Per esempio:

 $posts_to_exclude = array( 1, 2, 3 ); $posts_per_page = 10; $query = new WP_Query( array( 'posts_per_page' => $posts_per_page, 'post__not_in' => $posts_to_exclude ) ); for ( $i = 0; $i < count( $query->posts ); $i++ ) { //do stuff with $query->posts[ $i ] }

Ma mentre questo è abbastanza semplice, non è ottimale perché internamente genera una sottoquery. Soprattutto nelle installazioni di grandi dimensioni, ciò può portare a risposte lente. È più veloce lasciare che l'elaborazione venga eseguita dall'interprete PHP con alcune semplici modifiche:

 $posts_to_exclude = array( 1, 2, 3 ); $posts_per_page = 10; $query = new WP_Query( array( 'posts_per_page' => $posts_per_page + count( $posts_to_exclude ) ) ); for ( $i = 0; $i < count( $query->posts ) && $i < $posts_per_page; $i++ ) { if ( ! in_array( $query->posts[ $i ]->ID, $posts_to_exclude ) ) { //do stuff with $query->posts[ $i ] } }

Cosa ho fatto lì?

Fondamentalmente, ho tolto del lavoro dal motore di database e l'ho lasciato al motore PHP, che fa le stesse cose ma in memoria, che è molto più veloce.

Come?

Innanzitutto, ho rimosso il parametro post__not_in dalla query.

Poiché la query potrebbe portarci alcuni post che non desideriamo come risultato, ho aumentato il parametro posts_per_page . In questo modo mi assicuro che, anche se avessi avuto alcuni post indesiderati nella mia risposta, avrei almeno $posts_per_page post desiderati lì.

Quindi, quando elaboro i post, elaboro solo quelli che non sono all'interno dell'array $posts_to_exclude .

Evitare la parametrizzazione complessa

Tutti questi metodi di query offrono un'ampia varietà di possibilità per recuperare i post: per categorie, per meta chiavi o valori, per data, per autore, ecc.

E sebbene tale flessibilità sia una caratteristica potente, dovrebbe essere usata con cautela perché tale parametrizzazione potrebbe tradursi in complessi join di tabelle e costose operazioni di database.

Nella prossima sezione, illustreremo un modo elegante per ottenere comunque funzionalità simili senza compromettere le prestazioni.

Spremi al massimo le opzioni di WordPress

L'API delle opzioni di WordPress fornisce una serie di strumenti per caricare o salvare facilmente i dati. È utile per gestire piccole informazioni, per le quali altri meccanismi offerti da WordPress (come post o tassonomie) sono eccessivamente complessi.

Opzioni Wordpress ottimizzate

Ad esempio, se vogliamo memorizzare una chiave di autenticazione o il colore di sfondo dell'intestazione del nostro sito, le opzioni sono ciò che stiamo cercando.

WordPress non solo ci offre le funzioni per gestirli, ma ci consente anche di farlo nel modo più efficiente.

Alcune delle opzioni vengono persino caricate direttamente all'avvio del sistema, fornendoci così un accesso più rapido (quando si crea una nuova opzione, dobbiamo considerare se vogliamo caricarla automaticamente o meno).

Si consideri, ad esempio, un sito su cui abbiamo un carosello che mostra le ultime notizie specificate nel back-end. Il nostro primo istinto sarebbe quello di utilizzare una meta chiave per questo come segue:

 // functions.php add_action( 'save_post', function ( $post_id ) { // For simplicity, we do not include all the required validation before saving // the meta key: checking nonces, checking post type and status, checking // it is not a revision or an autosaving, etc. update_post_meta( $post_id, 'is_breaking_news', ! empty ( $_POST['is_breaking_news'] ) ); } ); // front-page.php $query = new WP_Query( array( 'posts_per_page' => 1, 'meta_key' => 'is_breaking_news' ) ); $breaking_news = $query->posts[0] ?: NULL;

Come puoi vedere, questo approccio è molto semplice, ma non è ottimale. Eseguirà una query del database cercando di trovare un post con una meta chiave specifica. Potremmo usare un'opzione per ottenere un risultato simile:

 // functions.php add_action( 'save_post', function ( $post_id ) { // Same comment for post validation if ( ! empty ( $_POST['is_breaking_news'] ) ) update_option( 'breaking_news_id', $post_id ); } ); // front-page.php if ( $breaking_news_id = get_option( 'breaking_news_id' ) ) $breaking_news = get_post( $breaking_news_id ); else $breaking_news = NULL;

La funzionalità varia leggermente da un esempio all'altro.

Nella prima parte di codice, avremo sempre le ultime notizie dell'ultima ora, in termini di data di pubblicazione del post.

Nella seconda, ogni volta che un nuovo post viene impostato come ultime notizie, sovrascriverà le ultime notizie precedenti.

Ma poiché probabilmente vogliamo un post di ultime notizie alla volta, non dovrebbe essere un problema.

E, alla fine, abbiamo cambiato una query di database pesante (usando WP_Query con meta chiavi) in una query semplice e diretta (chiamando get_post() ) che è un approccio migliore e più performante.

Potremmo anche apportare una piccola modifica e utilizzare i transitori invece delle opzioni.

I transitori funzionano in modo simile ma ci consentono di specificare un tempo di scadenza.

Ad esempio, per le ultime notizie, si adatta come un guanto perché non vogliamo un vecchio post come ultime notizie e se lasciamo il compito di modificare o eliminare quelle ultime notizie all'amministratore, [le] potrebbe dimenticare di farlo esso. Quindi, con due semplici modifiche, aggiungiamo una data di scadenza:

 // functions.php add_action( 'save_post', function ( $post_id ) { // Same comment for post validation // Let's say we want that breaking news for one hour // (3600 = # of seconds in an hour). if ( ! empty ( $_POST['is_breaking_news'] ) ) set_transient( 'breaking_news_id', $post_id, 3600 ); } ); // front-page.php if ( $breaking_news_id = get_transient( 'breaking_news_id' ) ) $breaking_news = get_post( $breaking_news_id ); else $breaking_news = NULL;

Abilita memorizzazione nella cache persistente

WordPress ha nativamente un meccanismo di memorizzazione nella cache degli oggetti.

Le opzioni, ad esempio, vengono memorizzate nella cache utilizzando quel meccanismo.

Ma, per impostazione predefinita, la memorizzazione nella cache non è persistente, il che significa che vive solo per la durata di una singola richiesta. Tutti i dati vengono memorizzati nella cache per un accesso più rapido, ma sono disponibili solo durante tale richiesta.

Illustrazione della memorizzazione nella cache persistente

Il supporto della memorizzazione nella cache persistente richiede l'installazione di un plug-in di cache persistente.

Alcuni plug-in di cache a pagina intera sono dotati di un plug-in di cache persistente incluso (ad esempio W3 Total Cache), ma altri no, e dobbiamo installarlo separatamente.

Dipenderà dall'architettura della nostra piattaforma, se utilizzeremo file, Memcached o qualche altro meccanismo per archiviare i dati memorizzati nella cache, ma dovremmo sfruttare questa straordinaria funzionalità.

Ci si potrebbe chiedere: "Se questa è una funzionalità così eccezionale, perché WordPress non la abilita per impostazione predefinita"?

Il motivo principale è che, a seconda dell'architettura della nostra piattaforma, alcune tecniche di cache funzioneranno e altre no.

Se ospitiamo il nostro sito nel nostro server distribuito, ad esempio, dovremmo utilizzare un sistema di cache esterno, (come un server Memcached), ma se il nostro sito Web risiede su un unico server, potremmo risparmiare denaro semplicemente utilizzando il file system per memorizzare nella cache.

Una cosa di cui dobbiamo tenere conto è la scadenza della cache. Questa è la trappola più comune nel lavorare con la memorizzazione nella cache persistente.

Se non risolviamo correttamente questo problema, i nostri utenti si lamenteranno che non vedranno le modifiche apportate o che le modifiche hanno impiegato troppo tempo per essere applicate.

A volte ci ritroveremo a fare compromessi tra prestazioni e dinamismo, ma anche con questi ostacoli, la memorizzazione nella cache persistente è qualcosa di cui praticamente ogni installazione di WordPress dovrebbe trarre vantaggio.

AJAX nel modo più veloce

Se dobbiamo comunicare tramite AJAX con il nostro sito Web, WordPress offre alcune atrazioni al momento dell'elaborazione della richiesta lato server.

Anche se queste tecniche possono essere utilizzate durante la programmazione di strumenti di back-end o l'invio di moduli dal front-end, dovrebbero essere evitate se non è strettamente necessario.

La ragione di ciò è che per utilizzare questi meccanismi, siamo obbligati a fare una richiesta di post a un file che si trova all'interno della cartella wp-admin . La maggior parte (se non tutti) dei plug-in di memorizzazione nella cache a pagina intera di WordPress non memorizzano nella cache le richieste di post né le chiamate ai file dell'amministratore.

Ad esempio, se carichiamo dinamicamente più post quando l'utente sta scorrendo la nostra home page, sarebbe meglio chiamare direttamente un'altra pagina front-end, che otterrà i vantaggi di essere memorizzata nella cache.

Potremmo quindi analizzare i risultati tramite JavaScript nel browser.

Sì, stiamo inviando più dati del necessario, ma stiamo vincendo in termini di velocità di elaborazione e tempo di risposta.

Distruggi l'idea che WordPress sia solo lento

Questi sono solo alcuni consigli che gli sviluppatori dovrebbero prendere in considerazione durante la programmazione per WordPress.

A volte, dimentichiamo che il nostro plugin o tema potrebbe dover convivere con altri plugin o che il nostro sito potrebbe essere servito da una società di hosting che serve centinaia o migliaia di altri siti con un database comune.

Ci concentriamo solo su come dovrebbe funzionare il plug-in e non su come gestisce quella funzionalità o su come farlo in modo efficiente.

Da quanto sopra, è chiaro che le cause principali delle scarse prestazioni in WordPress sono codice cattivo e inefficiente. Tuttavia, WordPress fornisce tutte le funzionalità necessarie attraverso le sue varie API che possono aiutarci a creare plugin e temi molto più performanti senza compromettere la velocità della piattaforma complessiva.