development

JavaScript 앞에 CSS를 포함하라는 권장 사항이 유효하지 않습니까?

big-blog 2020. 9. 28. 09:32
반응형

JavaScript 앞에 CSS를 포함하라는 권장 사항이 유효하지 않습니까?


온라인의 수많은 곳에서 JavaScript 이전에 CSS를 포함하라는 권장 사항을 보았습니다. 그 이유는 일반적으로 다음 과 같은 형식입니다 .

CSS와 자바 스크립트를 주문할 때 CSS가 먼저 나오기를 원합니다. 그 이유는 렌더링 스레드에 페이지를 렌더링하는 데 필요한 모든 스타일 정보가 있기 때문입니다. JavaScript 포함이 먼저 오는 경우 JavaScript 엔진은 다음 리소스 세트로 계속 진행하기 전에 모든 것을 구문 분석해야합니다. 이것은 렌더링 스레드가 필요한 모든 스타일을 가지고 있지 않기 때문에 페이지를 완전히 표시 할 수 없음을 의미합니다.

내 실제 테스트는 매우 다른 것을 보여줍니다.

내 테스트 하네스

다음 Ruby 스크립트를 사용하여 다양한 리소스에 대한 특정 지연을 생성합니다.

require 'rubygems'
require 'eventmachine'
require 'evma_httpserver'
require 'date'

class Handler  < EventMachine::Connection
  include EventMachine::HttpServer

  def process_http_request
    resp = EventMachine::DelegatedHttpResponse.new( self )

    return unless @http_query_string

    path = @http_path_info
    array = @http_query_string.split("&").map{|s| s.split("=")}.flatten
    parsed = Hash[*array]

    delay = parsed["delay"].to_i / 1000.0
    jsdelay = parsed["jsdelay"].to_i

    delay = 5 if (delay > 5)
    jsdelay = 5000 if (jsdelay > 5000)

    delay = 0 if (delay < 0) 
    jsdelay = 0 if (jsdelay < 0)

    # Block which fulfills the request
    operation = proc do
      sleep delay 

      if path.match(/.js$/)
        resp.status = 200
        resp.headers["Content-Type"] = "text/javascript"
        resp.content = "(function(){
            var start = new Date();
            while(new Date() - start < #{jsdelay}){}
          })();"
      end
      if path.match(/.css$/)
        resp.status = 200
        resp.headers["Content-Type"] = "text/css"
        resp.content = "body {font-size: 50px;}"
      end
    end

    # Callback block to execute once the request is fulfilled
    callback = proc do |res|
        resp.send_response
    end

    # Let the thread pool (20 Ruby threads) handle request
    EM.defer(operation, callback)
  end
end

EventMachine::run {
  EventMachine::start_server("0.0.0.0", 8081, Handler)
  puts "Listening..."
}

위의 미니 서버를 사용하면 JavaScript 파일 (서버 및 클라이언트 모두) 및 임의 CSS 지연에 대해 임의의 지연을 설정할 수 있습니다. 예를 들어, http://10.0.0.50:8081/test.css?delay=500CSS 전송이 500ms 지연됩니다.

다음 페이지를 사용하여 테스트합니다.

<!DOCTYPE html>
<html>
  <head>
      <title>test</title>
      <script type='text/javascript'>
          var startTime = new Date();
      </script>
      <link href="http://10.0.0.50:8081/test.css?delay=500" type="text/css" rel="stylesheet">
      <script type="text/javascript" src="http://10.0.0.50:8081/test2.js?delay=400&amp;jsdelay=1000"></script> 
  </head>
  <body>
    <p>
      Elapsed time is: 
      <script type='text/javascript'>
        document.write(new Date() - startTime);
      </script>
    </p>    
  </body>
</html>

CSS를 먼저 포함하면 페이지를 렌더링하는 데 1.5 초가 걸립니다.

CSS 우선

JavaScript를 먼저 포함하면 페이지를 렌더링하는 데 1.4 초가 걸립니다.

자바 스크립트 우선

Chrome, Firefox 및 Internet Explorer에서 비슷한 결과를 얻습니다. 그러나 Opera에서는 순서가 중요하지 않습니다.

