在以 WordPress 架設的網站中通常都會有許多外掛模組(plugin)所提供的 JavaScript 檔,這些檔案都散佈在不同的位置,而且隨時可能更動,如果要讓這些 JavaScript 加上 asyncdefer,必須使用 WordPress 的 add_filter 功能,靠 PHP 程式來判斷與處理,這樣就算未來外掛模組有更動時,也會很好維護。

加入 asyncdefer

若要讓 WordPress 網站內所有的 JavaScript 引入檔都自動加入 async,可以在佈景主題(theme)中的 function.php 檔中,加入類似這樣的 filter:

# 把所有引入的 JavaScript 檔加入 async 屬性
function js_async_attr($tag){
  return str_replace( ' src', ' async="async" src', $tag );
}
add_filter( 'script_loader_tag', 'js_async_attr', 10 );

這是將所有 JavaScript 引入檔都加入 defer 的版本:

# 把所有引入的 JavaScript 檔加入 defer 屬性
function js_defer_attr($tag){
  return str_replace( ' src', ' defer="defer" src', $tag );
}
add_filter( 'script_loader_tag', 'js_defer_attr', 10 );

排除某些 JavaScript

如果想要所有的 JavaScript 引入檔都自動加入 async,但是排除某些少數的 JavaScript 檔案,就可以使用這樣的方式。

# 把所有引入的 JavaScript 檔加入 async 屬性,
# 但排除某些 JavaScript 檔
function js_async_attr($tag){

  # 排除的 JavaScript 檔
  $scripts_to_exclude = array(
    'script-name1.js',
    'script-name2.js',
    'script-name3.js');

  foreach($scripts_to_exclude as $exclude_script){
    if (true == strpos($tag, $exclude_script))
      return $tag;
  }
  return str_replace( ' src', ' async="async" src', $tag );
}
add_filter( 'script_loader_tag', 'js_async_attr', 10 );

其中 $scripts_to_exclude 就是要排除的 JavaScript 檔案列表。由於我們這裡是使用 PHP 的 strpos 函數來比對 JavaScript 檔案的,所以不見得一定要指定整個 JavaScript 全名,也可以使用重點的關鍵字,例如若要排除 foo-bar-core.jsfoo-bar-libs.js 兩個 JavaScript 檔,可以直接指定 foo-bar- 這樣的關鍵字即可。

若要加入 defer 的話,就把上面這段程式碼的 async 改為 defer 即可。

限定 JavaScript 檔

如果要對每一個 JavaScript 引入檔個別指定要是否要加入 asyncdefer 的話,就可以使用這樣的方式,這種做法可以對網站進行比較細部的校調。

# 把指定的 JavaScript 檔加入 async 或 defer 屬性
function defer_js_async($tag){

  # 要加入 defer 屬性的 JavaScript 檔
  $scripts_to_defer = array(
    'script-name1.js',
    'script-name2.js',
    'script-name3.js');

  # 要加入 async 屬性的 JavaScript 檔
  $scripts_to_async = array(
    'script-name4.js',
    'script-name5.js',
    'script-name6.js');

  # 處理 defer
  foreach($scripts_to_defer as $defer_script){
    if(true == strpos($tag, $defer_script ) )
      return str_replace( ' src', ' defer="defer" src', $tag );
  }
  # 處理 async
  foreach($scripts_to_async as $async_script){
    if(true == strpos($tag, $async_script ) )
      return str_replace( ' src', ' async="async" src', $tag );
  }
  return $tag;
}
add_filter( 'script_loader_tag', 'defer_js_async', 10 );

其中 $scripts_to_defer 與 $scripts_to_async 分別是要加入 deferasync 的 JavaScript 引入檔清單,這裡同樣可以使用重點關鍵字的方式來指定 JavaScript 檔案。

以上就是在 WordPress 中調整 JavaScript 引入檔載入的方法,善用這些技巧就可以有效提升網頁的效率,除此之外,我們還可以利用 YUI CompressorGoogle Closure Compiler 來壓縮 JavaScript 檔案,讓 JavaScript 的載入速度更快。

參考資料:Orbiting WebGrowing with the Web