Gravatar 官方伺服器位於國外,受 GFW 影響國內訪問極慢,嚴重拖慢頁面載入。本文提供三層遞進的解決方案:基礎緩存、Email 預檢、完整優化版,徹底解決頭像載入慢問題。
function my_avatar($avatar) {
$tmp = strpos($avatar, 'http');
$g = substr($avatar, $tmp, strpos($avatar, "'", $tmp) - $tmp);
$tmp = strpos($g, 'avatar/') + 7;
$f = substr($g, $tmp, strpos($g, "?", $tmp) - $tmp);
$w = get_bloginfo('wpurl');
$e = ABSPATH . 'avatar/' . $f . '.jpg';
$t = 1209600; // 14 天
if (!is_file($e) || (time() - filemtime($e)) > $t) {
copy(htmlspecialchars_decode($g), $e);
} else {
$avatar = strtr($avatar, array($g => $w . '/avatar/' . $f . '.jpg'));
}
// 檔案過小視為無效,替換為預設頭像
if (filesize($e) < 500) copy($w . '/avatar/default.jpg', $e);
return $avatar;
}
add_filter('get_avatar', 'my_avatar');
avatar/ 資料夾,權限 0755(或 0777)default.jpg 放入該資料夾functions.phpfunction validate_gravatar($email) {
$hash = md5(strtolower(trim($email)));
$uri = 'https://www.gravatar.com/avatar/' . $hash . '?d=404';
$headers = @get_headers($uri);
return (preg_match("|200|", $headers[0])) ? true : false;
}
用法:if (validate_gravatar($email)) echo get_avatar($email); else echo '本地預設頭像';
function my_avatar($email, $size = '32', $default = '', $alt = '') {
$f = md5(strtolower($email));
// 路徑配置:緩存到主題目錄下的 avatar/ 資料夾
$a = get_bloginfo('template_url') . '/avatar/' . $f . $size . '.png'; // URL
$e = get_template_directory() . '/avatar/' . $f . $size . '.png'; // 實體路徑
$d = get_template_directory() . '/avatar/' . $f . '-d.png'; // 無頭像標記檔
if ($default == '') $default = get_bloginfo('wpurl') . '/avatar/default.jpg';
$t = 2592000; // 30 天緩存
// 本地緩存不存在或過期
if (!is_file($e) || (time() - filemtime($e)) > $t) {
// 無頭像標記不存在或過期 → 驗證遠端
if (!is_file($d) || (time() - filemtime($d)) > $t) {
$uri = 'https://www.gravatar.com/avatar/' . $f . '?d=404';
$headers = @get_headers($uri);
if (!preg_match("|200|", $headers[0])) {
// 無頭像:建立空標記檔,避免重複請求
$handle = fopen($d, 'w'); fclose($handle);
$a = $default;
} else {
// 有頭像:下載並緩存
$r = get_option('avatar_rating');
$g = 'https://www.gravatar.com/avatar/' . $f . '?s=' . $size . '&r=' . $r;
copy($g, $e);
}
} else {
// 有無頭像標記 → 直接用預設
$a = $default;
}
}
$avatar = "<img alt='{$alt}' src='{$a}' class='avatar avatar-{$size} photo' height='{$size}' width='{$size}' />";
return apply_filters('my_avatar', $avatar, $email, $size, $default, $alt);
}
// 原來
get_avatar($comment, 48);
// 改為
my_avatar($comment->comment_author_email, 48);
// 或
my_avatar($comment, 48); // 需修改函數第一參數判斷型別
| 方案 | 遠端請求 | 預設頭像重複 | 緩存策略 | 適用場景 |
|---|---|---|---|---|
| 基礎版 | 每新用戶一次 | 會產生多個 default.jpg | 14 天 | 簡單部落格 |
| 優化版 | 首次驗證+下載 | 空標記檔機制完全避免 | 30 天 | 高流量站點 |
https://www.gravatar.com 改為 https://secure.gravatar.com 或 https://cn.gravatar.com(國內鏡像)avatar/ 目錄掛載到 CDN 或對象儲存(OSS/S3)imagewebp()核心原則:以空間換時間、以標記檔換請求。優化版通過
-d.png標記檔徹底解決「無頭像用戶重複請求 404」與「預設頭像產生大量重複檔案」兩大痛點。