일어나는 것처럼 보이는 것은 모든 CSS가 다운로드 될 때까지 JavaScript 인터프리터가 시작을 거부한다는 것입니다. 따라서 JavaScript 스레드가 더 많은 런타임을 얻음에 따라 JavaScript 포함을 먼저 사용하는 것이 더 효율적으로 보입니다.

내가 뭔가를 놓치고 있습니까? JavaScript 포함 전에 CSS 포함을 배치하라는 권장 사항이 올바르지 않습니까?

비동기를 추가하거나 setTimeout을 사용하여 렌더링 스레드를 비우거나 바닥 글에 JavaScript 코드를 넣거나 JavaScript 로더를 사용할 수 있다는 것은 분명합니다. 여기서 요점은 머리에서 필수 JavaScript 비트와 CSS 비트의 순서에 관한 것입니다.


이것은 매우 흥미로운 질문입니다. "나는 한 번 더 낫다고 읽었 기 때문에"나는 항상 내 CSS를 <link href="...">JS 앞에 두었습니다 <script src="...">. 그래서, 당신이 옳습니다. 실제 조사를 할 때입니다!

Node에서 자체 테스트 하네스를 설정했습니다 (아래 코드). 기본적으로 나는 :

  • HTTP 캐싱이 없는지 확인하여 페이지가로드 될 때마다 브라우저가 전체 다운로드를 수행해야합니다.
  • 현실을 시뮬레이션하기 위해 jQuery와 H5BP CSS를 포함했습니다 (따라서 구문 분석 할 스크립트 / CSS의 양이 적당합니다 ).
  • 두 페이지를 설정합니다. 하나는 스크립트 이전에 CSS를 사용하고 다른 하나는 스크립트 이후에 CSS를 사용합니다.
  • 의 외부 스크립트 <head>를 실행 하는 데 걸린 시간을 기록했습니다.
  • 의 인라인 스크립트 <body>를 실행 하는 데 걸린 시간을 기록 했습니다 DOMReady. 이는 .
  • 브라우저에 CSS 및 / 또는 스크립트 전송을 500ms 지연했습니다.
  • 3 개의 주요 브라우저에서 테스트를 20 회 실행했습니다.

결과

먼저 CSS 파일이 500ms 지연된 경우 :

     Browser: Chrome 18    | IE 9         | Firefox 9
         CSS: first  last  | first  last  | first last
=======================================================
Header Exec |              |              |
Average     | 583ms  36ms  | 559ms  42ms  | 565ms 49ms
St Dev      | 15ms   12ms  | 9ms    7ms   | 13ms  6ms
------------|--------------|--------------|------------
Body Exec   |              |              |
Average     | 584ms  521ms | 559ms  513ms | 565ms 519ms
St Dev      | 15ms   9ms   | 9ms    5ms   | 13ms  7ms

다음으로 CSS 대신 500ms 지연되도록 jQuery를 설정했습니다.

     Browser: Chrome 18    | IE 9         | Firefox 9
         CSS: first  last  | first  last  | first last
=======================================================
Header Exec |              |              |
Average     | 597ms  556ms | 562ms  559ms | 564ms 564ms
St Dev      | 14ms   12ms  | 11ms   7ms   | 8ms   8ms
------------|--------------|--------------|------------
Body Exec   |              |              |
Average     | 598ms  557ms | 563ms  560ms | 564ms 565ms
St Dev      | 14ms   12ms  | 10ms   7ms   | 8ms   8ms

마지막으로 jQuery와 CSS를 모두 500ms 지연하도록 설정했습니다.

     Browser: Chrome 18    | IE 9         | Firefox 9
         CSS: first  last  | first  last  | first last
=======================================================
Header Exec |              |              |
Average     | 620ms  560ms | 577ms  577ms | 571ms 567ms
St Dev      | 16ms   11ms  | 19ms   9ms   | 9ms   10ms
------------|--------------|--------------|------------
Body Exec   |              |              |
Average     | 623ms  561ms | 578ms  580ms | 571ms 568ms
St Dev      | 18ms   11ms  | 19ms   9ms   | 9ms   10ms

결론

첫째, <head>문서의 끝에 스크립트가 있다는 가정하에 작업하고 있다는 점에 유의하는 것이 중요합니다 ( <body>). <head>문서의 끝과 끝 에서 스크립트에 연결하는 이유에 대한 다양한 주장이 있지만이 답변의 범위를 벗어납니다. 이것은 <script>s가 <link>s에서 s 앞에 와야 하는지 여부 에 관한 것 <head>입니다.

