web-dev-qa-db-ja.com

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

CDNが失敗したり、インターネットに接続していないローカルサーバーでテーマを開発したりする場合は、Wordpressテーマを開発し、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' );
    }

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

11
Knott

問題は、CSSがPHPを介してページに効果的に追加されているかどうかを確認するのが 不可能 であることを確信しているということです。

もちろん、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をすべて許可する plugins があると考えてください。これがパブリックテーマが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%未満にこのハッキングをする価値はありますか?この質問に答えるのはあなた次第です。

14
gmazzap

サーバー側のチェックも、防弾ではありません。サーバーがカリフォルニアにある場合、小切手はカリフォルニアの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="/css/font-awesome.min.css" rel="stylesheet">');
        }
        $span.remove();
    })(jQuery);
</script>
1
skibulk