Başsız WordPress: Ayrılmış Bir WordPress Oluşturmanın İniş ve Düşüşleri

Yayınlanan: 2022-03-10
Kısa özet ↬ Bir web sitesi yavaşsa, kullanıcıların onu terk edeceğini herkes bilir. Birçok çalışma, web sitesi performansı ve dönüşüm oranları arasındaki bağlantıyı göstermektedir. Bu makalede Denis Zoljom, deneyimini ve ayrıştırılmış bir WordPress oluşturmanın temellerini paylaşıyor.

WordPress, başlangıcından beri basit bir blog yazma aracı olarak çok yol kat etti. Uzun bir 15 yıl sonra hem geliştiriciler hem de geliştirici olmayanlar için bir numaralı CMS seçimi oldu. WordPress artık web'deki en iyi 10 milyon sitenin yaklaşık %30'una güç sağlıyor.

REST API, WordPress çekirdeğinde paketlendiğinden beri, geliştiriciler bunu ayrıştırılmış bir şekilde deneyebilir ve kullanabilir, yani JavaScript çerçevelerini veya kitaplıklarını kullanarak ön uç kısmını yazabilir. Infinum'da WordPress'i 'klasik' bir şekilde kullanıyorduk (ve hala kullanıyoruz): PHP ön uç için olduğu kadar arka uç için de. Bir süre sonra, ayrıştırılmış yaklaşıma bir şans vermek istedik. Bu yazıda, neyi başarmak istediğimizi ve hedeflerimizi uygulamaya çalışırken nelerle karşılaştığımızı özetleyeceğim.

Bu yaklaşımdan yararlanabilecek çeşitli proje türleri vardır. Örneğin, arka uç olarak WordPress kullanan basit sunum siteleri veya siteler, ayrıştırılmış yaklaşımın ana adaylarıdır.

Son yıllarda, sektör neyse ki performansa daha fazla dikkat etmeye başladı. Bununla birlikte, kullanımı kolay, kapsayıcı ve çok yönlü bir yazılım parçası olan WordPress, her projede mutlaka kullanılması gerekmeyen çok sayıda seçenek ile birlikte gelir. Sonuç olarak, web sitesi performansı düşebilir.

Önerilen okuma : WordPress Web Sitenizdeki Tıklamaları İzlemek İçin Isı Haritaları Nasıl Kullanılır

Uzun web sitesi yanıt süreleri sizi geceleri ayakta tutuyorsa, bu sizin için bir nasıl yapılır. Ayrıştırılmış bir WordPress oluşturmanın temellerini ve aşağıdakiler de dahil olmak üzere alınan bazı dersleri ele alacağım:

  1. “Ayrıştırılmış WordPress”in anlamı
  2. Varsayılan WordPress REST API ile çalışma
  3. Ayrılmış JSON yaklaşımıyla performansı iyileştirme
  4. Güvenlik endişeleri
Atlamadan sonra daha fazlası! Aşağıdan okumaya devam edin ↓

Peki, Ayrılmış WordPress Tam Olarak Nedir?

WordPress'in nasıl programlandığına gelince, kesin olan bir şey var: Birçok geliştiricinin aşina olduğu Model Görünümü Kontrolörü ( MVC ) tasarım modelini takip etmiyor . Geçmişi ve “b2” adlı eski bir blog platformunun bir tür çatalı olması nedeniyle (daha fazla ayrıntı burada), büyük ölçüde prosedürel bir şekilde (işlev tabanlı kod kullanılarak) yazılmıştır. WordPress çekirdek geliştiricileri, diğer geliştiricilerin belirli işlevleri değiştirmesine veya genişletmesine izin veren bir kanca sistemi kullandı.

Çalışan bir yönetici arayüzü ile donatılmış hepsi bir arada bir sistemdir; veritabanı bağlantısını yönetir ve kullanıcı kimlik doğrulamasını, yönlendirmeyi ve daha fazlasını işleyen bir dizi kullanışlı API'ye sahiptir.

Ancak REST API sayesinde, WordPress arka ucunu, veri işlemeyi ve veritabanı etkileşimini yöneten bir arada paketlenmiş bir tür model ve denetleyici olarak ayırabilir ve çeşitli API uç noktalarını kullanarak ayrı bir görünüm katmanıyla etkileşim kurmak için REST API Denetleyicisini kullanabilirsiniz. MVC ayrımına ek olarak, (güvenlik nedenleriyle veya hız iyileştirmeleri nedeniyle) JS Uygulamasını aşağıdaki şemada olduğu gibi ayrı bir sunucuya yerleştirebiliriz:

PHP ve JS kısmı ayrılmış olarak ayrılmış WordPress diyagramını gösteren resim
Ayrılmış WordPress diyagramı. (Büyük önizleme)

Ayrık Yaklaşımı Kullanmanın Avantajları