최신 데스크톱 브라우저에서는 CSS에 연결하는 것이 성능 향상을 제공 하지 않는 것처럼 보입니다 . 스크립트 뒤에 CSS를 배치하면 CSS와 스크립트가 모두 지연 될 때 약간의 이득을 얻지 만 CSS가 지연되면 큰 이득을 얻을 수 있습니다. ( last첫 번째 결과 집합의 열로 표시됩니다 .)

마지막으로 CSS에 연결하면 성능이 저하되지 않지만 특정 상황에서 이점을 제공 할 수 있으므로 이전 브라우저의 성능이 문제가되지 않는 경우 데스크톱 브라우저에서만 외부 스크립트에 연결 한 후 외부 스타일 시트에 연결해야합니다 . 모바일 상황에 대해 읽어보십시오.

왜?

역사적으로 브라우저가 <script>외부 리소스를 가리키는 태그를 발견 하면 브라우저는 HTML 구문 분석 중지 하고 스크립트를 검색하고 실행 한 다음 HTML 구문 분석을 계속했습니다. 반대로 브라우저가 <link>외부 스타일 시트에 대해를 발견 하면 CSS 파일을 가져 오는 동안 (병렬로) HTML을 계속 구문 분석합니다.

따라서 스타일 시트를 먼저 배치하라는 널리 반복되는 조언은 먼저 다운로드하고 다운로드 할 첫 번째 스크립트를 병렬로로드 할 수 있습니다.

그러나 최신 브라우저 (위에서 테스트 한 모든 브라우저 포함)는 브라우저가 HTML에서 "앞으로보고" 스크립트를 다운로드하고 실행 하기 전에 리소스 다운로드 하기 시작 하는 추측 파싱 을 구현했습니다 .

추측 파싱이없는 오래된 브라우저에서는 스크립트를 먼저 배치하면 병렬로 다운로드되지 않으므로 성능에 영향을 미칩니다.

브라우저 지원

추측 파싱은 다음에서 처음 구현되었습니다. (2012 년 1 월 현재이 버전 이상을 사용하는 전 세계 데스크톱 브라우저 사용자의 비율과 함께)

  • Chrome 1 (WebKit 525) (100 %)
  • IE 8 (75 %)
  • Firefox 3.5 (96 %)
  • Safari 4 (99 %)
  • 오페라 11.60 (85 %)

현재 사용중인 데스크톱 브라우저의 약 85 %가 예측로드를 지원합니다. CSS 앞에 스크립트를 넣으면 전 세계 사용자의 15 %에 대한 성능 저하가 발생 합니다 . 사이트의 특정 잠재 고객을 기반으로 한 YMMV. (그리고 숫자가 줄어들고 있음을 기억하십시오.)

모바일 브라우저에서는 모바일 브라우저와 OS 환경이 얼마나 이질적인 지로 인해 정확한 수치를 얻는 것이 조금 더 어렵습니다. 추측 적 렌더링이 WebKit 525 (2008 년 3 월 출시)에서 구현되었고 거의 모든 가치있는 모바일 브라우저가 WebKit을 기반으로했기 때문에 "대부분의"모바일 브라우저 가이를 지원 해야한다고 결론을 내릴 수 있습니다 . quirksmode 에 따르면 iOS 2.2 / Android 1.0은 WebKit 525를 사용합니다. Windows Phone이 어떻게 생겼는지 모르겠습니다.

하지만 내 Android 4 기기에서 테스트를 실행했는데 데스크톱 결과와 비슷한 수치를 보았지만 Android 용 Chrome 의 환상적인 새 원격 디버거 에 연결했고 네트워크 탭에 브라우저가 실제로 다운로드를 기다리고 있음이 표시되었습니다. 즉, 최신 버전의 Android 용 WebKit조차도 추론 적 구문 분석을 지원하지 않는 것으로 보입니다. 모바일 장치에 내재 된 CPU, 메모리 및 / 또는 네트워크 제약으로 인해 꺼져있을 수 있습니다.

암호

엉성함을 용서하십시오 – 이것은 Q & D였습니다.

app.js

var express = require('express')
, app = express.createServer()
, fs = require('fs');

app.listen(90);

