CDNが失敗した場合にFont Awesomeのローカルフォールバックを提供する方法は?


13

Wordpressテーマを開発し、CDNが失敗した場合、またはインターネットに接続せずにローカルサーバーでテーマを開発した場合にFont Awesomeのローカルフォールバックを提供する方法を見つけようとしています。

私が考えている解決策は次のようなものです(擬似コード):

if ( $CDN_IS_AVAILABLE ) { 
        wp_enqueue_style( 'font-awesome', '//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css', false );
    } else {
        wp_enqueue_style('font-awesome', get_template_directory_uri() . '/css/font-awesome/css/font-awesome.min.css', false, '4.0.3' );
    }

ありがとうございました!


1
質問はWordPress固有のものではないようです。おそらくこの質問はあなたに合っています。
Mayeenulイスラム14

なぜそう思うの?ライブラリのCDNバージョンが含まれている場合、フォールバックとしてローカルコピーを提供する必要があることを示すWordPressテーマおよび特定の(tf)標準の開発について話している。とにかくありがとう。
ノット14

1
wp_enqueue_style()そして、それをどのように扱うかは話題です。
FUXIA

2
少なくともいくつかの方法がありますが、CDNを使用する理由はパフォーマンスだけですが、あなたが見つける方法がパフォーマンスを悪化させると確信しているので、私見は意味がありません。テーマが共有/販売用である場合、ローカルコピーのみを使用します。CDNバージョンに切り替えるには、必要に応じて簡単に切り替えられるようにしてください。テーマが自分専用である場合は、いずれかを選択します。最も有名なCDNのダウンタイムの割合は非常に低いことを考慮してください(cdnperf.comによると、bootstrapcdnは最も信頼できるものの1つです)。
gmazzap

1
もちろん、あなたはそうしますが、私はそのためにPHPから余分なリクエストをすることはありません。それがここでの課題です。初心者にとっては、CSSの負荷をチェックする良い方法がまったく考えられません。
ラスト14

回答:


14

問題は、PHPを介してCSSがページに効果的に追加されているかどうかを確認できないことです。ブラウザによってCSSが解析されるため、クライアント側であり、サーバー側にはまったく効果がありません。

もちろん、PHPではCDNが応答するかどうかを確認できます...

オプション1

要求を送信し、HTTPステータス200で応答する場合は使用します。何かのようなもの:

function font_awesome_css() {
    $url = 'http://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css';
    $cdn = wp_remote_get( $url );
    if ( (int) wp_remote_retrieve_response_code( $cdn) !== 200 ) {
        $url = get_template_directory_uri() . '/css/font-awesome/css/font-awesome.min.css';
    }
    wp_enqueue_style( 'font-awesome', $url, false );
}

その結果、2つのHTTPリクエストが発生します。1つはチェック用、もう1つは埋め込みCSS用です。本当に悪いです。

オプション2

function font_awesome_css() {
    $url = 'http://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css';
    $cdn = wp_remote_get( $url );
    if ( (int) wp_remote_retrieve_response_code( $cdn ) === 200 ) {
        $css = wp_remote_retrieve_body( $cdn );
        add_action( 'wp_head', function() use( $css ) {
            $absolute = "//netdna.bootstrapcdn.com/font-awesome/4.0.3/fonts/";
            $css = str_replace( "../fonts/", $absolute, $css );
            echo '<style type="text/css">' . $css . '</style>';
        } );
    } else {
        $url = get_template_directory_uri() . '/css/font-awesome/css/font-awesome.min.css';
        wp_enqueue_style( 'font-awesome', $url, false );
    }
}

これはさらに悪いです:

  • それはwp_enqueue_styleワークフローを台無しにします:プラグインがFont Awesomeを追加する場合、2回追加されます。
  • HTTPリクエストの数は同じですが、通常は2つのリクエストが並行して実行されるため、この方法では、ページのPHP生成は最初のリクエストの応答を待つ必要があるため遅くなります。
  • これにより、ブラウザーがCSSをキャッシュすることも防止されるため、異なるページで同じスタイルを使用する場合、アクセスしたすべてのページでCDN要求を強制します。通常のワークフローを使用する場合、最初のCSSの後のページはキャッシュから取得されます。

それで、本当に、家でこれをしないでください。

本当に重要なのは、PHPを使用すると、CDNリクエストをチェックできるが、CSSを検証できないため、すべての努力がパフォーマンスの向上ではなく、パフォーマンスの低下につながることです。

心から、もしあなたのものが公開テーマなら、私はあなたがローカルコピーのみを使用することを提案します。そして、ユーザーにCDNを選ぶ方法を提供します:

if ( ! function_exists( 'font_awesome_css' ) ) {
    function font_awesome_css() {
        $_url = get_template_directory_uri() . '/css/font-awesome/css/font-awesome.min.css';
        $url = apply_filters( 'font_awesome_css_url', $_url );
        wp_enqueue_style( 'font-awesome', $url, false );
    }
}