Bu yaklaşımı kullanmak isteyebileceğiniz bir şey, endişelerin ayrılmasını sağlamaktır. Ön uç ve arka uç, uç noktalar aracılığıyla etkileşime girer; her biri, her bir ilgili görev için özel olarak optimize edilebilen, yani ayrı ayrı bir PHP uygulamasını ve bir Node.js uygulamasını çalıştıran kendi ayrı sunucusunda olabilir.

Ön ucunuzu arka uçtan ayırarak, gelecekte CMS'yi değiştirmeden yeniden tasarlamak daha kolaydır. Ayrıca, ön uç geliştiricilerin yalnızca arka ucun onlara sağladığı verilerle ne yapacaklarına dikkat etmesi gerekir. Bu, yaratıcı olmalarını ve son derece dinamik web uygulamaları sunmak için ReactJS, Vue veya Angular gibi modern kitaplıkları kullanmalarını sağlar. Örneğin, yukarıda belirtilen kitaplıkları kullanırken aşamalı bir web uygulaması oluşturmak daha kolaydır.

Diğer bir avantaj, web sitesi güvenliğine yansır. Web sitesini arka uç aracılığıyla kullanmak, büyük ölçüde halktan gizlendiğinden daha zor hale gelir.

Önerilen okuma : Bir Süreç Olarak WordPress Güvenliği

Dekuplajlı Yaklaşımı Kullanmanın Eksiklikleri

İlk olarak, ayrılmış bir WordPress'e sahip olmak, iki ayrı örneği korumak anlamına gelir:

  1. Arka uç için WordPress;
  2. Zamanında güvenlik güncellemeleri de dahil olmak üzere ayrı bir ön uç uygulaması.

