Як забезпечити локальний запасний варіант для шрифту Awesome, якщо CDN не працює?


14

Я намагаюся розробити тему Wordpress і зрозуміти, як надати локальний запасний варіант для шрифту Awesome, якщо CDN не працює або я розробляю свою тему на локальному сервері без підключення до Інтернету.

Я маю на увазі таке рішення (псевдокод):

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

Дякую!


@Alexan Що про це is_readable($cdnPath)?
Mayeenul Islam

Дякуємо @MayeenulIslam, але, здається, повертає помилкові навіть CDN доступний.
Нотт

2
Існує - принаймні, кілька способів, однак єдиною причиною використання CDN є продуктивність, але я впевнений, що будь-який спосіб, який ви знайдете, погіршить роботу, тому imho не має сенсу. Якщо тема призначена для спільного використання / продажу, я б перейшов лише до локальної копії, обов'язково залишаючи користувачам простий спосіб перейти на версію CDN, якщо вони бажають. Якщо тема призначена лише для вас, виберіть ту чи іншу. Вважайте, що більшість відомих CDN мають дуже низький відсоток простою (а bootstrapcdn є одним із найнадійніших, згідно з даними cdnperf.com ).
gmazzap

Чи маєте ви загальне уявлення про те, як впоратися з резервними копіями для початківців? Я знаю, що резервні копії JS покладаються на перевірку змінних, я не впевнений, на що слід покласти перевірку завантаження CSS.
Рарст

1
Ну і звичайно, що ви робите, я ніколи б не звертався із додатковою заявою до PHP. У цьому полягає проблема - для початківців я не можу придумати гарного способу перевірити завантаження CSS.
Рарст

Відповіді:


15

Проблема полягає в тому, що я майже впевнений, що неможливо перевірити, чи CSS ефективно доданий на сторінку через PHP: 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-запитів, один для перевірки, другий для вбудованого 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робочий процес: якщо плагін додасть шрифт Awesome, він буде доданий 2 рази.
  • Кількість запитів HTTP однакова, однак зазвичай два запити працюють паралельно , тому таким чином генерація сторінки 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 мають дуже низький відсоток простою (а bootstrapcdn є одним із найнадійніших, згідно з даними cdnperf.com ). Я впевнений, що у вашого хостингу час простою на% більше, ніж на bootstrapcdn, тому люди мають більшу ймовірність взагалі не бачити ваш сайт, ніж бачити його зі зламаними значками.

Брудний шлях

Як було сказано, PHP не може перевірити CSS, оскільки відображення CSS відбувається на стороні клієнта, але ви можете використовувати перевірку на стороні клієнта: JavaScript.

Перший вбудований CSS за допомогою CDN:

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' має властивість сімейства шрифтів встановлено на 'FontAwesome'. Це встановлено Font Awesome, тому якщо це неправда, це означає, що CSS не завантажується. Якщо це сталося, код використовує JavaScript, щоб додати локальний CSS до голови.

(Для тестування цього коду можна вставити через wp_enqueue_styleнеправильну URL-адресу CDN і подивитися, що відбувається)

Так, у рідкісному випадку CDN недоступний, всі стилі будуть показані, як очікувалося (протягом декількох мілісекунд користувачі побачать «зламані» піктограми CSS, оскільки CSS додається після завантаження сторінки).

Тепер, враховуючи, що CDN дуже надійні, чи варто робити цей злом для <1% людей, які побачать зламані піктограми? Відповідь на це питання залишається вам.


Давно я не бачив такого складного та глибокого підходу до такої теми, як ця. Це мене повністю очистило. Зараз я думаю, що я буду використовувати CDN лише як варіант теми, залишаючи користувачеві свободу вибору. Дякую!
Нотт

Я довго шукав таке рішення, тож щодо останнього речення, яке запитує, "чи варто робити цей злом для <1% людей, які побачать зламані піктограми?" Можливо, додавання завантажувального спінера вийде?
Карл Альберто

2

Перевірка на стороні сервера також не захищена від кулі. Якщо ваш сервер розташований у Каліфорнії, для вашої чеки буде використано Центр даних Каліфорнії 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.
унциль

1
Оскільки немає часу очікування, це закінчиться завантаженням шрифту Awesome двічі, якщо екземпляр CDN закінчить завантаження після перевірки на fontFamily.
Дан Даскалеску

1
@DanDascalescu Чи не завантажуються файли CSS синхронно (блокуються) за замовчуванням? Я вважаю, що сторінка не буде продовжуватися, поки CDN не завантажується чи не вийде з ладу?
skibulk

1
CSS завантажується синхронно, але сам шрифт завантажується лише тоді, коли подається текст, що використовує його. Ось JSbin, що показує це .
Дан Даскалеску
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.