そのため、ユーザーは子テーマを使用して関数を完全にオーバーライドでき、'font_awesome css_url'フィルターを使用してURLを変更することもできます。

また、一部のハイエンドホスティングプロバイダーはローカルアセットをCDNに自動的に変換し、CDNをすべて許可するプラグインがあることも考慮してください。これが、パブリックテーマでCDNをまったく使用しない理由です。

テーマが自分用である場合は、選択を行います。最も有名なCDNのダウンタイムの割合は非常に低いことを考慮してください(cdnperf.comによると、bootstrapcdnは最も信頼できるものの1つです)。あなたのホスティングはbootstrapcdnよりも長いダウンタイム%を持っているので、壊れたアイコンで見るよりも、あなたのサイトがまったく見えない可能性が高いと確信しています。

汚い方法

前述のように、CSSレンダリングはクライアント側で行われるため、PHPはCSSをチェックできませんが、クライアント側のチェックであるJavaScriptを使用できます。

CDNを使用して最初にCSSを埋め込みます。

function font_awesome_css() {
    $url =  '//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css';
    wp_enqueue_style( 'font-awesome', $url, false );
} 

その後、フッターにJavaScriptを追加します。

/*
Normally the JS should be properly enqueued and the URL
passed via wp_enqueue_script, but this is a proof of concept,
more than real code.
*/
add_action( 'wp_footer', function() {
    $cssurl = get_template_directory_uri() . '/css/';
    ?>
    <span id="facheck" data-cssuri="<?php echo $cssurl; ?>" class="fa" style="display:none">
    </span>
    <script>
        jQuery(document).ready(function($) {
            var $check = $('#facheck');
            if ( $check.css('fontFamily') !== 'FontAwesome' ) {
                // Font Awesome not loaded!
                // Remove current CSS link
                $('#font-awesome-css').remove;
                // Add the local version
                var local = '<link rel="stylesheet" type="text/css" href="' +
                    $check.data('cssuri') + // This is the theme CSS folder URL
                    'font-awesome/css/font-awesome.min.css" />';
                $('head').append( local );
            }
        });
    </script>
    <?php
});

このコードは、ページがロードされたときに実行され、クラス「fa」のフッターに追加された非表示のスパンのfont-familyプロパティが「FontAwesome」に設定されているかどうかを確認します。これはFont Awesomeによって設定されるため、そうでない場合は、CSSがロードされていないことを意味します。その場合、コードはJavaScriptを使用してローカルCSSを先頭に追加します。

(このコードをテストするにはwp_enqueue_style、間違ったCDN URL を使用して埋め込み、何が起こるかを確認します)

そのため、まれにCDNが使用できない場合、すべてのスタイルが期待どおりに表示されます(CSSはページの読み込み後に追加されるため、数ミリ秒の間、ユーザーに「壊れた」CSSアイコンが表示されます)。

さて、CDNは非常に信頼性が高いことを考えると、壊れたアイコンが表示される人の1%未満に対してこのハックを行う価値がありますか?この質問に答えるのはあなた次第です。


長い間、私はこのようなトピックに関するそのような複雑で深いアプローチを見ていません。それは完全に私をクリアしました。ここで、テーマオプションとしてCDNを使用し、ユーザーが自由に選択できるようにします。ありがとうございました!
ノット14

私はこのような解決策を長い間探していたので、「壊れたアイコンが表示される人の1%未満に対してこのハックを行う価値はありますか?」ロードスピナーを追加するとうまくいくのでしょうか?
カールアルベルト

1

サーバー側のチェックも防弾ではありません。サーバーがカリフォルニアにある場合、小切手はカリフォルニアCDNのデータセンターを使用します。ユーザーが中国にいる場合は、まったく異なるデータセンターを使用している可能性があります。少なくとも、それは私がそれが働くと思う方法です。

とにかく、改善されたjqueryソリューションを次に示します。

http://jsfiddle.net/skibulk/fp1gqnyc/

<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet">
<script>
    (function($){
        var $span = $('<span class="fa" style="display:none"></span>').appendTo('body');
        if ($span.css('fontFamily') !== 'FontAwesome' ) {
            // Fallback Link
            $('head').append('<link href="/wordpress//css/font-awesome.min.css" rel="stylesheet">');
        }
        $span.remove();
    })(jQuery);
</script>

素晴らしい、そしてフォントよりもはるかに多くのための有効なアプローチ、共有してくれてありがとう。たとえば、ここや他のSOの他のソリューションとは異なり、不可知論者も追加する必要があります。
oucil

1
タイムアウトがないため、CDNインスタンスがのチェック後に読み込みを完了した場合、これによりFont Awesomeが2回読み込まれfontFamilyます。
ダンダスカレスク

@DanDascalescuデフォルトでは、CSSファイルは同期的にロード(ブロック)されていませんか?CDNがロードされるか失敗するまで、ページは継続しないと思いますか?
skibulk

CSSは同期的にロードしますが、フォント自体は、それを使用するテキストがレンダリングされるときにのみロードされます。ここだことを示すJSbinが
ダンダスカレスク
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.