Làm cách nào để cung cấp dự phòng cục bộ cho Font Awesome nếu CDN không thành công?


13

Tôi đang cố gắng phát triển chủ đề Wordpress và tìm ra cách cung cấp dự phòng cục bộ cho Font Awesome nếu CDN không thành công hoặc tôi phát triển chủ đề của mình trên máy chủ cục bộ không có kết nối internet.

Giải pháp tôi có trong đầu là một cái gì đó như thế này (mã giả):

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

Cảm ơn bạn!


1
Tôi sợ Câu hỏi không dành riêng cho WordPress. Có lẽ câu hỏi này phù hợp với bạn.
Mayeenul Hồi giáo

Tại sao bạn nghĩ rằng? Tôi đang nói về việc phát triển một chủ đề WordPress và các tiêu chuẩn (tf) nhất định nói rằng nếu bao gồm phiên bản CDN của thư viện, một bản sao cục bộ phải được cung cấp dưới dạng dự phòng. Dẫu sao cũng xin cảm ơn.
Knott

1
wp_enqueue_style()và làm thế nào để làm việc với nó là về chủ đề.
fuxia

2
Có - ít nhất là - một vài cách, tuy nhiên lý do duy nhất để sử dụng CDN là hiệu suất, nhưng tôi khá chắc chắn rằng bất kỳ cách nào bạn sẽ tìm thấy sẽ làm cho hiệu suất kém hơn, vì vậy imho không có ý nghĩa gì. Nếu chủ đề chỉ để chia sẻ / bán, tôi chỉ sử dụng bản sao cục bộ, hãy chắc chắn để lại cho người dùng một cách dễ dàng để chuyển sang phiên bản CDN, nếu họ thích. Nếu chủ đề chỉ dành cho chính bạn, hãy chọn cái này hoặc cái khác. Hãy xem xét rằng hầu hết các CDN nổi tiếng có% thời gian ngừng hoạt động rất thấp (và bootstrapcdn là một trong những nơi đáng tin cậy nhất, theo cdnperf.com ).
gmazzap

1
Tất nhiên rồi, bạn sẽ không bao giờ yêu cầu thêm từ PHP cho điều đó. Đó là thách thức ở đây - đối với người mới bắt đầu, tôi không thể nghĩ ra cách nào tốt để kiểm tra tải CSS.
Rarst

Câu trả lời:


14

Vấn đề là tôi khá chắc chắn rằng không thể kiểm tra xem CSS có được thêm một cách hiệu quả vào một trang thông qua PHP hay không: CSS được trình duyệt phân tích cú pháp, vì vậy phía máy khách và hoàn toàn không ảnh hưởng đến phía máy chủ.

Tất nhiên, trong PHP có thể kiểm tra xem CDN có phản hồi hay không ...

lựa chọn 1

Gửi yêu cầu và nếu nó phản hồi với trạng thái HTTP 200, hãy sử dụng nó. Cái gì đó như:

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

dẫn đến 2 yêu cầu HTTP, một cho kiểm tra, thứ hai cho CSS nhúng: thực sự tồi tệ .

Lựa chọn 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 );
    }
}

Điều này thậm chí còn tồi tệ hơn :

  • Nó phá hỏng wp_enqueue_stylequy trình làm việc: nếu một plugin thêm Font Awesome, nó sẽ được thêm 2 lần.
  • Số lượng yêu cầu HTTP là như nhau, tuy nhiên thông thường 2 yêu cầu chạy song song , do đó, theo cách này, việc tạo trang PHP bị chậm lại vì nó cần chờ phản hồi yêu cầu đầu tiên.
  • Điều này cũng ngăn trình duyệt lưu bộ nhớ cache CSS, vì vậy nếu bạn sử dụng cùng một kiểu trong các trang khác nhau, bạn buộc yêu cầu CDN trên mỗi trang được truy cập. Khi sử dụng quy trình làm việc bình thường, các trang sau CSS đầu tiên được lấy từ bộ đệm.

Vì vậy, thực sự, không làm điều này ở nhà.

Điều thực sự quan trọng là sử dụng PHP bạn có thể kiểm tra yêu cầu CDN, nhưng không xác minh CSS, vì vậy tất cả các nỗ lực của bạn kết thúc trong hiệu suất kém hơn, thay vì tốt hơn.

Trân trọng, nếu bạn là chủ đề công khai, tôi khuyên bạn chỉ nên sử dụng bản sao cục bộ, cung cấp cho người dùng cách chọn 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 );
    }
}

