我有各种 javascript,它们是我的 WordPress 域之一中必需的插件,并且我知道它在 php 文件中的何处调用。
我正在采取一切措施来加快页面加载时间,网络上的每个速度测试人员都说如果可能的话推迟使用 JavaScript。
我已经阅读了有关 JavaScript 中的 defer='defer' 和 async 函数的内容,我认为其中之一将实现我想要实现的目标。但我不明白如何在 php 文件中执行此操作。
例如,下面是一个特定插件的 php 文件中调用 javascript 文件的片段:
function add_dcsnt_scripts() {
wp_enqueue_script( 'jquery' );
wp_enqueue_script( 'dcsnt', dc_jqsocialtabs::get_plugin_directory() . '/js/jquery.social.media.tabs.1.7.1.min.js' );
}
我读到最好做这样的事情来加快页面加载时间:
<script defer async src="..."></script>
但我不知道如何在 php 文件中实现这一点。我想对我所有的 javascript 文件执行此操作。
我如何实现延迟或异步此 JavaScript 代码片段到最后加载并加快页面加载时间?增加所有浏览器的页面加载时间的理想方法是什么?感谢任何人都可以提供的指导!
或更通用的方式:
function add_async_forscript($url)
{
if (strpos($url, '#asyncload')===false)
return $url;
else if (is_admin())
return str_replace('#asyncload', '', $url);
else
return str_replace('#asyncload', '', $url)."' async='async";
}
add_filter('clean_url', 'add_async_forscript', 11, 1);
因此您可以将异步添加到任何脚本而无需更改代码,只需将 #asyncload 添加到脚本 url 即可:
wp_enqueue_script('dcsnt', '/js/jquery.social.media.tabs.1.7.1.min.js#asyncload' )
为了使事情保持模块化和包容性,以下方法动态选择如何通过将一个小标识符附加到 $handle 名称来嵌入带有 async 或 defer 属性的标签:
/**
* Add async or defer attributes to script enqueues
* @author Mike Kormendy
* @param String $tag The original enqueued <script src="...> tag
* @param String $handle The registered unique name of the script
* @return String $tag The modified <script async|defer src="...> tag
*/
// only on the front-end
if(!is_admin()) {
function add_asyncdefer_attribute($tag, $handle) {
// if the unique handle/name of the registered script has 'async' in it
if (strpos($handle, 'async') !== false) {
// return the tag with the async attribute
return str_replace( '<script ', '<script async ', $tag );
}
// if the unique handle/name of the registered script has 'defer' in it
else if (strpos($handle, 'defer') !== false) {
// return the tag with the defer attribute
return str_replace( '<script ', '<script defer ', $tag );
}
// otherwise skip
else {
return $tag;
}
}
add_filter('script_loader_tag', 'add_asyncdefer_attribute', 10, 2);
}
使用示例:
function enqueue_my_scripts() {
// script to load asynchronously
wp_register_script('firstscript-async', '//www.domain.com/somescript.js', '', 2, false);
wp_enqueue_script('firstscript-async');
// script to be deferred
wp_register_script('secondscript-defer', '//www.domain.com/otherscript.js', '', 2, false);
wp_enqueue_script('secondscript-defer');
// standard script embed
wp_register_script('thirdscript', '//www.domain.com/anotherscript.js', '', 2, false);
wp_enqueue_script('thirdscript');
}
add_action('wp_enqueue_scripts', 'enqueue_my_scripts', 9999);
输出:
<script async type='text/javascript' src='//www.domain.com/somescript.js'></script>
<script defer type='text/javascript' src='//www.domain.com/otherscript.js'></script>
<script type='text/javascript' src='//www.domain.com/anothercript.js'></script>
感谢@MattKeys @crissoca 在这里启发我的回答。
这篇博客文章链接到两个感兴趣的插件:
异步Javascript
使用 head.js 异步加载 javascript 来提高页面加载性能
WP 延迟 Javascripts
使用 LABJS(异步 javascript 库)延迟加载通过 wp_enqueue_scripts 添加的所有 javascript。
还没有测试过它们,但检查了代码,它们在 WordPress 脚本排队过程中做了非常奇特的事情。
但是WPSE 来救援:
// Adapted from https://gist.github.com/toscho/1584783
add_filter( 'clean_url', function( $url ) {
if ( FALSE === strpos( $url, '.js' ) ) {
// not our file
return $url;
}
// Must be a ', not "!
return "$url' defer='defer";
}, 11, 1 );
使用不同过滤器的另一种解决方案,可用于针对特定脚本句柄:
function frontend_scripts()
{
wp_enqueue_script( 'my-unique-script-handle', 'path/to/my/script.js' );
}
add_action( 'wp_enqueue_scripts', 'frontend_script' );
function make_script_async( $tag, $handle, $src )
{
if ( 'my-unique-script-handle' != $handle ) {
return $tag;
}
return str_replace( '<script', '<script async', $tag );
}
add_filter( 'script_loader_tag', 'make_script_async', 10, 3 );
一种简化的方法。添加到你的functions.php文件中,使JavaScript在Wordpress中异步
// Make JavaScript Asynchronous in Wordpress
add_filter( 'script_loader_tag', function ( $tag, $handle ) {
if( is_admin() ) {
return $tag;
}
return str_replace( ' src', ' async src', $tag );
}, 10, 2 );
要控制要推迟的 js 文件并避免冲突,您可以将变量附加到 wp_register_script 函数中的 url,如下所示。
wp_register_script( 'menu', get_template_directory_uri() . '/js/script.js?defer', array('jquery'), '1.0', true );
然后更改行:
if ( FALSE === strpos( $url, '.js' ))
致:
if ( FALSE === strpos( $url, '.js?defer' ))
新过滤器看起来像这样。
add_filter( 'clean_url', function( $url )
{
if ( FALSE === strpos( $url, '.js?defer' ) )
{ // not our file
return $url;
}
// Must be a ', not "!
return "$url' defer='defer";
}, 11, 1 );
很少的修改代码Mike Kormendy,它允许您一次添加2个属性:
// Async load
function add_asyncdefer_attribute($tag, $handle)
{
$param = '';
if ( strpos($handle, 'async') !== false ) $param = 'async ';
if ( strpos($handle, 'defer') !== false ) $param .= 'defer ';
if ( $param )
return str_replace('<script ', '<script ' . $param, $tag);
else
return $tag;
}
结果:
<script async defer type='text/javascript' src='#URL'></script>
我认为推迟/异步 WordPress jQuery 是不好的做法。更好的解决方案是从过滤器中排除 jQuery:
if (!is_admin()) {
add_filter( 'script_loader_tag', function ( $tag, $handle ) {
if ( strpos( $tag, "jquery.js" ) || strpos( $tag, "jquery-migrate.min.js") ) {
return $tag;
}
return str_replace( ' src', ' async src', $tag );
}, 10, 2 );
}
您可以使用
defer
代替 async
将
async
属性合并到脚本中,以便仅在加载整个页面后才加载它们
<script type="text/javascript">
function ngfbJavascript( d, s, id, url ) {
var js, ngfb_js = d.getElementsByTagName( s )[0];
if ( d.getElementById( id ) ) return;
js = d.createElement( s );
js.id = id;
js.async = true;
js.src = url;
ngfb_js.parentNode.insertBefore( js, ngfb_js );
};
</script>
来源:这里
添加
clean_url
过滤器解决方案,请确保验证仅在字体端使用它,也许使用 if( ! is_admin() ){}
像 ACF 这样的流行插件可能会让你头疼。
更新
这是我的解决方案的修改版本:
if( ! is_admin() ){
add_filter( 'clean_url', 'so_18944027_front_end_defer', 11, 1 );
function so_18944027_front_end_defer( $url ) {
if ( FALSE === strpos( $url, '.js' ) )
{ // not our file
return $url;
}
// Must be a ', not "!
return "$url' defer='defer";
}
}
从 WordPress 6.3 开始,您现在可以而且应该使用
wp_enqueue_script
的第五个属性,它现在可以包含带有附加参数的数组。该属性为 strategy
,您可以使用 defer
或 async
作为值。
\wp_enqueue_script(
'dcsnt',
dc_jqsocialtabs::get_plugin_directory() . '/js/jquery.social.media.tabs.1.7.1.min.js',
[ 'jquery' ],
false,
[ 'strategy' => 'defer' ]
);