Безголовый WordPress: Взлеты и падения создания разъединенный WordPress

WordPress пришел долгий путь от его начала, как простой инструмент написания блога. Долгие 15 лет спустя он стал номером один CMS выбор для разработчиков и не-разработчиков, так. WordPress в настоящее время полномочия примерно 30% из 10 миллионов лучших сайтов в Интернете.

С тех пор как REST API был в комплекте в ядре WordPress, разработчики могут экспериментировать и использовать его в разъединении, т.е. писать фронтальная часть с помощью рамок Или библиотек JavaScript. В Infinum, мы были (и до сих пор) с помощью WordPress в «классический» способ: PHP для передней, а также бэкэнд. Через некоторое время, мы хотели дать разъединение подход идти. В этой статье я расскажу о том, чего мы хотели достичь и с чем столкнулись, пытаясь реализовать наши цели.

Существует несколько типов проектов, которые могут извлечь выгоду из этого подхода. Например, простые презентационные сайты или сайты, которые используют WordPress в качестве бэкэнда, являются основными кандидатами на разъединение подхода.

В последние годы отрасль, к счастью, стала уделять больше внимания производительности. Однако, будучи простой в использовании инклюзивный и универсальный кусок программного обеспечения, WordPress поставляется с множеством вариантов, которые не обязательно используются в каждом проекте. В результате, производительность веб-сайта может пострадать.

Рекомендуемое чтение: Как использовать тепловые карты для отслеживания кликов на вашем сайте WordPress

Если долго еженедельное время отклика веб-сайта держать вас в ночное время, это как-к для вас. Я буду охватывать основы создания разъединенные WordPress и некоторые уроки, в том числе:

  1. Смысл «разъединение WordPress»
  2. Работа с API WordPress REST по умолчанию
  3. Улучшение производительности с помощью разъединеного подхода JSON
  4. Проблемы безопасности

Итак, что именно является разъединение WordPress?

Когда дело доходит до того, как WordPress запрограммирован, одно можно сказать наверняка: он не следует Model-View-Controller (MVC) дизайн шаблона, что многие разработчики знакомы с. Из-за своей истории и за то, что своего рода вилка старой блогов платформы под названием «b2» (подробнее здесь),это в значительной степени написано в процедурном порядке (с использованием функции на основе кода). Разработчики core WordPress использовали систему крючков, которая позволяла другим разработчикам изменять или расширять определенные функциональные возможности.

Это все-в-одном система, которая оснащена рабочим интерфейсом админ; он управляет подключением к базе данных и имеет кучу полезных AA, которые обрабатывают аутентификацию пользователей, направление и многое другое.

Но благодаря REST API, вы можете отделить бэкэнд WordPress как своего рода модель и контроллер в комплекте, которые обрабатывают манипуляции данными и взаимодействие с базами данных, и использовать REST API Controller для взаимодействия с отдельным слоем просмотра с использованием различных конечных точек API . В дополнение к разделению MVC, мы можем (по соображениям безопасности или улучшения скорости) разместить Приложение JS на отдельном сервере, как в схеме ниже:

Image depicting decoupled WordPress diagram with PHP and JS part separated
Разъединеная диаграмма WordPress. (Большой предварительный просмотр)

Преимущества использования разъединеного подхода

Одна вещь, почему вы можете использовать этот подход для обеспечения разделения проблем. Фронтэнд и бэкэнд взаимодействуют через конечные точки; каждый из них может быть на своем отдельном сервере, который может быть оптимизирован специально для каждой соответствующей задачи, т.е. отдельно работает приложение PHP и работает приложение Node.js.

Отделяя переднюю часть от бэкэнда, проще перепроектировать его в будущем, не меняя CMS. Кроме того, разработчики фронт-энда должны заботиться только о том, что делать с данными, которые предоставляет им бэкэнд. Это позволяет им творчески и использовать современные библиотеки, такие как ReactJS, Vue или Angular, чтобы предоставлять высокодинамические веб-приложения. Например, проще создать прогрессивное веб-приложение при использовании вышеупомянутых библиотек.

