webentwicklung-frage-antwort-db.com.de

Wie kann ein lokaler Fallback für Font Awesome bereitgestellt werden, wenn CDN fehlschlägt?

Ich versuche, ein Wordpress-Theme zu entwickeln und herauszufinden, wie man einen lokalen Fallback für Font Awesome bereitstellt, wenn CDN fehlschlägt oder ich mein Theme auf einem lokalen Server ohne Internetverbindung entwickle.

Die Lösung, die ich vorhabe, ist ungefähr so ​​(Pseudocode):

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' );
    }

Vielen Dank!

11
Knott

Das Problem ist, dass ich ziemlich sicher bin, dass es unmöglich ist, zu überprüfen, ob CSS effektiv über PHP zu einer Seite hinzugefügt wird: CSS wird vom Browser analysiert, also clientseitig, und hat keinerlei Auswirkungen auf die Serverseite.

Natürlich kann in PHP überprüft werden, ob CDN reagiert oder nicht ...

Option 1

Senden Sie eine Anfrage, und verwenden Sie sie, wenn sie mit dem HTTP-Status 200 antwortet. So etwas wie:

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 );
}

das führt zu 2 HTTP-Anforderungen, eine für die Prüfung, die zweite für eingebettetes CSS: wirklich schlecht.

Option 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 );
    }
}

Dies ist sogar schlimmer :

  • Es ruiniert den wp_enqueue_style-Workflow: Wenn ein Plugin Font Awesome hinzufügt, wird es zweimal hinzugefügt.
  • Die Anzahl der HTTP-Anforderungen ist gleich, jedoch werden normalerweise die beiden Anforderungen parallel ausgeführt. Auf diese Weise wird die Generierung der Seite PHP verlangsamt, da auf die erste Antwort der Anforderung gewartet werden muss .
  • Dies verhindert auch, dass der Browser das CSS zwischenspeichert. Wenn Sie also denselben Stil auf verschiedenen Seiten verwenden, erzwingen Sie die CDN-Anforderung auf jeder besuchten Seite. Bei Verwendung des normalen Workflows werden die Seiten nach dem ersten CSS aus dem Cache entnommen.

Also wirklich, mach das nicht mach das zu Hause.

Was wirklich wichtig ist, ist, dass Sie mit PHP die CDN-Anforderung überprüfen können, aber nicht CSS, sodass alle Ihre Bemühungen zu einer schlechteren Leistung führen, anstatt zu einer besseren.

Mit freundlichen Grüßen, wenn es sich bei Ihrem um ein öffentliches Thema handelt, empfehle ich, dass Sie nur die lokale Kopie verwenden, um Benutzern die Möglichkeit zu geben, eine CDN auszuwählen:

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 );
    }
}

So können Benutzer die Funktion mithilfe eines untergeordneten Themas vollständig überschreiben und den 'font_awesome css_url'-Filter zum Ändern der URL verwenden.

Bedenken Sie auch, dass einige High-End-Hosting-Anbieter lokale Assets automatisch in CDN-Assets konvertieren und dass es Plugins gibt, die CDN alle Dinge ermöglichen. Aus diesem Grund sollte ein öffentliches Thema CDN überhaupt nicht verwenden.

Wenn das Thema für Sie selbst bestimmt ist, treffen Sie eine Auswahl. Bedenken Sie, dass die meisten bekannten CDNs nur einen sehr geringen Prozentsatz an Ausfallzeiten haben (und bootstrapcdn ist laut cdnperf.com eine der zuverlässigsten). Ich bin mir ziemlich sicher, dass Ihr Hosting eine um% längere Ausfallzeit aufweist als bootstrapcdn, sodass die Wahrscheinlichkeit höher ist, dass Ihre Website überhaupt nicht angezeigt wird, als dass sie mit beschädigten Symbolen angezeigt wird.

Der schmutzige Weg

Wie gesagt, PHP kann CSS nicht überprüfen, da das CSS-Rendering clientseitig erfolgt, Sie können jedoch die clientseitige Überprüfung verwenden: JavaScript.

Betten Sie zuerst CSS mit CDN ein:

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 );
} 

Fügen Sie anschließend etwas JavaScript in Ihre Fußzeile ein:

/*
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
});

Dieser Code wird beim Laden der Seite ausgeführt und überprüft, ob für den unsichtbaren Bereich, der der Fußzeile mit der Klasse 'fa' hinzugefügt wurde, die Eigenschaft font-family auf 'FontAwesome' festgelegt ist. Dies wird von Font Awesome festgelegt. Wenn dies nicht der Fall ist, wird CSS nicht geladen. In diesem Fall hängt der Code mithilfe von JavaScript das lokale CSS an head an.

(Um diesen Code zu testen, können Sie über wp_enqueue_style eine falsche CDN-URL einbetten und sehen, was passiert.)

In dem seltenen Fall, dass eine CDN nicht verfügbar ist, werden alle Stile wie erwartet angezeigt (für einige Millisekunden sehen Benutzer "kaputte" CSS-Symbole, da CSS nach dem Laden der Seite hinzugefügt wird).

Wenn man bedenkt, dass CDNs sehr zuverlässig sind, lohnt es sich, diesen Hack für die <1% der Leute durchzuführen, die kaputte Symbole sehen werden? Die Beantwortung dieser Frage bleibt Ihnen überlassen.

14
gmazzap

Eine serverseitige Überprüfung ist ebenfalls nicht kugelsicher. Befindet sich Ihr Server in Kalifornien, verwendet Ihr Scheck das Rechenzentrum des kalifornischen CDN. Wenn sich Ihr Benutzer in China befindet, wird er wahrscheinlich ein völlig anderes Rechenzentrum verwenden. Zumindest denke ich, dass es so funktioniert.

Sowieso ist hier eine verbesserte jquery Lösung:

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