var file={};
fs.readdirSync('.').forEach(function(f) {
    console.log(f)
    file[f] = fs.readFileSync(f);
    if (f != 'jquery.js' && f != 'style.css') app.get('/' + f, function(req,res) {
        res.contentType(f);
        res.send(file[f]);
    });
});


app.get('/jquery.js', function(req,res) {
    setTimeout(function() {
        res.contentType('text/javascript');
        res.send(file['jquery.js']);
    }, 500);
});

app.get('/style.css', function(req,res) {
    setTimeout(function() {
        res.contentType('text/css');
        res.send(file['style.css']);
    }, 500);
});


var headresults={
    css: [],
    js: []
}, bodyresults={
    css: [],
    js: []
}
app.post('/result/:type/:time/:exec', function(req,res) {
    headresults[req.params.type].push(parseInt(req.params.time, 10));
    bodyresults[req.params.type].push(parseInt(req.params.exec, 10));
    res.end();
});

app.get('/result/:type', function(req,res) {
    var o = '';
    headresults[req.params.type].forEach(function(i) {
        o+='\n' + i;
    });
    o+='\n';
    bodyresults[req.params.type].forEach(function(i) {
        o+='\n' + i;
    });
    res.send(o);
});

css.html

<!DOCTYPE html>
<html>
    <head>
        <title>CSS first</title>
        <script>var start = Date.now();</script>
        <link rel="stylesheet" href="style.css">
        <script src="jquery.js"></script>
        <script src="test.js"></script>
    </head>
    <body>
        <script>document.write(jsload - start);bodyexec=Date.now()</script>
    </body>
</html>

js.html

<!DOCTYPE html>
<html>
    <head>
        <title>CSS first</title>
        <script>var start = Date.now();</script>
        <script src="jquery.js"></script>
        <script src="test.js"></script>
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
        <script>document.write(jsload - start);bodyexec=Date.now()</script>
    </body>
</html>

test.js

var jsload = Date.now();


$(function() {
    $.post('/result' + location.pathname.replace('.html','') + '/' + (jsload - start) + '/' + (bodyexec - start));
});

jquery.js는 jquery-1.7.1.min.js였습니다.


JavaScript 앞에 CSS를 두는 주된 이유는 두 가지입니다.

  1. 이전 브라우저 (Internet Explorer 6-7, Firefox 2 등)는 스크립트 다운로드를 시작할 때 모든 후속 다운로드를 차단했습니다. 따라서 a.js다음 단계를 수행 하면 b.css순차적으로 다운로드됩니다. 먼저 a 다음 b. 다음을 b.css수행 a.js하면 페이지가 더 빨리로드되도록 병렬로 다운로드됩니다.

  2. 모든 스타일 시트가 다운로드 될 때까지 아무 것도 렌더링되지 않습니다. 이는 모든 브라우저에서 마찬가지입니다. 스크립트는 다릅니다 . 페이지 의 스크립트 태그 아래에있는 모든 DOM 요소의 렌더링을 차단 합니다. 스크립트를 HEAD에 넣으면 모든 스타일 시트와 모든 스크립트가 다운로드 될 때까지 전체 페이지가 렌더링되지 않도록 차단됩니다. 스타일 시트에 대한 모든 렌더링을 차단하는 것이 타당하지만 (그러므로 처음에는 올바른 스타일을 얻고 스타일이 지정되지 않은 콘텐츠 FOUC의 플래시를 피할 수 있습니다) 스크립트에 대한 전체 페이지 렌더링을 차단하는 것은 의미가 없습니다. 종종 스크립트는 DOM 요소 또는 DOM 요소의 일부에만 영향을주지 않습니다. 페이지에서 가능한 한 낮은 스크립트를로드하거나 비동기 적으로로드하는 것이 가장 좋습니다.

Cuzillion으로 예제를 만드는 것은 재미 있습니다 . 예를 들어, 이 페이지 에는 HEAD에 스크립트가 있으므로 다운로드가 완료 될 때까지 전체 페이지가 비어 있습니다. 그러나 스크립트를 BODY 블록의 끝으로 이동하면 이 페이지에서 볼 수 있듯이 해당 DOM 요소가 SCRIPT 태그 위에 발생하므로 페이지 헤더가 렌더링 됩니다 .