İkincisi, bazı ön uç kitaplıkların daha dik bir öğrenme eğrisi vardır. Yeni bir dil öğrenmek ya çok zaman alacak (eğer şablon oluşturmak için yalnızca HTML ve CSS'ye alışkınsanız) ya da projeye ek JavaScript uzmanları getirmeyi gerektirecektir.

Üçüncüsü, ön ucu ayırarak WYSIWYG düzenleyicisinin gücünü kaybediyorsunuz ve WordPress'teki 'Canlı Önizleme' düğmesi de çalışmıyor.

WordPress REST API ile Çalışmak

Kodu derinlemesine incelemeden önce, WordPress REST API hakkında birkaç şey daha var. WordPress'teki REST API'nin tam gücü, 6 Aralık 2016'da 4.7 sürümüyle geldi.

WordPress REST API'nin yapmanıza izin verdiği şey, JSON nesneleri gönderip alarak WordPress kurulumunuzla uzaktan etkileşimde bulunmaktır.

Proje Oluşturma

En son WordPress kurulumuyla birlikte geldiği için Yirmi Onyedi teması üzerinde çalışacağız. Varying Vagrant Vagrants üzerinde çalışıyorum ve https://dev.wordpress.test/ URL'sine sahip bir test sitesi kurdum. Bu URL makale boyunca kullanılacaktır. Ayrıca, üzerinde çalışabileceğimiz bazı test verilerimiz olması için wordpress.org Tema İnceleme Ekipleri deposundan gönderileri içe aktaracağız. Ancak önce varsayılan uç noktalarla çalışmaya alışacağız ve ardından kendi özel uç noktamızı oluşturacağız.

Varsayılan REST Uç Noktasına Erişin

Daha önce de belirtildiği gibi, WordPress, /wp-json/ yoluna giderek inceleyebileceğiniz birkaç yerleşik uç nokta ile birlikte gelir:

 https://dev.wordpress.test/wp-json/

Bu URL'yi doğrudan tarayıcınıza koyarak veya postacı uygulamasına ekleyerek, WordPress REST API'sinden şuna benzeyen bir JSON yanıtı alırsınız:

 { "name": "Test dev site", "description": "Just another WordPress site", "url": "https://dev.wordpress.test", "home": "https://dev.wordpress.test", "gmt_offset": "0", "timezone_string": "", "namespaces": [ "oembed/1.0", "wp/v2" ], "authentication": [], "routes": { "/": { "namespace": "", "methods": [ "GET" ], "endpoints": [ { "methods": [ "GET" ], "args": { "context": { "required": false, "default": "view" } } } ], "_links": { "self": "https://dev.wordpress.test/wp-json/" } }, "/oembed/1.0": { "namespace": "oembed/1.0", "methods": [ "GET" ], "endpoints": [ { "methods": [ "GET" ], "args": { "namespace": { "required": false, "default": "oembed/1.0" }, "context": { "required": false, "default": "view" } } } ], "_links": { "self": "https://dev.wordpress.test/wp-json/oembed/1.0" } }, ... "wp/v2": { ...

Bu yüzden sitemizdeki tüm gönderileri REST kullanarak alabilmek için https://dev.wordpress.test/wp-json/wp/v2/posts adresine gitmemiz gerekecek. wp/v2/ gönderiler, sayfalar, medya, sınıflandırmalar, kategoriler vb. gibi ayrılmış temel uç noktaları işaretlediğine dikkat edin.

Peki, özel bir uç noktayı nasıl ekleyeceğiz?

Özel Bir REST Uç Noktası Oluşturun

Mevcut uç noktaya yeni bir uç nokta veya ek alan eklemek istediğimizi varsayalım. Bunu yapmamızın birkaç yolu var. İlk olarak, özel bir gönderi türü oluştururken otomatik olarak yapılabilir. Örneğin, bir dokümantasyon bitiş noktası oluşturmak istiyoruz. Küçük bir test eklentisi oluşturalım. wp-content/plugins klasöründe bir test-documentation klasörü oluşturun ve aşağıdaki gibi görünen document.php dosyasını ekleyin:

 <?php /** * Test plugin * * @since 1.0.0 * @package test_plugin * * @wordpress-plugin * Plugin Name: Test Documentation Plugin * Plugin URI: * Description: The test plugin that adds rest functionality * Version: 1.0.0 * Author: Infinum <[email protected]> * Author URI: https://infinum.co/ * License: GPL-2.0+ * License URI: https://www.gnu.org/licenses/gpl-2.0.txt * Text Domain: test-plugin */ namespace Test_Plugin; // If this file is called directly, abort. if ( ! defined( 'WPINC' ) ) { die; } /** * Class that holds all the necessary functionality for the * documentation custom post type * * @since 1.0.0 */ class Documentation { /** * The custom post type slug * * @var string * * @since 1.0.0 */ const PLUGIN_NAME = 'documentation-plugin'; /** * The custom post type slug * * @var string * * @since 1.0.0 */ const POST_TYPE_SLUG = 'documentation'; /** * The custom taxonomy type slug * * @var string * * @since 1.0.0 */ const TAXONOMY_SLUG = 'documentation-category'; /** * Register custom post type * * @since 1.0.0 */ public function register_post_type() { $args = array( 'label' => esc_html( 'Documentation', 'test-plugin' ), 'public' => true, 'menu_position' => 47, 'menu_icon' => 'dashicons-book', 'supports' => array( 'title', 'editor', 'revisions', 'thumbnail' ), 'has_archive' => false, 'show_in_rest' => true, 'publicly_queryable' => false, ); register_post_type( self::POST_TYPE_SLUG, $args ); } /** * Register custom tag taxonomy * * @since 1.0.0 */ public function register_taxonomy() { $args = array( 'hierarchical' => false, 'label' => esc_html( 'Documentation tags', 'test-plugin' ), 'show_ui' => true, 'show_admin_column' => true, 'update_count_callback' => '_update_post_term_count', 'show_in_rest' => true, 'query_var' => true, ); register_taxonomy( self::TAXONOMY_SLUG, [ self::POST_TYPE_SLUG ], $args ); } } $documentation = new Documentation(); add_action( 'init', [ $documentation, 'register_post_type' ] ); add_action( 'init', [ $documentation, 'register_taxonomy' ] );

WordPress, yeni gönderi türünü ve sınıflandırmayı kaydederek ve show_in_rest bağımsız değişkenini true olarak ayarlayarak, /wp/v2/ ad alanında otomatik olarak bir REST yolu oluşturdu. Artık https://dev.wordpress.test/wp-json/wp/v2/documentation ve https://dev.wordpress.test/wp-json/wp/v2/documentation-category uç noktalarınız var. Yeni oluşturduğumuz dokümantasyon özel https://dev.wordpress.test/?post_type=documentation giden bir yazı eklersek, bize şuna benzeyen bir yanıt verecektir:

 [ { "id": 4, "date": "2018-06-11T19:48:51", "date_gmt": "2018-06-11T19:48:51", "guid": { "rendered": "https://dev.wordpress.test/?post_type=documentation&p=4" }, "modified": "2018-06-11T19:48:51", "modified_gmt": "2018-06-11T19:48:51", "slug": "test-documentation", "status": "publish", "type": "documentation", "link": "https://dev.wordpress.test/documentation/test-documentation/", "title": { "rendered": "Test documentation" }, "content": { "rendered": "

Bu, bazı dokümantasyon içeriğidir

\n", "korumalı": yanlış }, "özellikli_medya": 0, "şablon": "", "belgeleme kategorisi": [ 2 ], "_bağlantılar": { "kendi": [ { "href": "https://dev.wordpress.test/wp-json/wp/v2/documentation/4" } ], "Toplamak": [ { "href": "https://dev.wordpress.test/wp-json/wp/v2/documentation" } ], "hakkında": [ { "href": "https://dev.wordpress.test/wp-json/wp/v2/types/documentation" } ], "sürüm geçmişi": [ { "href": "https://dev.wordpress.test/wp-json/wp/v2/documentation/4/revisions" } ], "wp:ek": [ { "href": "https://dev.wordpress.test/wp-json/wp/v2/media?parent=4" } ], "wp: terim": [ { "taksonomi": "belgeleme kategorisi", "yerleştirilebilir": doğru, "href": "https://dev.wordpress.test/wp-json/wp/v2/documentation-category?post=4" } ], "küriler": [ { "isim": "wp", "href": "https://api.w.org/{rel}", "şablonlu": doğru } ] } } ]

Bu, tek sayfalık uygulamamız için harika bir başlangıç ​​noktasıdır. Özel bir uç nokta eklemenin başka bir yolu da rest_api_init kancasına takıp kendimiz bir uç nokta oluşturmaktır. Kaydettiğimizden biraz farklı bir custom-documentation rotası ekleyelim. Hala aynı eklentide çalışıyoruz, şunları ekleyebiliriz:

 /** * Create a custom endpoint * * @since 1.0.0 */ public function create_custom_documentation_endpoint() { register_rest_route( self::PLUGIN_NAME . '/v1', '/custom-documentation', array( 'methods' => 'GET', 'callback' => [ $this, 'get_custom_documentation' ], ) ); } /** * Create a callback for the custom documentation endpoint * * @return string JSON that indicates success/failure of the update, * or JSON that indicates an error occurred. * @since 1.0.0 */ public function get_custom_documentation() { /* Some permission checks can be added here. */ // Return only documentation name and tag name. $doc_args = array( 'post_type' => self::POST_TYPE_SLUG, 'post_status' => 'publish', 'perm' => 'readable' ); $query = new \WP_Query( $doc_args ); $response = []; $counter = 0; // The Loop if ( $query->have_posts() ) { while ( $query->have_posts() ) { $query->the_post(); $post_id = get_the_ID(); $post_tags = get_the_terms( $post_id, self::TAXONOMY_SLUG ); $response[ $counter ]['title'] = get_the_title(); foreach ( $post_tags as $tags_key => $tags_value ) { $response[ $counter ]['tags'][] = $tags_value->name; } $counter++; } } else { $response = esc_html__( 'There are no posts.', 'documentation-plugin' ); } /* Restore original Post Data */ wp_reset_postdata(); return rest_ensure_response( $response ); }

Ve create_custom_documentation_endpoint() yöntemini rest_api_init kancasına şu şekilde bağlayın:

 add_action( 'rest_api_init', [ $documentation, 'create_custom_documentation_endpoint' ] );

Bu, https://dev.wordpress.test/wp-json/documentation-plugin/v1/custom-documentation özel bir rota ekler ve geri arama bu rota için yanıtı döndürür.

 [{ "title": "Another test documentation", "tags": ["Another tag"] }, { "title": "Test documentation", "tags": ["REST API", "test tag"] }]

REST API ile yapabileceğiniz birçok başka şey vardır (daha fazla ayrıntıyı REST API el kitabında bulabilirsiniz).

Varsayılan REST API'sini Kullanırken Uzun Yanıt Sürelerinde Çalışma

Ayrılmış bir WordPress sitesi oluşturmaya çalışan herkes için bu yeni bir şey değil – REST API yavaş.

Ekibim ve ben ilk olarak, Advanced Custom Fields Pro kullanılarak oluşturulan diğer meta bilgilerin yanı sıra bir Google haritasındaki konumların listesini almak için özel uç noktaları kullandığımız bir istemci sitesinde (ayrışmamış) garip WordPress gecikmeli REST API ile karşılaştık. Eklenti. Bir web sunucusunun veya başka bir ağ kaynağının yanıt verme hızının bir göstergesi olarak kullanılan ilk baytın (TTFB) süresinin 3 saniyeden fazla sürdüğü ortaya çıktı.

Biraz araştırma yaptıktan sonra, özellikle siteyi ek eklentilerle "yüklediğimizde" varsayılan REST API çağrılarının gerçekten yavaş olduğunu fark ettik. Bu yüzden küçük bir test yaptık. Birkaç popüler eklenti yükledik ve bazı ilginç sonuçlarla karşılaştık. Postacı uygulaması, 41,9KB yanıt boyutu için 1,97 saniyelik yükleme süresi verdi. Chrome'un yükleme süresi 1,25 saniyeydi (TTFB 1,25 saniyeydi, içerik 3,96 ms'de indirildi). Sadece basit bir gönderi listesi almak için. Taksonomi yok, kullanıcı verisi yok, ek meta alan yok.

Bu neden oldu?

Varsayılan WordPress'te REST API'ye erişmenin, kullanılmasa bile uç noktalara hizmet etmek için tüm WordPress çekirdeğini yükleyeceği ortaya çıktı. Ayrıca ne kadar çok eklenti eklerseniz işler o kadar kötüleşir. Varsayılan REST denetleyicisi WP_REST_Controller , basit bir web sayfası oluştururken gerekenden çok daha fazlasını yapan gerçekten büyük bir sınıftır. Rotaların kaydedilmesi, izin kontrolleri, öğelerin oluşturulması ve silinmesi vb. işlemleri gerçekleştirir.

Bu sorun için iki yaygın geçici çözüm vardır:

  1. Eklentilerin yüklenmesini durdurun ve basit bir REST yanıtı vermeniz gerektiğinde tümünün yüklenmesini önleyin;
  2. Yalnızca minimum WordPress'i yükleyin ve verileri, daha sonra özel bir sayfa kullanarak verileri alacağımız bir geçici durumda saklayın.

Ayrıştırılmış JSON Yaklaşımıyla Performansı Artırma

Basit sunum siteleriyle çalışırken, REST API'nin size sunduğu tüm işlevselliklere ihtiyacınız yoktur. Tabii ki, burada iyi bir planlama çok önemlidir. Gerçekten sitenizi REST API olmadan oluşturmak ve ardından bir yıl sonra sitenize bağlanmak istediğinizi söylemek veya REST API işlevini kullanması gereken bir mobil uygulama oluşturmak istemezsiniz. Öyle mi?

Bu nedenle, basit JSON verilerini dışarı sunarken size yardımcı olabilecek iki WordPress özelliği kullandık:

  • Önbelleğe alma için geçici API,
  • SHORTINIT sabitini kullanarak gerekli minimum WordPress yükleniyor.

Basit Bir Ayrılmış Sayfa Uç Noktası Oluşturma

Bahsettiğimiz etkiyi gösterecek küçük bir eklenti oluşturalım. İlk olarak, json-transient eklentinize şuna benzeyen bir wp-config-simple.php dosyası ekleyin:

 <?php /** * Create simple wp configuration for the routes * * @since 1.0.0 * @package json-transient */ define( 'SHORTINIT', true ); $parse_uri = explode( 'wp-content', $_SERVER['SCRIPT_FILENAME'] ); require_once filter_var( $parse_uri[0] . 'wp-load.php', FILTER_SANITIZE_STRING );

define( 'SHORTINIT', true ); wp-settings.php dosyasında görülebileceği gibi, WordPress çekirdek dosyalarının çoğunun yüklenmesini önleyecektir.

Yine de bazı WordPress işlevlerine ihtiyacımız olabilir, bu nedenle dosyayı ( wp-load.php gibi) manuel olarak talep edebiliriz. wp-load.php WordPress kurulumumuzun kökünde bulunduğundan, onu $_SERVER['SCRIPT_FILENAME'] kullanarak dosyamızın yolunu alarak ve sonra wp-content string ile bu stringi patlatarak alacağız. Bu, iki değer içeren bir dizi döndürür:

  1. Kurulumumuzun kökü;
  2. Dosya yolunun geri kalanı (ki bizi ilgilendirmiyor).

WordPress'in varsayılan kurulumunu kullandığımızı ve örneğin WordPress'i farklı bir dosya organizasyonunda bölen Bedrock ortak metninde olduğu gibi değiştirilmiş bir kurulum kullanmadığımızı unutmayın.

Son olarak, güvenlik için wp-load.php dosyasına biraz temizlikle ihtiyacımız var.

init.php dosyamıza aşağıdakileri ekleyeceğiz:

* Author URI: https://infinum.co/ * License: GPL-2.0+ * License URI: https://www.gnu.org/licenses/gpl-2.0.txt * Text Domain: json-transient */ namespace Json_Transient; // If this file is called directly, abort. if ( ! defined( 'WPINC' ) ) { die; } class Init { /** * Get the array of allowed types to do operations on. * * @return array * * @since 1.0.0 */ public function get_allowed_post_types() { return array( 'post', 'page' ); } /** * Check if post type is allowed to be save in transient. * * @param string $post_type Get post type. * @return boolean * * @since 1.0.0 */ public function is_post_type_allowed_to_save( $post_type = null ) { if( ! $post_type ) { return false; } $allowed_types = $this->get_allowed_post_types(); if ( in_array( $post_type, $allowed_types, true ) ) { return true; } return false; } /** * Get Page cache name for transient by post slug and type. * * @param string $post_slug Page Slug to save. * @param string $post_type Page Type to save. * @return string * * @since 1.0.0 */ public function get_page_cache_name_by_slug( $post_slug = null, $post_type = null ) { if( ! $post_slug || ! $post_type ) { return false; } $post_slug = str_replace( '__trashed', '', $post_slug ); return 'jt_data_' . $post_type . '_' . $post_slug; } /** * Get full post data by post slug and type. * * @param string $post_slug Page Slug to do Query by. * @param string $post_type Page Type to do Query by. * @return array * * @since 1.0.0 */ public function get_page_data_by_slug( $post_slug = null, $post_type = null ) { if( ! $post_slug || ! $post_type ) { return false; } $page_output = ''; $args = array( 'name' => $post_slug, 'post_type' => $post_type, 'posts_per_page' => 1, 'no_found_rows' => true ); $the_query = new \WP_Query( $args ); if ( $the_query->have_posts() ) { while ( $the_query->have_posts() ) { $the_query->the_post(); $page_output = $the_query->post; } wp_reset_postdata(); } return $page_output; } /** * Return Page in JSON format * * @param string $post_slug Page Slug. * @param string $post_type Page Type. * @return json * * @since 1.0.0 */ public function get_json_page( $post_slug = null, $post_type = null ) { if( ! $post_slug || ! $post_type ) { return false; } return wp_json_encode( $this->get_page_data_by_slug( $post_slug, $post_type ) ); } /** * Update Page to transient for caching on action hooks save_post. * * @param int $post_id Saved Post ID provided by action hook. * * @since 1.0.0 */ public function update_page_transient( $post_id ) { $post_status = get_post_status( $post_id ); $post = get_post( $post_id ); $post_slug = $post->post_name; $post_type = $post->post_type; $cache_name = $this->get_page_cache_name_by_slug( $post_slug, $post_type ); if( ! $cache_name ) { return false; } if( $post_status === 'auto-draft' || $post_status === 'inherit' ) { return false; } else if( $post_status === 'trash' ) { delete_transient( $cache_name ); } else { if( $this->is_post_type_allowed_to_save( $post_type ) ) { $cache = $this->get_json_page( $post_slug, $post_type ); set_transient( $cache_name, $cache, 0 ); } } } } $init = new Init(); add_action( 'save_post', [ $init, 'update_page_transient' ] );

Yukarıdaki koddaki yardımcı yöntemler, bazı önbellekleme yapmamızı sağlayacaktır:

  • get_allowed_post_types()
    Bu yöntem, gönderi türlerinin özel 'uç noktamızda' göstermeyi etkinleştirmek istediğimizi bilmesini sağlar. Bunu ve eklentiyi genişletebilirsiniz, aslında bu yöntemi filtrelenebilir hale getirdik, böylece ek öğeler eklemek için bir filtre kullanabilirsiniz.
  • is_post_type_allowed_to_save()
    Bu yöntem, verileri almaya çalıştığımız gönderi türünün önceki yöntemle belirtilen izin verilen dizide olup olmadığını kontrol eder.
  • get_page_cache_name_by_slug()
    Bu yöntem, verilerin getirileceği geçici olayın adını döndürür.
  • get_page_data_by_slug()
    Bu yöntem, gönderi üzerinde WP_Query slug ve gönderi türü aracılığıyla gerçekleştirecek ve get_json_page() yöntemini kullanarak JSON ile dönüştüreceğimiz gönderi dizisinin içeriğini döndürecek yöntemdir.
  • update_page_transient()
    Bu, save_post kancasında çalıştırılacak ve veri tabanındaki geçici olayın üzerine yazımızın JSON verileriyle yazılacaktır. Bu son yöntem “anahtar önbelleğe alma yöntemi” olarak bilinir.

Geçici olayları daha derinlemesine açıklayalım.

Geçici Olaylar API'sı

Transients API, verileri belirli bir süre için WordPress veritabanınızın seçenekler tablosunda depolamak için kullanılır. Bu kalıcı bir nesne önbelleğidir, yani bazı nesneleri, örneğin büyük ve yavaş sorguların sonuçlarını veya sayfa yüklemeleri boyunca kalıcı olabilen tam sayfaların sonuçlarını depoladığınız anlamına gelir. Normal WordPress Nesne Önbelleğine benzer, ancak WP_Cache farklı olarak, geçici olaylar verileri sayfa yüklemeleri boyunca sürdürür, burada WP_Cache (verileri bellekte saklar) verileri yalnızca bir istek süresi boyunca tutar.

Bu bir anahtar/değer deposudur, yani Memcached veya Redis gibi in-memory caching systems yaptığına benzer şekilde, istenen verileri kolay ve hızlı bir şekilde getirebiliriz. Aradaki fark, bunları genellikle sunucuya ayrı olarak yüklemeniz gerekmesidir (bu, paylaşılan sunucularda bir sorun olabilir), oysa geçici olaylar WordPress'te yerleşiktir.

Codex sayfasında belirtildiği gibi - geçici olaylar, eklentileri önbelleğe alarak doğal olarak hızlandırılır. Geçici olayları bir veritabanı yerine bellekte depolayabildikleri için. Genel kural, geçici durumun her zaman veritabanında bulunduğunu varsaymamanız gerektiğidir - bu nedenle, onu getirmeden önce varlığını kontrol etmek iyi bir uygulamadır.

 $transient_name = get_transient( 'transient_name' ); if ( $transient_name === false ) { set_transient( 'transient_name', $transient_data, $transient_expiry ); }

Süresi dolmadan kullanabilirsiniz (bizim yaptığımız gibi) ve bu yüzden kayıt sonrası bir tür 'önbellek bozma' uyguladık. Sağladıkları tüm harika işlevselliklere ek olarak, içinde 4 GB'a kadar veri tutabilirler, ancak bu kadar büyük bir şeyi tek bir veritabanı alanında saklamanızı önermiyoruz.

Önerilen okuma : Dikkatli Olun: Sitenizi Güvensiz Hale Getirebilecek PHP ve WordPress İşlevleri

Nihai Uç Nokta: Test Etme ve Doğrulama

İhtiyacımız olan bulmacanın son parçası bir 'bitiş noktası'. Sonuçlarımızı almak için doğrudan belirli bir dosyayı çağırdığımız için bir uç nokta olmasa da burada uç nokta terimini kullanıyorum. Böylece şuna benzeyen bir test.php dosyası oluşturabiliriz:

 get_page_cache_name_by_slug( $post_slug, $post_type ) ); // Return error on false. if ( $cache === false ) { wp_send_json( 'Error, the page does not exist or it is not cached correctly. Please try rebuilding cache and try again!' ); } // Decode json for output. wp_send_json( json_decode( $cache ) );

https://dev.wordpress.test/wp-content/plugins/json-transient/test.php şu mesajı görürüz:

Hata, sayfa bilgisi veya türü eksik!

Bu nedenle, gönderi türünü ve gönderi bilgisini belirtmemiz gerekecek. Şimdi https://dev.wordpress.test/wp-content/plugins/json-transient/test.php?slug=hello-world&type=post adresine gittiğimizde şunu göreceğiz:

Hata, sayfa mevcut değil veya doğru şekilde önbelleğe alınmadı. Lütfen önbelleği yeniden oluşturmayı deneyin ve tekrar deneyin!

Bekle! Önce sayfalarımızı ve gönderilerimizi yeniden kaydetmemiz gerekiyor. Yani başladığınızda, bu kolay olabilir. Ancak zaten 100'den fazla sayfanız veya yayınınız varsa, bu zorlu bir görev olabilir. Bu nedenle, Ayrılmış JSON İçeriği eklentisindeki geçici olayları temizlemenin ve bunları toplu olarak yeniden oluşturmanın bir yolunu uyguladık.

Ancak devam edin ve Hello World gönderisini yeniden kaydedin ve ardından bağlantıyı tekrar açın. Şimdi sahip olmanız gereken şuna benzeyen bir şey:

 { "ID": 1, "post_author": "1", "post_date": "2018-06-26 18:28:57", "post_date_gmt": "2018-06-26 18:28:57", "post_content": "Welcome to WordPress. This is your first post. Edit or delete it, then start writing!", "post_title": "Hello world!", "post_excerpt": "", "post_status": "publish", "comment_status": "open", "ping_status": "open", "post_password": "", "post_name": "hello-world", "to_ping": "", "pinged": "", "post_modified": "2018-06-30 08:34:52", "post_modified_gmt": "2018-06-30 08:34:52", "post_content_filtered": "", "post_parent": 0, "guid": "http:\/\/dev.wordpress.test\/?p=1", "menu_order": 0, "post_type": "post", "post_mime_type": "", "comment_count": "1", "filter": "raw" }

Ve bu kadar. Yaptığımız eklenti, kullanabileceğiniz bazı ekstra işlevlere sahiptir, ancak kısaca, JSON verilerini WordPress'inizden REST API kullanmaktan çok daha hızlı bir şekilde bu şekilde alabilirsiniz.

Öncesi ve Sonrası: İyileştirilmiş Tepki Süresi

Toplam yanıt süresini ve TTFB'yi ayrı ayrı görebileceğimiz Chrome'da testler yaptık. Yanıt sürelerini arka arkaya on kez test ettik: önce eklentiler olmadan ve ardından eklentiler eklenerek. Ayrıca, bir gönderi listesi ve tek bir gönderi için yanıtı test ettik.

Testin sonuçları aşağıdaki tablolarda gösterilmektedir:

Eklenen eklentiler olmadan ayrıştırılmış yaklaşımı kullanmaya karşı WordPress REST API kullanmanın yanıt sürelerini gösteren karşılaştırma grafiği. Ayrılmış yaklaşım 2 ila 3 kat daha hızlıdır
Eklenen eklentiler olmadan ayrıştırılmış yaklaşımı kullanmaya karşı WordPress REST API kullanmanın yanıt sürelerini gösteren karşılaştırma grafiği. Ayrılmış yaklaşım 2 ila 3 kat daha hızlıdır. (Büyük önizleme)
Eklenen eklentilerle ayrılmış yaklaşımı kullanmaya karşı WordPress REST API kullanmanın yanıt sürelerini gösteren karşılaştırma grafiği. Ayrılmış yaklaşım 8 kata kadar daha hızlıdır.
Eklenen eklentilerle ayrılmış yaklaşımı kullanmaya karşı WordPress REST API kullanmanın yanıt sürelerini gösteren karşılaştırma grafiği. Ayrılmış yaklaşım 8 kata kadar daha hızlıdır. (Büyük önizleme)

Gördüğünüz gibi, fark ciddi.

Güvenlik endişeleri

İyice incelemeniz gereken bazı uyarılar var. Her şeyden önce, WordPress dünyasında büyük bir hayır-hayır olan WordPress çekirdek dosyalarını manuel olarak yüklüyoruz. Niye ya? Çekirdek dosyaları manuel olarak getirmenin yanıltıcı olabilmesinin yanı sıra (özellikle Bedrock gibi standart olmayan kurulumlar kullanıyorsanız), bazı güvenlik endişeleri doğurabilir.

Bu makalede açıklanan yöntemi kullanmaya karar verirseniz, sunucu güvenliğinizi nasıl güçlendireceğinizi bildiğinizden emin olun.

İlk olarak, test.php dosyasındaki gibi HTML başlıklarını ekleyin:

 header( 'Access-Control-Allow-Origin: your-front-end-app.url' ); header( 'Content-Type: application/json' );

İlk başlık, belirtilen dosyaya giderken yalnızca ön uç uygulamanızın içeriği alabilmesi için CORS güvenlik önlemini atlamanın bir yoludur.

İkinci olarak, uygulamanızın dizin geçişini devre dışı bırakın. Bunu, nginx ayarlarını değiştirerek veya bir Apache sunucusundaysanız .htaccess dosyanıza Options -Indexes - Dizinler ekleyerek yapabilirsiniz.

Yanıta bir belirteç denetimi eklemek de istenmeyen erişimi engelleyebilecek iyi bir önlemdir. Aslında, bu güvenlik önlemlerini varsayılan olarak dahil edebilmemiz için Ayrılmış JSON eklentimizi değiştirmenin bir yolu üzerinde çalışıyoruz.

Ön uç uygulaması tarafından gönderilen bir Yetkilendirme başlığı kontrolü şöyle görünebilir:

 if ( ! isset( $_SERVER['HTTP_AUTHORIZATION'] ) ) { return; } $auth_header = $_SERVER['HTTP_AUTHORIZATION'];

Ardından, belirli belirtecin (yalnızca ön ve arka uç uygulamalar tarafından paylaşılan bir sır) sağlanmış ve doğru olup olmadığını kontrol edebilirsiniz.

Çözüm

REST API harikadır, çünkü tam teşekküllü uygulamalar oluşturmak için kullanılabilir - verileri oluşturmak, almak, güncellemek ve silmek. Kullanmanın dezavantajı hızıdır.

Açıkçası, bir uygulama oluşturmak, klasik bir web sitesi oluşturmaktan farklıdır. Muhtemelen yüklediğimiz tüm eklentilere ihtiyacınız olmayacak. Ancak verilere yalnızca sunum amacıyla ihtiyacınız varsa, verileri önbelleğe almak ve özel bir dosyada sunmak şu anda ayrıştırılmış sitelerle çalışırken mükemmel bir çözüm gibi görünüyor.

Web sitesi yanıt süresini hızlandırmak için özel bir eklenti oluşturmanın aşırıya kaçtığını düşünüyor olabilirsiniz, ancak her saniyenin önemli olduğu bir dünyada yaşıyoruz. Herkes, bir web sitesi yavaşsa, kullanıcıların onu terk edeceğini bilir. Web sitesi performansı ve dönüşüm oranları arasındaki bağlantıyı gösteren birçok çalışma var. Ancak yine de ikna etmeye ihtiyacınız varsa, Google yavaş web sitelerini cezalandırır.

Bu makalede açıklanan yöntem, WordPress REST API'sinin karşılaştığı hız sorununu çözer ve ayrıştırılmış bir WordPress projesi üzerinde çalışırken size ekstra destek sağlar. Her istek ve yanıttan o son milisaniyeyi çıkarmak için hiç bitmeyen arayışımızdayken, eklentiyi daha da optimize etmeyi planlıyoruz. Bu arada, lütfen ayrıştırılmış WordPress'i hızlandırma konusundaki fikirlerinizi paylaşın!