ブログのパフォーマンスチェックをやってみたところ、「余計なクエリは消してね!」って言われたので調べてみました。
問題の箇所
この赤い枠のところが余計なクエリ。バージョンが付与されているだけなので消しても動作に影響はありません。むしろこれがついていると一部のキャッシュ系プラグインが動かないとかの不具合が発生するかも?
いいねボタンとかの外部サービス系はしゃーないとして、自分のサイトに置いてるやつは対策したいところです。調べてみたところ、このあたりが有力候補に。
下のコードをfunctions.phpに記述すればいいらしいです。
// remove wp version param from any enqueued scripts
function vc_remove_wp_ver_css_js( $src ) {
if ( strpos( $src, 'ver=' ) )
$src = remove_query_arg( 'ver', $src );
return $src;
}
add_filter( 'style_loader_src', 'vc_remove_wp_ver_css_js', 9999 );
add_filter( 'script_loader_src', 'vc_remove_wp_ver_css_js', 9999 );
で、どういう処理してるのかというと
コードを見た感じ【remove_query_arg()】でvarというクエリを除去してるらしい。これがどういう動作かというと
公式のドキュメントによると以下の部分。
function remove_query_arg( $key, $query=false ) {
if ( is_array( $key ) ) { // removing multiple keys
foreach ( $key as $k )
$query = add_query_arg( $k, false, $query );
return $query;
}
return add_query_arg( $key, false, $query );
}
remove_query_arg()自体はクエリを除去する処理はしていない模様。渡された変数が文字列なら add_query_arg() 、配列ならループして add_query_arg() と、結局 add_query_arg() しかやってねぇ。肝心のクエリ除去の部分が一切ありません。そんなわけで add_query_arg() も追っかけてみました。
で、それがこちら
function add_query_arg() {
$ret = '';
$args = func_get_args();
if ( is_array( $args[0] ) ) {
if ( count( $args ) < 2 || false === $args[1] )
$uri = $_SERVER['REQUEST_URI'];
else
$uri = $args[1];
} else {
if ( count( $args ) < 3 || false === $args[2] )
$uri = $_SERVER['REQUEST_URI'];
else
$uri = $args[2];
}
if ( $frag = strstr( $uri, '#' ) )
$uri = substr( $uri, 0, -strlen( $frag ) );
else
$frag = '';
if ( 0 === stripos( 'http://', $uri ) ) {
$protocol = 'http://';
$uri = substr( $uri, 7 );
} elseif ( 0 === stripos( 'https://', $uri ) ) {
$protocol = 'https://';
$uri = substr( $uri, 8 );
} else {
$protocol = '';
}
if ( strpos( $uri, '?' ) !== false ) {
$parts = explode( '?', $uri, 2 );
if ( 1 == count( $parts ) ) {
$base = '?';
$query = $parts[0];
} else {
$base = $parts[0] . '?';
$query = $parts[1];
}
} elseif ( $protocol || strpos( $uri, '=' ) === false ) {
$base = $uri . '?';
$query = '';
} else {
$base = '';
$query = $uri;
}
wp_parse_str( $query, $qs );
$qs = urlencode_deep( $qs ); // this re-URL-encodes things that were already in the query string
if ( is_array( $args[0] ) ) {
$kayvees = $args[0];
$qs = array_merge( $qs, $kayvees );
} else {
$qs[ $args[0] ] = $args[1];
}
foreach ( $qs as $k => $v ) {
if ( $v === false )
unset( $qs[$k] );
}
$ret = build_query( $qs );
$ret = trim( $ret, '?' );
$ret = preg_replace( '#=(&|$)#', '$1', $ret );
$ret = $protocol . $base . $ret . $frag;
$ret = rtrim( $ret, '?' );
return $ret;
}
ちょっと長いコードだけど、結局のところ渡されたURL(なければ今アクセスしているURL)をバラバラにして必要なクエリだけを残して結合してるっぽい。
一度つくったURLをバラバラにするのはなんかアレだし、もっと単純にfalseにするだけでバージョン番号をなくせないかなぁと wp_register_script とか wp_enqueue_script も調べてみたけど、その方法でできない模様。なので潔く最初の記事に載っていた方法をやっときました。これでパフォーマンスチェックしても怒られなくなります。
これを行う上での危険性とか
バージョン番号がついているとキャッシュ系プラグインが対応してない場合があるかもとか冒頭に書きましたが、このバージョン番号がついてること、そして無理やりな方法でしか外せないことには理由があります。それはWordPressのコアファイルやテンプレートのアップデートの時に起こりえる不具合を回避するためです。
たとえばテンプレートが【style.css?ver=3.5.1】から【style.css?ver=3.6】にバージョンアップされたとします。バージョンアップにともないHTMLとCSSが更新されブラウザで外部から【style.css?ver=3.6】にアクセスすれば、キャッシュは存在しないため最新のCSSが読み込まれブラウザにキャッシュが作られます。
もしこの時、この記事の方法でバージョンを取り除いてしまうとどうなるでしょうか?ver=3.5.1もver=3.6も【style.css】になりますよね。するとHTMLはver 3.6になっているのに、【style.css】にアクセスするとブラウザのキャッシュに残っているver 3.5.1が読み込まれてしまい、表示がズレたり最悪ブログが正常に動作しなくなる可能性があります。
この辺りのリスクも考えて実装してくださいね☆
関連
ピンバック: GTMetrix等で使われるパフォーマンスの改善方法を全てまとめてみた【まとめ編】 | PR1SM
ピンバック: WordPress3.9 で TinyMCE に追加したボタンが動作しない じぇじぇじぇ | セルティスラボ