나는 당신이 얻은 결과에 대해 너무 강조하지 않고 주관적이라고 생각하지만 CSS를 js보다 먼저 넣는 것이 더 낫다고 설명 할 이유가 있습니다.

웹 사이트를로드하는 동안 다음과 같은 두 가지 시나리오가 표시됩니다.

사례 1 : 흰색 화면> 스타일이 지정되지 않은 웹 사이트> 스타일이 지정된 웹 사이트> 상호 작용> 스타일이 지정된 대화 형 웹 사이트

사례 2 : 흰색 화면> 스타일이 지정되지 않은 웹 사이트> 상호 작용> 스타일이 지정된 웹 사이트> 스타일이 지정된 대화 형 웹 사이트


솔직히 사례 2를 선택하는 사람을 상상할 수 없습니다. 느린 인터넷 연결을 사용하는 방문자는 스타일이 지정되지 않은 웹 사이트에 직면하게되므로 자바 스크립트를 사용하여 상호 작용할 수 있습니다 (이미로드되었으므로). 또한, 스타일이 지정되지 않은 웹 사이트를 보는 데 소요되는 시간은 이러한 방식으로 최대화됩니다. 왜 그걸 원 하겠어요?

또한 jQuery 상태 로 더 잘 작동합니다.

"CSS 스타일 속성의 값에 의존하는 스크립트를 사용할 때는 스크립트를 참조하기 전에 외부 스타일 시트를 참조하거나 스타일 요소를 포함하는 것이 중요합니다."

파일이 잘못된 순서 (첫 번째 JS, 그다음 CSS)로로드되면 CSS 파일에 설정된 속성 (예 : div의 너비 또는 높이)에 의존하는 모든 자바 스크립트 코드가 올바르게로드되지 않습니다. 로드 순서가 잘못되면 올바른 속성이 Javascript에 '때때로'알려진 것 같습니다 (아마도 경쟁 조건으로 인해 발생합니까?). 이 효과는 사용하는 브라우저에 따라 더 크거나 작아 보입니다.


테스트가 개인용 컴퓨터에서 수행 되었습니까, 아니면 웹 서버에서 수행 되었습니까? 빈 페이지입니까, 아니면 이미지, 데이터베이스 등이있는 복잡한 온라인 시스템입니까? 스크립트가 간단한 호버 이벤트 작업을 수행하고 있습니까? 아니면 웹 사이트가 렌더링되고 사용자와 상호 작용하는 방식의 핵심 구성 요소입니까? 여기서 고려해야 할 몇 가지 사항이 있으며 이러한 권장 사항의 관련성은 높은 수준의 웹 개발에 참여할 때 거의 항상 규칙이됩니다.

규칙은 "하단에서 상단과 스크립트에 넣어 스타일"의 목적은 즉, 일반적으로 최적 달성하기 위해 가장 좋은 방법이다 진보적 인 렌더링 , 사용자 경험에 매우 중요합니다.

다른 모든 것은 제쳐두고 : 테스트가 유효하고 실제로 인기있는 규칙에 반하는 결과를 생성한다고 가정하면 실제로는 놀라운 일이 아닙니다. 모든 웹 사이트 (및 모든 것이 사용자 화면에 나타나도록하는 데 필요한 모든 것)는 다르며 인터넷은 지속적으로 진화하고 있습니다.


다른 이유로 Javascript 앞에 CSS 파일을 포함합니다.

내 Javascript가 일부 페이지 요소의 동적 크기 조정을 수행해야하는 경우 (CSS가 실제로 뒷면의 주요 요소 인 코너 케이스에 대해) JS가 russing 된 후 CSS를로드하면 CSS 스타일보다 먼저 요소의 크기가 조정되는 경쟁 조건이 발생할 수 있습니다. 적용되어 스타일이 마침내 시작될 때 이상해 보입니다. CSS를 미리로드하면 의도 한 순서대로 실행되고 최종 레이아웃이 원하는대로 실행되도록 보장 할 수 있습니다.


JavaScript 앞에 CSS를 포함하라는 권장 사항이 유효하지 않습니까?

단순히 권장 사항으로 취급하면 아닙니다. 그러나 당신이 그것을 단단하고 빠른 규칙으로 취급한다면 그것은 유효하지 않습니다.

에서 https://developer.mozilla.org/en-US/docs/Web/Reference/Events/DOMContentLoaded

