WordPress サイトのSEO対策用プラグインとして鉄板の「All In One SEO Pack」ですが、これがなかなか重いんです。
WordPress の表示速度が遅い、と相談を受けた場合、大抵 All In One SEO Pack が入っており、P3 等で重いプラグインのモニタリングをしても、必ずこいつが上位に入ってきます。
非常に高機能なプラグインなので仕方ないのですが、実際のところ、投稿ごとの title 、keywords 、description の設定くらいしか使っていない、という方も多いのではないでしょうか。
それなら、いっそ停止して独自実装してしまった方が、高速化した分 SEO にも有利に働くかもしれません。
All In One SEO Pack と互換性をもたせつつ、高速化する
まずは、投稿の編集ページに、タイトルやキーワードの入力欄を追加します。
All In One SEO Pack は、タイトル、キーワード、ディスクリプションを、それぞれ
_aioseop_title
_aioseop_keywords
_aioseop_description
という meta_key のカスタムフィールドに保存しています。
これと同じ meta_key でカスタムフィールドを作って保存するようにすれば、これまで All In One SEO Pack で設定してきた内容を失うことなく、独自実装に切り替えることができます。
以下がメタボックスを表示、保存するための実装です。
ほぼ WordPress.org のサンプルそのままです。いっそ Advanced Custom Field で設置しても良いでしょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
<?php /** * SEO用クラス (管理画面用) * All In One SEO Pack 互換 */ class My_Seo_Admin { //出力する投稿タイプ const POST_TYPES = array( 'post', 'page', ); public function __construct() { add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ) ); add_action( 'save_post', array( $this, 'save' ) ); } /** * メタボックスを追加 */ public function add_meta_box( $post_type ) { if ( in_array( $post_type, self::POST_TYPES )) { add_meta_box( 'my_seo' ,'SEO設定' ,array( $this, 'render_meta_box_content' ) ,self::POST_TYPES ,'advanced' ,'high' ); } } /** * メタボックスの内容をカスタムフィールドとして保存 */ public function save( $post_id ) { //NONCEチェック if ( ! isset( $_POST['my_seo_nonce'] ) ) { return $post_id; } $nonce = $_POST['my_seo_nonce']; if ( ! wp_verify_nonce( $nonce, 'my_seo' ) ) { return $post_id; } //自動保存は無視 if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) { return $post_id; } //権限チェック $post_type = $_POST['post_type']; $cap = $GLOBALS['wp_post_types'][$post_type]->cap->edit_post; if ( ! current_user_can( $cap, $post_id ) ) { return $post_id; } //保存 $title = sanitize_text_field( $_POST['_aioseop_title'] ); $keywords = sanitize_text_field( $_POST['_aioseop_keywords'] ); $description = sanitize_text_field( $_POST['_aioseop_description'] ); update_post_meta( $post_id, '_aioseop_title', $title ); update_post_meta( $post_id, '_aioseop_keywords', $keywords ); update_post_meta( $post_id, '_aioseop_description', $description ); } /** * メタボックスを表示 */ public function render_meta_box_content( $post ) { wp_nonce_field( 'my_seo', 'my_seo_nonce' ); $title = get_post_meta( $post->ID, '_aioseop_title', true ); $keywords = get_post_meta( $post->ID, '_aioseop_keywords', true ); $description = get_post_meta( $post->ID, '_aioseop_description', true ); ?> <table class="form-table"> <tr> <th>タイトル</th> <td><input type="text" name="_aioseop_title" value="<?php echo $title; ?>" style="width:100%; padding:5px;"></td> </tr> <tr> <th>キーワード</th> <td><input type="text" name="_aioseop_keywords" value="<?php echo $keywords; ?>" style="width:100%; padding:5px;"></td> </tr> <tr> <th>ディスクリプション</th> <td><textarea name="_aioseop_description" style="width:100%; height:100px; padding:5px;"><?php echo $description; ?></textarea></td> </tr> </table> <?php } } |
上記の例ではデフォルト投稿と固定ページのみに設置していますが、
冒頭の定数 POST_TYPES を編集すれば、その他のカスタム投稿タイプにも対応できます。
続いてフロント側です。
やることは基本的に2つだけで、pre_get_document_title フィルタを使ってタイトルタグを書き換える(※)処理と、
wp_head アクションにフックして、メタタグ類を書き出す処理です。
せっかくなので OGP 関連のタグもきっちり吐き出しておきましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
<?php /** * SEO用クラス (フロント用) * All In One SEO Pack 互換 */ class My_Seo_Front { //TOPページ用の設定 const HOME_TITLE = "トップページのタイトルです"; //デフォルト設定 const DEFAULT_DESCRIPTION = "デフォルトのディスクリプションをここに書きましょう。"; const DEFAULT_KEYWORDS = "WordPress,プラグイン,重い,遅い,高速化"; const DEFAULT_OG_IMAGE = "/img/og-image.jpg"; //Facebook用 APP ID const FACEBOOK_APP_ID = "xxxxxxxxxx"; public function __construct() { add_filter( 'pre_get_document_title', array( $this, 'seo_title' ) ); add_action( 'wp_head', array( $this, 'seo_meta' ) ); } /** * タイトルを書き換え */ public function seo_title( $title ) { if ( is_home() || is_front_page() ) { $title = self::HOME_TITLE; } elseif ( is_singular() ) { global $post; $seo_title = get_post_meta( $post->ID, '_aioseop_title', true ); if ( $seo_title ) { $title = $seo_title . ' | ' . get_bloginfo( 'name' ); } } elseif ( is_archive() ) { if ( is_category() || is_tax() ) { $term = get_queried_object(); $tax = get_taxonomy( $term->taxonomy ); $type = get_post_type_object( $tax->object_type[0] ); $title = $term->name . 'の' . $type->labels->name . '一覧'; } elseif ( is_post_type_archive() ) { $title = $type->labels->name . '一覧'; } global $wp_query; if ( $wp_query->query_vars['paged'] > 1 ) { $title .= ' (' . $wp_query->query_vars['paged'] . 'ページ目)'; } $title .= ' | ' . get_bloginfo( 'name' ); } return $title; } /** * SEO用のメタタグを出力 */ public function seo_meta() { $keywords = ""; $description = ""; $og_image = ""; $og_type = ""; $url = ""; if ( is_home() || is_front_page() ) { $og_type = 'website'; $url = home_url(); } elseif ( is_singular() ) { global $post; $keywords = get_post_meta( $post->ID, '_aioseop_keywords', true ); $description = get_post_meta( $post->ID, '_aioseop_description', true ); if ( !$description ) { $description = mb_strimwidth( strip_tags( $post->content ), 0, 140, '...' ); } $url = get_permalink( $post->ID ); if ( has_post_thumbnail( $post->ID ) ) { $og_image = get_the_post_thumbnail_url( $post->ID, array(1200, 630) ); } } if ( ! $keywords ) { $keywords = self::DEFAULT_KEYWORDS; } if ( ! $description ) { $description = self::DEFAULT_DESCRIPTION; } if ( ! $og_image ) { $og_image = get_template_directory_uri() . self::DEFAULT_OG_IMAGE; } if ( ! $og_type ) { $og_type = 'article'; } if ( ! $url ) { $uri = explode( '?', $_SERVER["REQUEST_URI"] )[0]; $url = ( empty( $_SERVER["HTTPS"] ) ? "http://" : "https://" ) . $_SERVER["HTTP_HOST"] . $uri; } ?> <link rel="canonical" href="<?php echo $url; ?>"> <meta name="keywords" value="<?php echo $keywords; ?>"> <meta name="description" value="<?php echo $description; ?>"> <meta property="og:title" content="<?php echo wp_get_document_title(); ?>" /> <meta property="og:type" content="<?php echo $og_type; ?>" /> <meta property="og:url" content="<?php echo $url; ?>" /> <meta property="og:image" content="<?php echo $og_image; ?>" /> <meta property="og:site_name" content="<?php echo get_bloginfo( 'name' ); ?>" /> <meta property="og:description" content="<?php echo $description; ?>" /> <?php if ( self::FACEBOOK_APP_ID ): ?> <meta property="fb:app_id" content="<?php echo self::FACEBOOK_APP_ID; ?>" /> <?php endif; ?> <meta name="twitter:card" content="summary_large_image" /> <?php } } |
色々と場合分けしていますが、物足りない方はもっと条件分岐を増やしてください。
特に、アーカイブ系のページが雑なので、カテゴリーやその他のタクソノミーにもメタボックスを追加して、keywords と description 入れられるようにすると尚いいですね。
また、日付アーカイブとか投稿者アーカイブとかキーワード検索とかは考慮していないので、使用している場合はIF文を増やしてください。
canonical_url をどうするかは悩ましいです。サイト構成によっては変更が必要かも。
まぁこだわり始めるとキリがないのですが、これで少なくとも All In One SEO Pack ほど重くならずに、同程度の処理ができるでしょう。
※ WP ver4.1 以上で テーマが title-tag をサポートしている(header.php 等に <title> タグを直書きしていない)ことが前提です。
※ get_the_post_thumbnail_url() を使ってるので、ver4.4以上前提です。
ver4.4未満の場合は wp_get_attachment_image_src() とかを使った昔ながらの方法に書き換えてください。
あとは、管理画面、フロントのそれぞれで、これらのクラスをインスタンス化するだけ。
1 2 3 4 5 6 7 |
if ( is_admin() ) { require_once( TEMPLATEPATH . '/includes/class-my-seo-admin.php' ); new My_Seo_Admin(); } else { require_once( TEMPLATEPATH . '/includes/class-my-seo-front.php' ); new My_Seo_Front(); } |
これでだいぶ重いのがマシになった・・・はず!