WordPress Tanpa Kepala: Pasang surut Membuat WordPress Terpisah
Diterbitkan: 2022-03-10WordPress datang jauh dari awal sebagai alat menulis blog sederhana. 15 tahun kemudian menjadi pilihan CMS nomor satu untuk pengembang dan non-pengembang. WordPress sekarang mendukung sekitar 30% dari 10 juta situs teratas di web.
Sejak REST API dibundel dalam inti WordPress, pengembang dapat bereksperimen dan menggunakannya dengan cara yang terpisah, yaitu menulis bagian front-end dengan menggunakan kerangka kerja atau pustaka JavaScript. Di Infinum, kami (dan masih) menggunakan WordPress dengan cara 'klasik': PHP untuk frontend dan juga backend. Setelah beberapa saat, kami ingin mencoba pendekatan yang dipisahkan. Dalam artikel ini, saya akan membagikan ikhtisar tentang apa yang ingin kami capai dan apa yang kami temui saat mencoba menerapkan tujuan kami.
Ada beberapa jenis proyek yang dapat mengambil manfaat dari pendekatan ini. Misalnya, situs presentasi sederhana atau situs yang menggunakan WordPress sebagai backend adalah kandidat utama untuk pendekatan decoupled.
Dalam beberapa tahun terakhir, untungnya industri mulai lebih memperhatikan kinerja. Namun, sebagai perangkat lunak inklusif dan serbaguna yang mudah digunakan, WordPress hadir dengan sejumlah besar opsi yang belum tentu digunakan di setiap proyek. Akibatnya, kinerja situs web dapat menurun.
Bacaan yang disarankan : Cara Menggunakan Heatmaps Untuk Melacak Klik Di Situs WordPress Anda
Jika waktu respons situs web yang lama membuat Anda terjaga di malam hari, ini adalah cara untuk Anda. Saya akan membahas dasar-dasar membuat WordPress terpisah dan beberapa pelajaran, termasuk:
- Arti dari "WordPress yang dipisahkan"
- Bekerja dengan API REST WordPress default
- Meningkatkan kinerja dengan pendekatan JSON yang dipisahkan
- Perhatian pada keamanan
Jadi, Apa Sebenarnya WordPress yang Dipisahkan?
Ketika sampai pada bagaimana WordPress diprogram, satu hal yang pasti: itu tidak mengikuti pola desain model-View- C controller ( MVC ) yang sudah dikenal banyak pengembang. Karena sejarahnya dan menjadi semacam garpu dari platform blogging lama yang disebut "b2" (lebih detail di sini), sebagian besar ditulis dengan cara prosedural (menggunakan kode berbasis fungsi). Pengembang inti WordPress menggunakan sistem kait yang memungkinkan pengembang lain untuk memodifikasi atau memperluas fungsionalitas tertentu.
Ini adalah sistem all-in-one yang dilengkapi dengan antarmuka admin yang berfungsi; itu mengelola koneksi database, dan memiliki banyak API berguna yang terbuka yang menangani otentikasi pengguna, perutean, dan banyak lagi.
Namun berkat REST API, Anda dapat memisahkan backend WordPress sebagai semacam model dan pengontrol yang digabungkan bersama yang menangani manipulasi data dan interaksi basis data, dan menggunakan REST API Controller untuk berinteraksi dengan lapisan tampilan terpisah menggunakan berbagai titik akhir API. Selain pemisahan MVC, kami dapat (untuk alasan keamanan atau peningkatan kecepatan) menempatkan Aplikasi JS di server terpisah seperti pada skema di bawah ini:
Keuntungan Menggunakan Pendekatan Terpisah
Satu hal mengapa Anda mungkin ingin menggunakan pendekatan ini adalah untuk memastikan pemisahan masalah. Frontend dan backend berinteraksi melalui titik akhir; masing-masing dapat berada di server terpisah yang dapat dioptimalkan secara khusus untuk setiap tugas masing-masing, yaitu menjalankan aplikasi PHP secara terpisah dan menjalankan aplikasi Node.js.
Dengan memisahkan frontend dari backend, akan lebih mudah untuk mendesain ulang di masa mendatang, tanpa mengubah CMS. Selain itu, pengembang front-end hanya perlu peduli tentang apa yang harus dilakukan dengan data yang diberikan backend kepada mereka. Ini memungkinkan mereka menjadi kreatif dan menggunakan perpustakaan modern seperti ReactJS, Vue atau Angular untuk menghadirkan aplikasi web yang sangat dinamis. Misalnya, lebih mudah untuk membangun aplikasi web progresif saat menggunakan pustaka yang disebutkan di atas.
Keuntungan lain tercermin dalam keamanan situs web. Mengeksploitasi situs web melalui backend menjadi lebih sulit karena sebagian besar tersembunyi dari publik.
Bacaan yang disarankan : Keamanan WordPress Sebagai Proses
Kekurangan Menggunakan Pendekatan Terpisah
Pertama, memiliki WordPress yang dipisahkan berarti mempertahankan dua instance terpisah:
- WordPress untuk backend;
- Aplikasi front-end terpisah, termasuk pembaruan keamanan tepat waktu.
Kedua, beberapa perpustakaan front-end memang memiliki kurva belajar yang lebih curam. Ini akan memakan banyak waktu untuk mempelajari bahasa baru (jika Anda hanya terbiasa dengan HTML dan CSS untuk templating), atau akan membutuhkan ahli JavaScript tambahan untuk proyek tersebut.
Ketiga, dengan memisahkan frontend, Anda kehilangan kekuatan editor WYSIWYG, dan tombol 'Live Preview' di WordPress juga tidak berfungsi.
Bekerja Dengan WordPress REST API
Sebelum kita mempelajari kode lebih dalam, beberapa hal lagi tentang WordPress REST API. Kekuatan penuh dari REST API di WordPress hadir dengan versi 4.7 pada 6 Desember 2016.
Apa yang WordPress REST API memungkinkan Anda lakukan adalah berinteraksi dengan instalasi WordPress Anda dari jarak jauh dengan mengirim dan menerima objek JSON.
Menyiapkan Proyek
Karena dibundel dengan instalasi WordPress terbaru, kami akan mengerjakan tema Twenty Seventeen. Saya sedang mengerjakan Varying Vagrant Vagrants, dan telah menyiapkan situs uji dengan URL https://dev.wordpress.test/
. URL ini akan digunakan di seluruh artikel. Kami juga akan mengimpor posting dari repositori Tim Peninjau Tema wordpress.org sehingga kami memiliki beberapa data uji untuk digunakan. Tapi pertama-tama, kita akan terbiasa bekerja dengan titik akhir default, dan kemudian kita akan membuat titik akhir kustom kita sendiri.
Akses Titik Akhir REST Default
Seperti yang telah disebutkan, WordPress hadir dengan beberapa titik akhir bawaan yang dapat Anda periksa dengan membuka rute /wp-json/
:
https://dev.wordpress.test/wp-json/
Baik dengan meletakkan URL ini langsung di browser Anda, atau menambahkannya di aplikasi tukang pos, Anda akan mendapatkan respons JSON dari WordPress REST API yang terlihat seperti ini:
{ "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": { ...
Jadi untuk mendapatkan semua posting di situs kita dengan menggunakan REST, kita perlu membuka https://dev.wordpress.test/wp-json/wp/v2/posts
. Perhatikan bahwa wp/v2/
menandai titik akhir inti yang dicadangkan seperti posting, halaman, media, taksonomi, kategori, dan sebagainya.
Jadi, bagaimana cara menambahkan titik akhir khusus?
Buat Titik Akhir REST Kustom
Katakanlah kita ingin menambahkan titik akhir baru atau bidang tambahan ke titik akhir yang ada. Ada beberapa cara yang bisa kita lakukan. Pertama, seseorang dapat dilakukan secara otomatis saat membuat jenis posting khusus. Misalnya, kami ingin membuat titik akhir dokumentasi. Mari buat plugin uji kecil. Buat folder test-documentation di folder wp-content/plugins , dan tambahkan file dokumentasi.php yang terlihat seperti ini:
<?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' ] );
Dengan mendaftarkan jenis posting dan taksonomi baru, dan menyetel argumen show_in_rest
ke true
, WordPress secara otomatis membuat rute REST di /wp/v2/
namespace. Anda sekarang memiliki https://dev.wordpress.test/wp-json/wp/v2/documentation
dan https://dev.wordpress.test/wp-json/wp/v2/documentation-category
endpoint yang tersedia. Jika kita menambahkan postingan di postingan kustom dokumentasi yang baru dibuat ke https://dev.wordpress.test/?post_type=documentation
, itu akan memberi kita respons yang terlihat seperti ini:
[ { "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": "
Ini adalah beberapa konten dokumentasi
\n", "dilindungi": false }, "featured_media": 0, "templat": "", "kategori-dokumentasi": [ 2 ], "_link": { "diri sendiri": [ { "href": "https://dev.wordpress.test/wp-json/wp/v2/documentation/4" } ], "koleksi": [ { "href": "https://dev.wordpress.test/wp-json/wp/v2/documentation" } ], "tentang": [ { "href": "https://dev.wordpress.test/wp-json/wp/v2/types/documentation" } ], "versi-sejarah": [ { "href": "https://dev.wordpress.test/wp-json/wp/v2/documentation/4/revisions" } ], "wp:lampiran": [ { "href": "https://dev.wordpress.test/wp-json/wp/v2/media?parent=4" } ], "wp:istilah": [ { "taksonomi": "kategori-dokumentasi", "dapat disematkan": benar, "href": "https://dev.wordpress.test/wp-json/wp/v2/documentation-category?post=4" } ], "ingin": [ { "nama": "wp", "href": "https://api.w.org/{rel}", "template": benar } ] } } ]
Ini adalah titik awal yang bagus untuk aplikasi satu halaman kami. Cara lain kita dapat menambahkan titik akhir khusus adalah dengan menghubungkan ke kait rest_api_init
dan membuat titik akhir sendiri. Mari tambahkan rute custom-documentation
yang sedikit berbeda dari yang kita daftarkan. Masih bekerja di plugin yang sama, kita dapat menambahkan:
/** * 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 ); }
Dan kaitkan metode create_custom_documentation_endpoint()
ke kait rest_api_init
, seperti:
add_action( 'rest_api_init', [ $documentation, 'create_custom_documentation_endpoint' ] );
Ini akan menambahkan rute khusus di https://dev.wordpress.test/wp-json/documentation-plugin/v1/custom-documentation
dengan panggilan balik yang mengembalikan respons untuk rute itu.
[{ "title": "Another test documentation", "tags": ["Another tag"] }, { "title": "Test documentation", "tags": ["REST API", "test tag"] }]
Ada banyak hal lain yang dapat Anda lakukan dengan REST API (Anda dapat menemukan detail selengkapnya di buku pegangan REST API).
Mengatasi Waktu Respons yang Lama Saat Menggunakan REST API Default
Bagi siapa saja yang mencoba membangun situs WordPress terpisah, ini bukan hal baru — REST API lambat.
Tim saya dan saya pertama kali menemukan REST API aneh yang tertinggal WordPress di situs klien (tidak dipisahkan), di mana kami menggunakan titik akhir khusus untuk mendapatkan daftar lokasi di peta Google, di samping informasi meta lainnya yang dibuat menggunakan Advanced Custom Fields Pro pengaya. Ternyata waktu byte pertama (TTFB) — yang digunakan sebagai indikasi responsivitas server web atau sumber daya jaringan lainnya — membutuhkan waktu lebih dari 3 detik.
Setelah sedikit menyelidiki, kami menyadari bahwa panggilan REST API default sebenarnya sangat lambat, terutama ketika kami "membebani" situs dengan plugin tambahan. Jadi, kami melakukan tes kecil. Kami memasang beberapa plugin populer dan menemukan beberapa hasil yang menarik. Aplikasi tukang pos memberikan waktu buka 1,97 detik untuk ukuran respons 41,9KB. Waktu muat Chrome adalah 1,25 dtk (TTFB 1,25 dtk, konten diunduh dalam 3,96 mdtk). Hanya untuk mengambil daftar posting sederhana. Tidak ada taksonomi, tidak ada data pengguna, tidak ada bidang meta tambahan.
Kenapa ini terjadi?
Ternyata mengakses REST API pada default WordPress akan memuat seluruh inti WordPress untuk melayani endpoint, meskipun tidak digunakan. Juga, semakin banyak plugin yang Anda tambahkan, semakin buruk keadaannya. Pengontrol REST default WP_REST_Controller
adalah kelas yang sangat besar yang melakukan lebih dari yang diperlukan saat membuat halaman web sederhana. Ini menangani pendaftaran rute, pemeriksaan izin, membuat dan menghapus item, dan sebagainya.
Ada dua solusi umum untuk masalah ini:
- Cegat pemuatan plugin, dan cegah pemuatan semuanya saat Anda perlu menyajikan respons REST sederhana;
- Muat hanya WordPress minimal dan simpan data sementara, dari mana kami kemudian mengambil data menggunakan halaman kustom.
Meningkatkan Kinerja Dengan Pendekatan JSON Terpisah
Saat Anda bekerja dengan situs presentasi sederhana, Anda tidak memerlukan semua fungsionalitas yang ditawarkan REST API. Tentu saja, di sinilah perencanaan yang baik sangat penting. Anda benar-benar tidak ingin membangun situs Anda tanpa REST API, dan kemudian mengatakan dalam beberapa tahun bahwa Anda ingin terhubung ke situs Anda, atau mungkin membuat aplikasi seluler yang perlu menggunakan fungsionalitas REST API. Apakah kamu?
Untuk alasan itu, kami menggunakan dua fitur WordPress yang dapat membantu Anda saat menyajikan data JSON sederhana:
- API sementara untuk caching,
- Memuat WordPress minimum yang diperlukan menggunakan konstanta
SHORTINIT
.
Membuat Titik Akhir Halaman Terpisah Sederhana
Mari kita buat sebuah plugin kecil yang akan mendemonstrasikan efek yang sedang kita bicarakan. Pertama, tambahkan file wp-config-simple.php di plugin json-transient
Anda yang terlihat seperti ini:
<?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 );
akan mencegah sebagian besar file inti WordPress dimuat, seperti yang dapat dilihat di file wp-settings.php .
Kami mungkin masih memerlukan beberapa fungsionalitas WordPress, jadi kami dapat meminta file tersebut (seperti wp-load.php ) secara manual. Karena wp-load.php berada di root instalasi WordPress kami, kami akan mengambilnya dengan mendapatkan jalur file kami menggunakan $_SERVER['SCRIPT_FILENAME']
, dan kemudian meledakkan string itu dengan string wp-content
. Ini akan mengembalikan array dengan dua nilai:
- Akar instalasi kami;
- Sisa jalur file (yang tidak menarik bagi kami).
Perlu diingat bahwa kami menggunakan instalasi default WordPress, dan bukan instalasi yang dimodifikasi, seperti misalnya di boilerplate Bedrock, yang membagi WordPress dalam organisasi file yang berbeda.
Terakhir, kami memerlukan file wp-load.php , dengan sedikit sanitasi, untuk keamanan.
Dalam file init.php kita, kita akan menambahkan yang berikut ini:
* 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' ] );
Metode pembantu dalam kode di atas akan memungkinkan kita untuk melakukan beberapa caching:
-
get_allowed_post_types()
Metode ini memungkinkan jenis postingan mengetahui bahwa kami ingin mengaktifkan tampilan di 'titik akhir' kustom kami. Anda dapat memperluas ini, dan plugin kami sebenarnya telah membuat metode ini dapat difilter sehingga Anda dapat menggunakan filter untuk menambahkan item tambahan. -
is_post_type_allowed_to_save()
Metode ini hanya memeriksa untuk melihat apakah jenis kiriman yang kita coba ambil datanya ada dalam larik yang diizinkan yang ditentukan oleh metode sebelumnya. -
get_page_cache_name_by_slug()
Metode ini akan mengembalikan nama sementara dari mana data akan diambil. -
get_page_data_by_slug()
Metode ini adalah metode yang akan melakukanWP_Query
pada kiriman melalui slug dan jenis kirimannya dan mengembalikan isi larik kiriman yang akan kita konversi dengan JSON menggunakan metodeget_json_page()
. -
update_page_transient()
Ini akan dijalankan di hooksave_post
dan akan menimpa transien dalam database dengan data JSON dari posting kami. Metode terakhir ini dikenal sebagai "metode caching kunci".
Mari kita jelaskan transien secara lebih mendalam.
API Transien
Transients API digunakan untuk menyimpan data di tabel opsi database WordPress Anda untuk jangka waktu tertentu. Ini adalah cache objek yang bertahan, artinya Anda menyimpan beberapa objek, misalnya, hasil kueri besar dan lambat atau halaman penuh yang dapat dipertahankan di seluruh pemuatan halaman. Ini mirip dengan WordPress Object Cache biasa, tetapi tidak seperti WP_Cache
, transien akan menyimpan data di seluruh pemuatan halaman, di mana WP_Cache
(menyimpan data dalam memori) hanya akan menyimpan data selama durasi permintaan.
Ini adalah penyimpanan nilai kunci, artinya kita dapat dengan mudah dan cepat mengambil data yang diinginkan, mirip dengan apa in-memory caching systems
seperti Memcached atau Redis. Perbedaannya adalah Anda biasanya perlu menginstalnya secara terpisah di server (yang bisa menjadi masalah di server bersama), sedangkan transien dibangun dengan WordPress.
Seperti yang dicatat pada halaman Codex - transien secara inheren dipercepat oleh plugin caching. Karena mereka dapat menyimpan transien dalam memori alih-alih database. Aturan umumnya adalah Anda tidak boleh berasumsi bahwa transien selalu ada di database — itulah sebabnya praktik yang baik adalah memeriksa keberadaannya sebelum mengambilnya
$transient_name = get_transient( 'transient_name' ); if ( $transient_name === false ) { set_transient( 'transient_name', $transient_data, $transient_expiry ); }
Anda dapat menggunakannya tanpa kedaluwarsa (seperti yang kami lakukan), dan itulah mengapa kami menerapkan semacam 'penghancur cache' pada penyimpanan pos. Selain semua fungsionalitas hebat yang mereka sediakan, mereka dapat menyimpan hingga 4GB data di dalamnya, tetapi kami tidak menyarankan untuk menyimpan apa pun yang sebesar itu dalam satu bidang basis data.
Bacaan yang direkomendasikan : Waspadalah: Fungsi PHP dan WordPress yang Dapat Membuat Situs Anda Tidak Aman
Titik Akhir Akhir: Pengujian Dan Verifikasi
Bagian terakhir dari teka-teki yang kita butuhkan adalah 'titik akhir'. Saya menggunakan istilah titik akhir di sini, meskipun itu bukan titik akhir karena kami langsung memanggil file tertentu untuk mengambil hasil kami. Jadi kita bisa membuat file test.php yang terlihat seperti ini:
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 ) );
Jika kita membuka https://dev.wordpress.test/wp-content/plugins/json-transient/test.php
, kita akan melihat pesan ini:
Kesalahan, siput halaman, atau jenis tidak ada!
Jadi, kita perlu menentukan jenis posting dan post slug. Ketika kita sekarang pergi ke https://dev.wordpress.test/wp-content/plugins/json-transient/test.php?slug=hello-world&type=post
kita akan melihat:
Kesalahan, halaman tidak ada atau tidak di-cache dengan benar. Silakan coba membangun kembali cache dan coba lagi!
Oh tunggu! Kita perlu menyimpan ulang halaman dan postingan kita terlebih dahulu. Jadi ketika Anda memulai, ini bisa menjadi mudah. Tetapi jika Anda sudah memiliki 100+ halaman atau posting, ini bisa menjadi tugas yang menantang. Inilah sebabnya kami menerapkan cara untuk menghapus transien di plugin Konten JSON yang Dipisahkan, dan membangunnya kembali dalam satu batch.
Tapi lanjutkan dan simpan kembali posting Hello World lalu buka kembali tautannya. Apa yang seharusnya Anda miliki sekarang adalah sesuatu yang terlihat seperti ini:
{ "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" }
Dan itu saja. Plugin yang kami buat memiliki beberapa fungsi tambahan yang dapat Anda gunakan, tetapi singkatnya, ini adalah bagaimana Anda dapat mengambil data JSON dari WordPress Anda yang jauh lebih cepat daripada menggunakan REST API.
Sebelum Dan Setelah: Peningkatan Waktu Respon
Kami melakukan pengujian di Chrome, di mana kami dapat melihat total waktu respons dan TTFB secara terpisah. Kami menguji waktu respons sepuluh kali berturut-turut: pertama tanpa plugin dan kemudian dengan plugin yang ditambahkan. Selain itu, kami menguji respons untuk daftar posting dan untuk satu posting.
Hasil pengujian diilustrasikan pada tabel di bawah ini:
Seperti yang Anda lihat, perbedaannya drastis.
Perhatian pada keamanan
Ada beberapa peringatan yang harus Anda perhatikan baik-baik. Pertama-tama, kami memuat file inti WordPress secara manual, yang di dunia WordPress sangat dilarang. Mengapa? Selain fakta bahwa mengambil file inti secara manual bisa jadi rumit (terutama jika Anda menggunakan instalasi yang tidak standar seperti Bedrock), ini bisa menimbulkan beberapa masalah keamanan.
Jika Anda memutuskan untuk menggunakan metode yang dijelaskan dalam artikel ini, pastikan Anda mengetahui cara memperkuat keamanan server Anda.
Pertama, tambahkan header HTML seperti pada file test.php :
header( 'Access-Control-Allow-Origin: your-front-end-app.url' ); header( 'Content-Type: application/json' );
Header pertama adalah cara untuk melewati tindakan keamanan CORS sehingga hanya aplikasi front-end Anda yang dapat mengambil konten saat membuka file yang ditentukan.
Kedua, nonaktifkan traversal direktori aplikasi Anda. Anda dapat melakukannya dengan memodifikasi pengaturan nginx
, atau menambahkan Options -Indexes
ke file .htaccess Anda jika Anda menggunakan server Apache.
Menambahkan pemeriksaan token ke respons juga merupakan tindakan yang baik yang dapat mencegah akses yang tidak diinginkan. Kami sebenarnya sedang mengerjakan cara untuk memodifikasi plugin JSON Decoupled kami sehingga kami dapat menyertakan langkah-langkah keamanan ini secara default.
Pemeriksaan untuk header Otorisasi yang dikirim oleh aplikasi frontend dapat terlihat seperti ini:
if ( ! isset( $_SERVER['HTTP_AUTHORIZATION'] ) ) { return; } $auth_header = $_SERVER['HTTP_AUTHORIZATION'];
Kemudian Anda dapat memeriksa apakah token tertentu (rahasia yang hanya dibagikan oleh aplikasi front-end dan back-end) disediakan dan benar.
Kesimpulan
REST API sangat bagus karena dapat digunakan untuk membuat aplikasi yang lengkap — membuat, mengambil, memperbarui, dan menghapus data. Kelemahan dari menggunakannya adalah kecepatannya.
Jelas, membuat aplikasi berbeda dengan membuat situs web klasik. Anda mungkin tidak memerlukan semua plugin yang kami instal. Tetapi jika Anda hanya memerlukan data untuk tujuan presentasi, menyimpan data dalam cache dan menyajikannya dalam file khusus sepertinya merupakan solusi sempurna saat ini, ketika bekerja dengan situs yang dipisahkan.
Anda mungkin berpikir bahwa membuat plugin khusus untuk mempercepat waktu respons situs web adalah pekerjaan yang berlebihan, tetapi kita hidup di dunia di mana setiap detik sangat berarti. Semua orang tahu bahwa jika sebuah situs web lambat, pengguna akan meninggalkannya. Ada banyak penelitian yang menunjukkan hubungan antara kinerja situs web dan tingkat konversi. Tetapi jika Anda masih perlu diyakinkan, Google menghukum situs web yang lambat.
Metode yang dijelaskan dalam artikel ini memecahkan masalah kecepatan yang dihadapi WordPress REST API dan akan memberi Anda dorongan ekstra saat mengerjakan proyek WordPress yang dipisahkan. Saat kami dalam pencarian tanpa akhir untuk memeras milidetik terakhir dari setiap permintaan dan tanggapan, kami berencana untuk lebih mengoptimalkan plugin. Sementara itu, silakan bagikan ide Anda untuk mempercepat WordPress yang dipisahkan!