스타일 시트는 블록 스크립트 실행을로드하므로, <script>이후 <link rel="stylesheet" ...>페이지가 파싱을 완료하지 않으면 스타일 시트가로드 될 때까지 DOMContentLoaded가 실행되지 않습니다.

각 스크립트가 무엇에 의존하는지 알고 스크립트 실행이 올바른 완료 이벤트 이후까지 지연되는지 확인해야하는 것으로 보입니다. 스크립트가 DOM에만 의존하는 경우 ondomready / domcontentloaded에서 재개 할 수 있습니다.로드 할 이미지 또는 적용 할 스타일 시트에 의존하는 경우 위의 참조를 올바르게 읽으면 해당 코드를 onload 이벤트까지 연기해야합니다.

나는 그것이 그들이 판매되는 방식 임에도 불구하고 하나의 양말 크기가 모든 것에 적합하다고 생각하지 않으며 하나의 신발 크기가 모든 것에 적합하지 않다는 것을 알고 있습니다. 먼저로드 할 스타일이나 스크립트에 대한 확실한 답이 없다고 생각합니다. 어떤 순서로로드되어야하는지 그리고 나중에 "중요한 경로"에 있지 않은 것으로 연기 할 수있는 것은 사례별로 결정됩니다.

시트가 예뻐질 때까지 사용자의 상호 작용 능력을 지연시키는 것이 더 낫다고 언급 한 관찰자와 대화하기. 거기에는 많은 사람들이 있고 반대를 느끼는 상대방을 짜증나게합니다. 그들은 목적을 달성하기 위해 사이트를 찾았고,로드가 끝나는 데 중요하지 않은 일을 기다리는 동안 사이트와 상호 작용하는 능력이 지연되는 것은 매우 실망스러운 일입니다. 나는 당신이 틀렸다고 말하는 것이 아니라, 당신의 우선 순위를 공유하지 않는 또 다른 파벌이 존재한다는 것을 알아야만합니다.

이 질문은 특히 웹 사이트에 게재되는 모든 광고에 적용됩니다. 사이트 작성자가 광고 콘텐츠에 대한 자리 표시 자 div 만 렌더링하고 onload 이벤트에 광고를 삽입하기 전에 사이트가로드되고 상호 작용하는지 확인했다면 좋겠습니다. 그럼에도 불구하고 나는 광고가 부풀어 오르는 동안 사이트 콘텐츠를 스크롤하는 능력에 영향을 미치기 때문에 한 번에 모두가 아니라 순차적으로로드되는 것을보고 싶습니다. 그러나 그것은 한 사람의 관점에 불과합니다.

  • 사용자와 그들이 무엇을 중요하게 여기는지 알고 있습니다.
  • 사용자와 그들이 사용하는 브라우징 환경을 파악하십시오.
  • 각 파일의 기능과 전제 조건을 파악합니다. 모든 것을 작동시키는 것이 속도와 예쁘기보다 우선합니다.
  • 개발할 때 네트워크 타임 라인을 보여주는 도구를 사용합니다.
  • 사용자가 사용하는 각 환경에서 테스트하십시오. 사용자 환경에 따라 로딩 순서를 동적으로 (서버 측, 페이지 생성시) 변경해야 할 수 있습니다.
  • 확실하지 않은 경우 순서를 변경하고 다시 측정하십시오.
  • 로드 순서에서 스타일과 스크립트를 혼합하는 것이 최적 일 수 있습니다. 모두가 아니라 다른 모든 것.
  • 파일을로드 할 순서뿐만 아니라 위치를 실험 해보십시오. 머리? 몸에? 바디 후? DOM 준비 /로드? 짐을 실은?
  • 페이지와 상호 작용할 수 있기 전에 사용자가 경험하게 될 순 지연을 줄이기 위해 적절한 경우 비동기 및 지연 옵션을 고려하십시오. 도움이되는지 상처를 주는지 테스트하십시오.
  • 최적의로드 순서를 평가할 때 항상 고려해야 할 트레이드 오프가 있습니다. 단 하나 인 예쁜 반응 형 vs. 반응 형.

업데이트 됨 2017-12-16

나는 OP의 테스트에 대해 확신하지 못했습니다. 나는 약간의 실험을하기로 결정했고 결국 신화의 일부를 깨뜨 렸습니다.