Еще одно преимущество отражено в безопасности веб-сайта. Использование веб-сайта через бэкэнд становится все труднее, поскольку это в значительной степени скрыты от общественности.

Рекомендуемое чтение: WordPress безопасности как процесс

Недостатки использования разъединеного подхода

Во-первых, наличие разъединение WordPress означает поддержание двух отдельных экземпляров:

  1. WordPress для бэкэнда;
  2. Отдельное переднее приложение, включая своевременные обновления безопасности.

Во-вторых, некоторые из библиотек переднего конца имеют более крутой кривой обучения. Это займет много времени, чтобы узнать новый язык (если вы только привыкли к HTML и CSS для шаблонов), или потребует привлечения дополнительных экспертов JavaScript к проекту.

В-третьих, путем разделения переднего, вы теряете власть редактора WYSIWYG, и «Live Preview» кнопку в WordPress не работает либо.

Работа с WordPress REST API

Прежде чем углубиться в код, еще несколько вещей о WordPress REST API. Полная мощность REST API в WordPress пришла с версией 4.7 6 декабря 2016 года.

Что WordPress REST API позволяет вам сделать, это взаимодействовать с вашей установки WordPress удаленно, отправив и получая объекты JSON.

Настройка проекта

Так как он поставляется в комплекте с последней установкой WordPress, мы будем работать на двадцать семнадцать тему. Я работаю на Разнообразие Бродяга бродяги, и создали испытательный полигон с URL http://dev.wordpress.test/ . Этот URL будет использоваться на протяжении всей статьи. Мы также импортируем публикации из репозитория wordpress.org Theme Review Teams, чтобы у нас были некоторые тестовые данные для работы. Но сначала мы ознакомимся с конечными точками по умолчанию, а затем создадим нашу собственную конечную точку.

Доступ к конечная точка REST по умолчанию

Как уже упоминалось, WordPress поставляется с несколькими встроенными конечными точками, которые вы можете изучить, перейдя на /wp-json/ маршрут:

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

Либо поставив этот URL-адрес непосредственно в вашем браузере, или добавив его в приложение почтальона, вы получите ответ JSON от WordPress REST API, который выглядит примерно так:

