在wordpress后台,wordpress采用了一招load-scripts.php来加载核心的javascript代码,你可以在wordpress后台的html源代码中看到链接。但是有一个问题,就是每次加载的load-scripts.php的体积很大,导致后台实际上加载速度慢。在我上一篇文章中,也提到了php加载css遇到性能问题。那么怎么来解决这个问题呢?
实际上,wordpress通过load-scripts.php来加载的javascript代码,多半情况下是不会变的,输出结果是一样的。我们打开/wp-admin/load-scripts.php来看看它的源码是怎么回事。
而在源码的底部,我们可以看到这样一段代码:
header('Expires: ' . gmdate( "D, d M Y H:i:s", time() + $expires_offset ) . ' GMT'); header("Cache-Control: public, max-age=$expires_offset");
看样子wordpress试图要做一个缓存,通过Cache-Control: public来向浏览器发出缓存请求。但是可惜的是,这一缓存请求并没有被接受。我们通过chrome的调试面板去看network一栏,可以发现,每次对load-scripts.php的请求都是200响应,每次都是重新请求的资源。因此,我们要修改这个缓存,从而实现真正的浏览器缓存。把上面这两句代码替换为:
function http_header_cache($expire = '+15 minutes') { date_default_timezone_set('Etc/GMT'); header("Cache-Control: public"); header("Pragma: cache"); // 如果存在缓存,则使用缓存 if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { $last_modified = $_SERVER['HTTP_IF_MODIFIED_SINCE']; $expire = strtotime(trim("$last_modified $expire")); if($expire > time()) { header("Expires: ".gmdate("D, d M Y H:i:s",$expire)." GMT"); header("Last-Modified: $last_modified",true,304); exit; } } // 如果不存在缓存,则增加上次更新时间,从而加入缓存 header("Expires: ".gmdate("D, d M Y H:i:s",strtotime($expire))." GMT"); header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); date_default_timezone_set('PRC'); } http_header_cache($expires_offset);
这个http_header_cache函数是我的御用函数,我几乎在所有需要用到浏览器缓存的项目中都用到它。现在分享出来,解决这个问题。把上面的代码替换之后,通过header向浏览器端发送的缓存请求就实现了,第一次进入后台的时候会加载一次全部代码,而第二次请求时,直接使用浏览器缓存的内容,http响应码也变成了304。
但是,这个方法是有问题的,也就是每次wordpress升级的时候,核心文件会被覆盖,这段代码也就被升级后的wordpress核心代码覆盖掉了。那么怎么来处理这个问题呢?我们回到load-scripts.php的使用上。
在后台,为什么wordpress使用load-scripts.php来加载javascript呢?它是通过在/wp-admin/admin-header.php中的do_action( 'admin_enqueue_scripts', $hook_suffix );
这个位置的钩子输出的。所以,其实,我们是可以改变load-scripts.php的输出内容的。而最终,我们在/wp-includes/script-loader.php中找到了最终的输出函数function _print_scripts()
,在输出load-scripts.php时,竟然使用了esc_attr()
,那么我们就可以在这个位置上大做文章了。因为ecs_attr()函数的输出是有一个钩子的:attribute_escape,所以,我们就可以在这个钩子上进行处理:
add_filter('attribute_escape','change_load_scripts_filter'); function change_load_scripts_filter($url) { if(strpos($url,admin_url('load-scripts.php')) === 0) $url = '...your own url...'; return $url; }
当我们发现attribute_escape这个钩子要处理的url包含load-scripts.php时,把它替换为一个真实的javascripts.js文件,当然,这个文件得和load-scripts.php输出的内容一模一样。
2016-03-09 8638
define(‘CONCATENATE_SCRIPTS’, false); 就好了其实、
很赞👍
感谢分享