동기식 <script src...>은 다운로드 및 실행될 때까지 하위 리소스의 다운로드를 차단합니다.

이것은 더 이상 사실이 아닙니다 . Chrome 63에서 생성 한 폭포를 살펴보세요.

<head>
<script src="//alias-0.redacted.com/payload.php?type=js&amp;delay=333&amp;rand=1"></script>
<script src="//alias-1.redacted.com/payload.php?type=js&amp;delay=333&amp;rand=2"></script>
<script src="//alias-2.redacted.com/payload.php?type=js&amp;delay=333&amp;rand=3"></script>
</head>

Chrome net 검사기-> 폭포

<link rel=stylesheet> 그 아래에있는 스크립트의 다운로드 및 실행을 차단하지 않습니다.

이것은 올바르지 않습니다 . 스타일 시트는 다운로드를 차단하지 않습니다하지만 것입니다 (스크립트의 실행을 차단 여기에 약간의 설명 ). Chrome 63에서 생성 한 성능 차트를 살펴보세요.

<link href="//alias-0.redacted.com/payload.php?type=css&amp;delay=666" rel="stylesheet">
<script src="//alias-1.redacted.com/payload.php?type=js&amp;delay=333&amp;block=1000"></script>

Chrome 개발 도구-> 성능


위의 사항을 염두에두고 OP의 결과는 다음과 같이 설명 할 수 있습니다.

CSS 우선 :

CSS Download  500ms:<------------------------------------------------>
JS Download   400ms:<-------------------------------------->
JS Execution 1000ms:                                                  <-------------------------------------------------------------------------------------------------->
DOM Ready   @1500ms:                                                                                                                                                      ◆

JS 우선 :

JS Download   400ms:<-------------------------------------->
CSS Download  500ms:<------------------------------------------------>
JS Execution 1000ms:                                        <-------------------------------------------------------------------------------------------------->
DOM Ready   @1400ms:                                                                                                                                            ◆

Java 스크립트를 사용하여 테스트 시간을 '렌더링'하는 방법을 정확히 모르겠습니다. 그러나 이것을 고려하십시오

귀하의 사이트에있는 한 페이지는 50k로 불합리하지 않습니다. 사용자는 동부 해안에 있고 서버는 서부에 있습니다. MTU는 확실히 10k가 아니므로 몇 번의 왕복 여행이있을 것입니다. 페이지와 스타일 시트를받는 데 1/2 초가 걸릴 수 있습니다. 일반적으로 (나에게) javascript (jquery 플러그인 등을 통해)는 CSS 이상입니다. 인터넷 연결이 페이지 중간에 질식 할 때 발생하는 일도 있지만 무시할 수 있습니다 (가끔 발생하며 CSS가 렌더링된다고 믿지만 100 % 확신하지는 않습니다).

CSS가 헤드에 있기 때문에이를 얻기위한 추가 연결이있을 수 있습니다. 즉, 페이지가 수행되기 전에 완료 될 수 있습니다. 어쨌든 유형 동안 페이지의 나머지 부분과 자바 스크립트 파일 (더 많은 바이트)이 페이지 스타일이 지정되지 않아 사이트 / 연결 속도가 느려집니다.

JS 인터프리터가 CSS가 완료 될 때까지 시작을 거부하더라도 특히 서버에서 멀리 떨어져있는 CSS 시간으로 인해 사이트가 예쁘지 않게 보일 때 자바 스크립트 코드를 다운로드하는 데 걸리는 시간이 걸립니다.

작은 최적화이지만 그 이유입니다.


위의 모든 주요 답변 요약다음과 같습니다.

최신 브라우저의 경우 원하는 곳에 CSS를 넣으십시오. 그들은 당신의 html 파일을 분석하고 ( 투기 적 파싱 이라고 부르는 ) html 파싱과 병행하여 CSS 다운로드를 시작합니다.

오래된 브라우저의 경우 CSS를 맨 위에 계속 배치합니다 (네이 키드하지만 대화 형 페이지를 먼저 표시하고 싶지 않은 경우).

모든 브라우저에서 javascript는 가능한 한 페이지 아래로 내려 가면 html 구문 분석이 중단됩니다. 가급적 비동기 적으로 다운로드 (예 : ajax 호출)