{
    "name": "Test dev site",
    "description": "Just another WordPress site",
    "url": "http://dev.wordpress.test",
    "home": "http://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": "http://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": "http://dev.wordpress.test/wp-json/oembed/1.0"
            }
        },
        ...
        "wp/v2": {
        ...

Таким образом, для того, чтобы получить все сообщения на нашем сайте с помощью REST, мы должны пойти в http://dev.wordpress.test/wp-json/wp/v2/posts . Обратите внимание, что wp/v2/ отмечены зарезервированные основные конечные точки, такие как сообщения, страницы, средства массовой информации, таксономии, категории и так далее.

Итак, как мы можем добавить пользовательские конечную точку?

Создание пользовательской точки REST

Допустим, мы хотим добавить новую конечную точку или дополнительное поле к существующей конечной точке. Есть несколько способов, которыми мы можем это сделать. Во-первых, можно сделать автоматически при создании пользовательского типа поста. Например, мы хотим создать конечную точку документации. Давайте создадим небольшой тестовый плагин. Создайте папку с тестовой документацией в папке wp-content/plugins и добавьте файл documentation.php, который выглядит следующим образом:

<?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 <info@infinum.co>
 * Author URI:        https://infinum.co/
 * License:           GPL-2.0+
 * License URI:       http://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' ] );

Зарегистрировав новый тип поста и таксономии, и установка show_in_rest true аргумента, WordPress автоматически создал маршрут REST в /wp/v2/ пространстве имен. Теперь у вас есть http://dev.wordpress.test/wp-json/wp/v2/documentation и http://dev.wordpress.test/wp-json/wp/v2/documentation-category конечные точки доступны. Если мы добавим сообщение в нашей недавно созданной документации пользовательских должность http://dev.wordpress.test/?post_type=documentation собирается, это даст нам ответ, который выглядит следующим образом:

[
    {
        "id": 4,
        "date": "2018-06-11T19:48:51",
        "date_gmt": "2018-06-11T19:48:51",
        "guid": {
            "rendered": "http://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": "http://dev.wordpress.test/documentation/test-documentation/",
        "title": {
            "rendered": "Test documentation"
        },
        "content": {
            "rendered": "This is some documentation contentn",
            "protected": false
        },
        "featured_media": 0,
        "template": "",
        "documentation-category": [
            2
        ],
        "_links": {
            "self": [
                {
                    "href": "http://dev.wordpress.test/wp-json/wp/v2/documentation/4"
                }
            ],
            "collection": [
                {
                    "href": "http://dev.wordpress.test/wp-json/wp/v2/documentation"
                }
            ],
            "about": [
                {
                    "href": "http://dev.wordpress.test/wp-json/wp/v2/types/documentation"
                }
            ],
            "version-history": [
                {
                    "href": "http://dev.wordpress.test/wp-json/wp/v2/documentation/4/revisions"
                }
            ],
            "wp:attachment": [
                {
                    "href": "http://dev.wordpress.test/wp-json/wp/v2/media?parent=4"
                }
            ],
            "wp:term": [
                {
                    "taxonomy": "documentation-category",
                    "embeddable": true,
                    "href": "http://dev.wordpress.test/wp-json/wp/v2/documentation-category?post=4"
                }
            ],
            "curies": [
                {
                    "name": "wp",
                    "href": "https://api.w.org/{rel}",
                    "templated": true
                }
            ]
        }
    }
]

Это отличная отправная точка для нашего одностраничного приложения. Другой способ мы можем добавить пользовательские конечная точка, зацепив rest_api_init на крючок и создания конечную точку себя. Давайте добавим custom-documentation маршрут, который немного отличается от того, который мы зарегистрировали. Все еще работая в том же плагине, мы можем добавить:

/**
 * 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 );
}

И подключите create_custom_documentation_endpoint() метод к rest_api_init крючку, как так:

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

Это добавит пользовательский маршрут в http://dev.wordpress.test/wp-json/documentation-plugin/v1/custom-documentation обратный вызов, возвращающийся ответ на этот маршрут.

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

Есть много других вещей, которые вы можете сделать с REST API (вы можете найти более подробную информацию в справочнике REST API).

Работайте вокруг долгого времени отклика при использовании aPI REST по умолчанию

Для тех, кто пытался построить отделенный сайт WordPress, это не новая вещь — REST API медленно.

Моя команда и я впервые столкнулись со странным WordPress-отставания REST API на сайте клиента (не отделены), где мы использовали пользовательские конечные точки, чтобы получить список мест на карте Google, наряду с другой мета-информации, созданной с помощью Расширенный пользовательских полей Pro плагин. Оказалось, что время первого байта (TTFB), который используется как признак отзывчивости веб-сервера или другого сетевого ресурса, заняло более 3 секунд.

После небольшого расследования, мы поняли, что вызовы REST API по умолчанию были на самом деле очень медленными, особенно когда мы «обременили» сайт дополнительными плагинами. Итак, мы сделали небольшой тест. Мы установили несколько популярных плагинов и столкнулись с некоторыми интересными результатами. Почтальон приложение дало время загрузки 1.97s для 41.9KB размера ответа. Время загрузки Chrome составило 1.25s (TTFB был 1.25s, содержание было загружено в 3.96ms). Просто, чтобы получить простой список сообщений. Нет таксономии, нет пользовательских данных, нет дополнительных метаполей.

Почему это произошло?

Оказывается, что доступ к REST API по умолчанию WordPress загрузит все ядро WordPress, чтобы служить конечным точкам, даже если он не используется. Кроме того, чем больше плагинов вы добавляете, тем хуже вещи получить. Контроллер REST по умолчанию WP_REST_Controller является действительно большим классом, который делает намного больше, чем необходимо при создании простой веб-страницы. Он обрабатывает регистрацию маршрутов, проверку разрешений, создание и удаляние элементов и так далее.

Есть два общих обходных пути для этой проблемы:

  1. Перехватить загрузку плагинов и предотвратить их загрузку, когда вам нужно служить простой ответ REST;
  2. Загрузите только минимум WordPress и храните данные в переходном,из которого мы затем получить данные с помощью пользовательской страницы.

Улучшение производительности с разъединение JSON подход

Когда вы работаете с простыми сайтами презентаций, вам не нужно все функциональные возможности REST API предлагает вам. Конечно, это где хорошее планирование имеет решающее значение. Вы действительно не хотите строить свой сайт без REST API, а затем сказать через несколько лет, что вы хотите подключиться к вашему сайту, или, может быть, создать мобильное приложение, которое должно использовать функциональность REST API. А Вы?

По этой причине, мы использовали две функции WordPress, которые могут помочь вам при подаче простых данных JSON из:

  • API переходов для кэширования,
  • Загрузка минимально необходимого WordPress с помощью SHORTINIT постоянной.

Создание простой разъединение страниц конечная точка

Давайте создадим небольшой плагин, который продемонстрирует эффект, о котором мы говорим. Во-первых, добавить wp-конфигурация-simple.php файл в json-transient плагин, который выглядит следующим образом:

<?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 ); позволит предотвратить большинство WordPress основных файлов, которые будут загружены, как можно увидеть в wp-settings.php файл.

Мы все еще можем нуждаться в некоторых wordPress функциональность, поэтому мы можем потребовать файл (например, wp-load.php) вручную. Так как wp-load.php сидит в корне нашей установки WordPress, мы будем получать его, получив путь нашего файла с $_SERVER['SCRIPT_FILENAME'] помощью, а затем взрыва, что строка за wp-content строкой. Это вернет массив с двумя значениями:

  1. Корень нашей установки;
  2. Остальная часть пути файла (которая не представляет для нас интереса).

Имейте в виду, что мы используем установку по умолчанию WordPress, а не модифицированный, как, например, в шаблоне Bedrock, который разделяет WordPress в другой организации файлов.

Наконец, для обеспечения безопасности нам требуется файл wp-load.php с небольшим количеством дезинфекции.

В нашем файле init.php мы добавим следующее:


 * Author URI:        https://infinum.co/
 * License:           GPL-2.0+
 * License URI:       http://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' ] );

Вспомогательные методы в приведенном выше коде позволят нам сделать некоторое кэширование:

  • get_allowed_post_types()
    Этот метод позволяет размещать типы знают, что мы хотим включить показ в нашей пользовательской «конечная точка». Вы можете расширить это, и плагин мы на самом деле сделали этот метод фильтруемым, так что вы можете просто использовать фильтр для добавления дополнительных элементов.
  • is_post_type_allowed_to_save()
    Этот метод просто проверяет, находится ли тип публикации, из которой мы пытаемся получить данные, в разрешенном массиве, указанном предыдущим методом.
  • get_page_cache_name_by_slug()
    Этот метод вернет имя переходного, из которого будут извлечены данные.
  • get_page_data_by_slug()
    Этот метод является методом, который будет выполнять WP_Query на должность через его пули и пост типа и вернуть содержимое массива поста, который мы будем конвертировать с JSON с помощью get_json_page() метода.
  • update_page_transient()
    Это будет работать на save_post крючке и будет перезаписать переходных в базе данных с данными JSON нашего поста. Последний метод известен как «метод кэширования ключей».

Давайте объясним переходные более подробно.

API переходов

API Transients используется для хранения данных в таблице параметров базы данных WordPress в течение определенного периода времени. Это упорный кэш объектов, что означает, что вы сохраняете некоторые объекты, например, результаты больших и медленных запросов или полных страниц, которые могут сохраняться на нагрузках страниц. Он похож на обычный кэш объекта WordPress,но в отличие от WP_Cache , переходные будут сохраняться данные через нагрузок страницы, где WP_Cache (хранение данных в памяти) будет хранить данные только в течение всего срока запроса.

Это магазин с ключевым значением, что означает, что мы можем легко и быстро получить желаемые данные, аналогичные тому, что делают in-memory caching systems Memcached или Redis. Разница в том, что вы, как правило, необходимо установить их отдельно на сервере (который может быть проблемой на общих серверах), в то время как переходные встроены в WordPress.

Как отмечено на его странице Codex — переходные по своей сути ускорили путем кэширования плагинов. Так как они могут хранить переходные в памяти, а не базу данных. Общее правило заключается в том, что вы не должны считать, что переходный всегда присутствует в базе данных — именно поэтому это хорошая практика, чтобы проверить его существование, прежде чем получить его

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

Вы можете использовать его без истечения срока действия (как мы делаем), и именно поэтому мы реализовали своего рода «кэш-перебор» на пост сохранить. В дополнение ко всей большой функциональности они предоставляют, они могут содержать до 4 ГБ данных в нем, но мы не рекомендуем хранить все, что большой в одной области базы данных.

Рекомендуемое чтение: Будьте бдительны: PHP и WordPress Функции, которые могут сделать ваш сайт небезопасным

Окончательная конечная точка: Тестирование и проверка

Последняя часть головоломки, что нам нужно, это «конечная точка». Я использую термин конечная точка здесь, даже если это не конечная точка, поскольку мы непосредственно вызова конкретного файла, чтобы получить наши результаты. Таким образом, мы можем создать файл test.php, который выглядит следующим образом:

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 ) );

Если мы идем к http://dev.wordpress.test/wp-content/plugins/json-transient/test.php , мы увидим это сообщение:

Ошибка, пуля страницы или тип отсутствует!

Таким образом, мы должны указать тип поста и должность пули. Когда мы сейчас идем к http://dev.wordpress.test/wp-content/plugins/json-transient/test.php?slug=hello-world&type=post мы увидим:

Ошибка, страница не существует или она не кэшируется правильно. Пожалуйста, попробуйте восстановить кэш и попробуйте еще раз!

Ой, подождите! Мы должны повторно сохранить наши страницы и сообщения в первую очередь. Так что, когда вы начинаете, это может быть легко. Но если у вас уже есть 100 страниц или сообщений, это может быть сложной задачей. Вот почему мы внедрили способ очистить переходные части плагина Decoupled JSON Content и восстановить их в партии.

Но идти вперед и вновь сохранить Hello World пост, а затем открыть ссылку снова. То, что вы должны сейчас есть то, что выглядит следующим образом:

{
  "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"
}

И это все. Плагин мы сделали имеет несколько дополнительных функций, которые можно использовать, но в двух словах, это, как вы можете получить данные JSON от вашего WordPress, что это путь быстрее, чем с помощью REST API.

До и после: Улучшенное время отклика

Мы провели тестирование в Chrome, где мы могли видеть общее время отклика и TTFB отдельно. Мы тестировали ответ раз десять раз подряд: сначала без плагинов, а затем с плагинами добавил. Кроме того, мы протестировали ответ на список сообщений и на одну должность.

Результаты теста иллюстрируются в таблицах ниже:

Comparison graph depicting response times of using WordPress REST API vs using the decoupled approach without added plugins. The decoupled approach is 2 to 3 times faster
Сравнение график, изображающий время отклика с помощью WordPress REST API против использования разъединенный подход без дополнительных плагинов. Разъединение подхода в 2-3 раза быстрее. (Большой предварительный просмотр)
Comparison graph depicting response times of using WordPress REST API vs using the decoupled approach with added plugins. The decoupled approach is up to 8 times faster.
Сравнение график, изображающий время отклика с помощью WordPress REST API против с помощью разъединенный подход с добавленными плагинами. Разъединение подхода происходит в 8 раз быстрее. (Большой предварительный просмотр)

Как вы можете видеть, разница является резким.

Проблемы безопасности

Есть некоторые предостережения, что вам нужно, чтобы хорошо взглянуть на. Прежде всего, мы вручную загрузки WordPress основных файлов, которые в мире WordPress является большой нет-нет. Почему? Ну, помимо того, что вручную извлечения основных файлов может быть сложно (особенно если вы используете нестандартные установки, такие как Bedrock), это может создать некоторые проблемы безопасности.

Если вы решили использовать метод, описанный в этой статье, убедитесь, что вы знаете, как укрепить безопасность сервера.

Во-первых, добавьте HTML заголовки, как в файле test.php:

header( 'Access-Control-Allow-Origin: your-front-end-app.url' );

header( 'Content-Type: application/json' );

Первый заголовок — это способ обойти меры безопасности CORS, чтобы только переднее приложение мог получать содержимое при переходе к указанному файлу.

Во-вторых, отключить обход каталога вашего приложения. Вы можете сделать это, изменив nginx настройки, или Options -Indexes добавить в файл .htaccess, если вы находитесь на сервере Apache.

Добавление проверки маркеров в ответ также является хорошей мерой, которая может предотвратить нежелательный доступ. Мы на самом деле работаем над способом модификации нашего плагина Decoupled JSON, чтобы мы могли включить эти меры безопасности по умолчанию.

Проверка заголовка авторизации, отправленного приложением frontend, может выглядеть следующим образом:

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

$auth_header = $_SERVER['HTTP_AUTHORIZATION'];

Затем вы можете проверить, предоставляется ли и корректен конкретный токен (секрет, которым делятся только передние и задние приложения).

Заключение

REST API отлично подходит тем, что его можно использовать для создания полноценных приложений – создания, извлечения, обновления и удаляния данных. Недостатком его использования является его скорость.

Очевидно, что создание приложения отличается от создания классического веб-сайта. Вам, вероятно, не понадобятся все плагины, которые мы установили. Но если вам просто нужны данные для презентационных целей, кэширование данных и обслуживание их в пользовательском файле кажется идеальным решением на данный момент, при работе с разъединеными сайтами.

Вы можете думать, что создание пользовательского плагина для ускорения времени ответа на веб-сайт является излишним, но мы живем в мире, в котором каждая секунда имеет значение. Всем известно, что если веб-сайт медленно, пользователи будут отказываться от него. Есть много исследований, которые демонстрируют связь между производительностью веб-сайта и коэффициенты конверсии. Но если вам все еще нужно убедить, Google наказывает медленные веб-сайты.

Метод, объясняемый в этой статье, решает проблему скорости, с которой сталкивается API WordPress REST, и даст вам дополнительный импульс при работе над разъединеным проектом WordPress. Как мы находимся на нашем бесконечные поиски, чтобы выжать, что последняя миллисекунда из каждого запроса и ответа, мы планируем оптимизировать плагин еще больше. В то же время, пожалуйста, поделитесь своими идеями по ускорению разъединение WordPress!

Источник: smashingmagazine.com

Великолепный Журнал

Великолепный, сокрушительный, разящий (см. перевод smashing) независимый журнал о веб-разработке. Основан в 2006 году в Германии. Имеет няшный дизайн и кучу крутых авторов, которых читают 2 млн человек в месяц.

Добавить комментарий

%d такие блоггеры, как: