CDN이 실패한 경우 Font Awesome에 대한 로컬 폴백을 제공하는 방법은 무엇입니까?


14

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

감사합니다!


@Alexan 어떻 is_readable($cdnPath)습니까?
Mayeenul Islam

@MayeenulIslam에게 감사하지만 CDN을 사용할 수 있어도 false를 반환하는 것 같습니다.
매듭

2
최소한 몇 가지 방법이 있지만 CDN을 사용하는 이유는 성능 뿐이지 만 찾은 방법으로 성능이 나빠질 것이므로 imho는 의미가 없습니다. 테마가 공유 / 판매를위한 것이라면 로컬 사본 만 사용하고 사용자가 원하는 경우 CDN 버전으로 쉽게 전환 할 수 있도록하십시오. 테마가 자신만을위한 것이라면 하나 이상을 선택하십시오. 대부분의 유명한 CDN은 가동 중지 시간의 비율이 매우 낮다는 것을 고려하십시오 ( cdnperf.com 에 따르면 bootstrapcdn은 가장 신뢰할 수있는 것 중 하나입니다 ).
gmazzap

당신은 마 일반적인 아이디어는 어떻게 선발을위한 대체 처리하기 위해? JS 폴백은 변수 확인에 의존한다는 것을 알고 있습니다 .CSS로드를 확인하는 것이 무엇인지 확실하지 않습니다.
Rarst

1
물론, 당신은 PHP에 추가 요청을하지 않을 것입니다. CSS 과제를 전혀 점검 할 수있는 좋은 방법은 생각할 수 없습니다.
Rarst

답변:


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워크 플로우 : 플러그인이 굉장 글꼴 추가하는 경우, 그것은 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은 가장 신뢰할 수있는 것 중 하나입니다 ). 나는 귀하의 호스팅이 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에 의해 설정되므로 true가 아닌 경우 CSS가로드되지 않았 음을 의미합니다. 이 경우 코드는 JavaScript를 사용하여 로컬 CSS를 추가합니다.

(이 코드를 테스트하기 wp_enqueue_style위해 잘못된 CDN URL을 통해 임베드 할 수 있습니다. )

따라서 드물게 CDN을 사용할 수없는 경우 모든 스타일이 예상대로 표시됩니다 (페이지가로드 된 후 CSS가 추가 되었기 때문에 몇 밀리 초 동안 사용자에게 '깨진'CSS 아이콘이 표시됨).

이제 CDN이 매우 안정적이라는 점을 고려하면 깨진 아이콘이 표시되는 <1 %의 사람들을 위해 해킹을 수행 할 가치가 있습니까? 이 질문에 대한 답변은 귀하에게 있습니다.


오랫동안 나는 이와 같은 주제에 대해 그렇게 복잡하고 깊은 접근법을 보지 못했습니다. 그것은 나를 완전히 지웠다. 이제 CDN을 테마 옵션으로 사용하여 사용자가 자유롭게 선택할 수 있다고 생각합니다. 감사합니다!
Knott

나는 이와 같은 해결책을 오랫동안 찾고 있었기 때문에 마지막 문장에 대해 "파손 된 아이콘을 볼 수있는 사람들의 <1 %에 대해이 해킹을하는 것이 가치가 있는가?" 로딩 스피너를 추가하면 문제가 해결 될까요?
Carl Alberto

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>

공유해 주셔서 감사합니다. 예를 들어 여기 및 다른 곳의 다른 솔루션과 달리 불가지론을 추가해야합니다.
oucil

1
시간 초과가 없으므로 CDN 인스턴스가 확인 후로드를 완료하면 Font Awesome이 두 번로드됩니다 fontFamily.
Dan Dascalescu

1
@DanDascalescu 기본적으로 CSS 파일이 동 기적으로로드되지 않습니까 (차단)? CDN이로드되거나 실패 할 때까지 페이지가 계속되지 않는다고 생각합니까?
skibulk

1
CSS는 동 기적으로로드되지만 글꼴을 사용하는 텍스트가 렌더링 될 때만 글꼴 자체가로드됩니다. 여기의 것을 보여주는 JSbin은 .
Dan Dascalescu
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.