또한 자바 스크립트를 우선 (CSS를 우선으로 사용하는 전통적 지혜와는 반대로)하는 것이 더 나은 성능을 제공한다고 주장하는 특정 사례에 대한 몇 가지 실험 결과가 있지만 이에 대한 논리적 추론이 없으며 광범위한 적용 가능성에 대한 유효성 검사가 부족합니다. 지금은 무시하십시오.

따라서 질문에 답하려면 : 예. JS 앞에 CSS를 포함하라는 권장 사항은 최신 브라우저에서 유효하지 않습니다. 원하는 곳에 CSS를 배치하고 가능한 한 끝에 JS를 배치하십시오.


Steve Souders는 이미 확실한 대답을했지만 ...

Sam의 원래 테스트와 Josh의 반복에 문제가 있는지 궁금합니다.

두 테스트 모두 TCP 연결을 설정하는 데 약간의 비용이 드는 저 지연 연결에서 수행 된 것으로 보입니다.

이것이 테스트 결과에 어떤 영향을 미치는지 확실하지 않으며 '정상적인'대기 시간 연결을 통한 테스트를 위해 폭포를보고 싶지만 ...

다운로드 된 첫 번째 파일은 해야 HTML 페이지에 사용되는 연결을 얻고, 두 번째 파일은 새 연결을 얻을 것이다 다운로드. (초기 플러싱은 동적을 변경하지만 여기서는 수행되지 않습니다)

최신 브라우저에서는 두 번째 TCP 연결이 추측 적으로 열리므로 연결 오버 헤드가 줄어들거나 사라집니다. 이전 브라우저에서는 이것이 사실이 아니며 두 번째 연결이 열리게되는 오버 헤드가 있습니다.

이것이 테스트 결과에 어떤 영향을 미치는지 확실하지 않습니다.


나는 이것이 모든 경우에 사실이 아닐 것이라고 생각합니다. CSS는 병렬로 다운로드되지만 js는 할 수 없기 때문입니다. 같은 경우를 고려하십시오.

단일 CSS 대신 2 개 또는 3 개의 CSS 파일을 가져 와서 이러한 방법으로 시도해보세요.

1) css..css..js 2) css..js..css 3) js..css..css

나는 css..css..js가 다른 모든 것보다 더 나은 결과를 줄 것이라고 확신합니다.


새로운 브라우저는 자바 스크립트 엔진, 파서 등에서 작업하여 <= IE8과 같은 고대 브라우저에서 경험 한 문제가 더 이상 관련이없는 방식으로 공통 코드 및 마크 업 문제를 최적화했습니다. 마크 업뿐만 아니라 JavaScript 변수, 요소 선택기 등의 사용과 관련이 있습니다. 멀지 않은 미래에 기술이 더 이상 성능이 더 이상 문제가되지 않는 지점에 도달 한 상황을 볼 수 있습니다.


개인적으로 나는 그러한 "민속적인 지혜"를 너무 강조하지 않을 것입니다. 과거에 사실이었던 것이 지금은 사실이 아닐 수도 있습니다. 웹 페이지의 해석 및 렌더링과 관련된 모든 작업이 완전히 비동기 적이라고 가정합니다 ( "가져 오기"와 "조작"은 서로 다른 스레드에 의해 처리 될 수있는 완전히 다른 두 가지입니다 . ). 어떤 경우에도 전적으로 귀하의 통제 또는 귀하의 우려를 벗어납니다.

CSS 참조를 문서의 "head"부분에 외부 스크립트에 대한 참조와 함께 넣었습니다. (일부 스크립트는 본문에 배치하도록 요구할 수 있으며, 그렇다면 의무화합니다.)

그 이상으로 ... "이 브라우저에서 이보다 더 빠르거나 느린 것 같다"는 것을 발견하면이 관찰을 흥미롭지 만 관련없는 호기심으로 취급 하고 디자인 결정에 영향을주지 않도록하십시오. 너무 많은 것들이 너무 빨리 변합니다. (누구나 파이어 폭스 팀이 그들의 제품의 또 다른 중간 릴리스를 출시하기까지 분이 걸릴지에 대해 베팅을하고 싶은 사람이 있습니까? 네, 저도 마찬가지입니다.)

참고 URL : https://stackoverflow.com/questions/9271276/is-the-recommendation-to-include-css-before-javascript-invalid

반응형