Vì vậy, người dùng hoàn toàn có thể ghi đè chức năng bằng cách sử dụng một chủ đề con và cũng có thể sử dụng 'font_awesome css_url'bộ lọc để thay đổi URL.

Cũng xem xét rằng một số nhà cung cấp dịch vụ lưu trữ cao cấp tự động chuyển đổi tài sản cục bộ sang CDN và có các plugin cho phép CDN tất cả mọi thứ; đây là lý do một chủ đề công cộng không nên sử dụng CDN.

Nếu chủ đề là cho chính bạn, sau đó đưa ra một lựa chọn. Hãy xem xét rằng hầu hết các CDN nổi tiếng có% thời gian ngừng hoạt động rất thấp (và bootstrapcdn là một trong những nơi đáng tin cậy nhất, theo cdnperf.com ). Tôi khá chắc chắn rằng lưu trữ của bạn có% thời gian chết lớn hơn bootstrapcdn, vì vậy mọi người có nhiều khả năng không thấy trang web của bạn hơn là nhìn thấy nó với các biểu tượng bị hỏng.

Cách bẩn

Như đã nói, PHP không thể kiểm tra CSS, vì kết xuất CSS xảy ra phía máy khách, nhưng bạn có thể sử dụng kiểm tra phía máy khách: JavaScript.

CSS nhúng đầu tiên bằng 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 );
} 

Sau đó, thêm một số JavaScript vào chân trang của bạn:

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

Mã này chạy khi trang được tải và kiểm tra xem khoảng vô hình được thêm vào chân trang với lớp 'fa' có thuộc tính họ phông chữ được đặt thành 'FontAwgie'. Điều này được đặt bởi Font Awesome, vì vậy nếu nó không đúng, điều đó có nghĩa là CSS không được tải. Nếu nó xảy ra, mã sử dụng JavaScript để nối CSS cục bộ vào đầu.

(Để kiểm tra mã này, bạn có thể nhúng qua wp_enqueue_styleURL CDN sai và xem điều gì xảy ra)

Vì vậy, trong trường hợp hiếm hoi không có CDN, tất cả các kiểu sẽ được hiển thị như mong đợi (đối với một số mili giây người dùng sẽ thấy các biểu tượng CSS 'bị hỏng', vì CSS được thêm sau khi tải trang).

Bây giờ, xem xét rằng CDN rất đáng tin cậy, có đáng để thực hiện hack này cho <1% số người sẽ thấy các biểu tượng bị hỏng không? Trả lời câu hỏi này là để lại cho bạn.


Lâu rồi tôi chưa thấy một cách tiếp cận phức tạp và sâu sắc như vậy về một chủ đề như thế này. Điều đó đã xóa tôi hoàn toàn. Bây giờ tôi đoán tôi sẽ sử dụng CDN như một tùy chọn chủ đề, để người dùng tự do lựa chọn. Cảm ơn bạn!
Knott

Tôi đã tìm kiếm một giải pháp như thế này từ lâu, vì vậy liên quan đến câu cuối cùng hỏi "có đáng để thực hiện việc hack này cho <1% số người sẽ thấy các biểu tượng bị hỏng không?" Có lẽ thêm một spinner tải sẽ làm việc ra?
Carl Alberto

1

Kiểm tra phía máy chủ cũng không phải là chống đạn. Nếu máy chủ của bạn được đặt tại California, séc của bạn sẽ sử dụng Trung tâm dữ liệu của CDN của California. Nếu người dùng của bạn ở Trung Quốc, họ có thể sẽ sử dụng Trung tâm dữ liệu hoàn toàn khác. Ít nhất, đó là cách tôi nghĩ nó hoạt động.

Dù sao, đây là một giải pháp jquery cải tiến:

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>

tuyệt vời, và một cách tiếp cận hợp lệ cho nhiều hơn so với phông chữ tuyệt vời, cảm ơn vì đã chia sẻ. Tôi nên thêm, cũng không giống như các giải pháp khác ở đây và các nơi khác trong SO chẳng hạn.
Pháp

1
Vì không có thời gian chờ, điều này sẽ kết thúc tải Font Awesome hai lần nếu phiên bản CDN kết thúc tải sau khi kiểm tra fontFamily.
Dan Dascalescu

@DanDascalescu Các tệp CSS không được tải đồng bộ (chặn) theo mặc định? Tôi tin rằng trang sẽ không tiếp tục cho đến khi CDN được tải hoặc không thành công?
skibulk

CSS không tải đồng bộ, nhưng bản thân phông chữ chỉ tải khi văn bản sử dụng được hiển thị. Đây là một JSbin cho thấy điều đó .
Dan Dascalescu
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.