[Javascript] 자바 스크립트가 무효가되기 전에 CSS를 포함 할 것을 권장합니까?



Answers

JavaScript 앞에 CSS를 두 가지 주요 이유가 있습니다.

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

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

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

Question

온라인 셀 수없이 많은 곳에서 나는 JavaScript 이전에 CSS를 포함 할 것을 권고했다. 추론은 일반적으로 다음 과 같은 형식입니다 .

CSS와 JavaScript를 주문할 때 CSS가 가장 먼저 필요합니다. 그 이유는 렌더링 스레드가 페이지를 렌더링하는 데 필요한 모든 스타일 정보를 갖고 있기 때문입니다. 자바 스크립트가 먼저 포함되면 자바 스크립트 엔진은 다음 리소스 집합을 계속하기 전에이를 모두 파싱해야합니다. 즉, 렌더링 스레드는 필요한 모든 스타일을 가지고 있지 않기 때문에 페이지를 완전히 표시 할 수 없습니다.

제 실제 테스트 결과는 상당히 다른 것을 보여줍니다 :

내 테스트 장치

다음 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=500 은 CSS를 전송하는 데 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 초가 걸립니다.

자바 스크립트를 처음으로 포함 시키면 1.4 초가 걸립니다.

Chrome, Firefox 및 Internet Explorer에서도 비슷한 결과가 나타납니다. 하지만 Opera에서는 순서가 중요하지 않습니다.

무슨 일이 벌어지고 있는지는 JavaScript 인터프리터가 모든 CSS가 다운로드 될 때까지 시작을 거부한다는 것입니다. 따라서 자바 스크립트 스레드가 더 많은 런타임을 얻으므로 먼저 JavaScript를 사용하는 것이 더 효율적입니다.

내가 뭔가를 놓친 건지, CSS를 포함하기 전에 권장 사항은 자바 스크립트에 포함되지 않은 올바른가 포함되어 있습니까?

async를 추가하거나 setTimeout을 사용하여 렌더링 스레드를 확보하거나 JavaScript 코드를 바닥 글에 넣거나 JavaScript 로더를 사용할 수 있습니다. 요점은 핵심 JavaScript 비트 및 CSS 비트의 순서를 지정하는 것입니다.




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

"맨 위에 스타일 시트 넣기"의 목적은 일반적으로 사용자 경험에 중요한 최적의 점진적 렌더링 을 얻는 가장 좋은 방법 입니다.

그 외에는 테스트가 유효하고 대중적인 규칙에 반하는 결과를 실제로 내고 있다고 가정 할 때 놀랄 일이 아닙니다. 모든 웹 사이트 (그리고 모든 것을 사용자의 화면에 표시하는 데 필요한 모든 것)는 다르며 인터넷은 끊임없이 진화하고 있습니다.




정확히 어떻게 자바 스크립트를 사용하여 테스트 시간을 '렌더링'하는지 모르겠습니다. 그러나 이것을 고려해 보라.

귀하의 사이트에있는 한 페이지는 부당하지 않은 50k입니다. 서버가 서쪽에있는 동안 사용자는 동해안에 있습니다. MTU는 확실히 10k가 아니므로 약간의 왕복이있을 것입니다. 페이지 및 스타일 시트를 받으려면 1/2 초가 걸릴 수 있습니다. 일반적으로 (나를 위해) javascript (jquery plugin 등을 통해)는 CSS 이상입니다. Theres 또한 귀하의 인터넷 연결이 페이지의 중간에 질식하지만 그것을 무시할 때 발생합니다 (그것은 나에게 가끔 발생하고 CSS는 렌더링하지만 나는 100 % 확실하지 않습니다) 믿습니다.

css가 머리에 있기 때문에 그것을 얻기 위해 추가 연결이있을 수 있습니다. 이는 페이지가 끝나기 전에 잠재적으로 끝날 수 있음을 의미합니다. 어쨌든 유형 중에는 나머지 페이지가 필요하고 javascript 파일 (더 많은 바이트)은 페이지가 스타일이 지정되지 않아 사이트 / 연결이 느리게 보입니다.

CSS 해석이 시작될 때까지 JS 인터프리터가 거절하는 경우에도 자바 스크립트 코드를 다운로드하는 데 걸린 시간은 특히 서버에서 멀어 질수록 CSS 시간이 줄어들어 사이트가 예쁘게 보이지 않게됩니다.

그것의 작은 최적화하지만 thats 이유.




나는 이것이 모든 경우에 사실이 아닐 것이라고 생각한다. CSS는 병렬하지만 js cant를 다운로드하기 때문에. 같은 경우를 고려해보십시오.

대신 하나의 CSS를 가지고, 2 또는 3 CSS는 파일을 받아이 방법을 사용해보십시오,

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

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




자바 스크립트가 무효가되기 전에 CSS를 포함 할 것을 권장합니까?

단순히 권고 사항으로 취급하지 않아도됩니다. 그러나 당신이 그것을 단단하고 빠른 규칙으로 다루는가?, 예, 그것은 무효입니다.

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

스타일 시트가 스크립트 실행을로드하므로 <link rel="stylesheet" ...> 뒤에 <script> 가 있으면 스타일 시트가로드 될 때까지 페이지가 파싱을 끝내지 않고 DOMContentLoaded가 실행되지 않습니다.

각 스크립트가 무엇을 의존하는지 알아야하며 올바른 완료 이벤트가 발생할 때까지 스크립트의 실행이 지연되도록해야합니다. 스크립트가 DOM에만 의존하는 경우로드 할 이미지 또는 스타일 시트를 사용하는 경우 ondomready / domcontentloaded에서 다시 시작할 수 있습니다. 위의 참조를 올바르게 읽으면 해당 코드를 onload 이벤트까지 지연해야합니다.

나는 그것이 하나의 양말 사이즈가 모두 맞는 것을 생각하지 않는다. 비록 그것이 그들이 팔리는 방식이고, 한가지의 신발 사이즈가 모두에게 맞지 않는다고 알고있다 할지라도. 내가 먼저, 스타일 또는 스크립트를로드 할 수있는 확실한 대답은 없다고 생각합니다. 어떤 순서로로드되어야하는지, 나중에 "임계 경로"에 있지 않은 것으로 지연 될 수 있는지에 대한 사례 결정이 있습니다.

관찰자와 이야기를 나누려면 사용자가 시트가 깔끔해질 때까지 대화 할 수있는 능력을 늦추는 것이 낫다는 의견을 제시하십시오. 거기 밖으로 당신의 많은 것이고 당신은 반대를 느끼는 당신의 대조 물을 괴롭힌다. 그들은 목적을 달성하기 위해 사이트를 방문했으며,로드를 끝내기 위해 중요하지 않은 것을 기다리는 동안 사이트와 상호 작용할 수있는 능력을 지연시키는 것은 매우 실망 스럽습니다. 나는 당신이 틀렸다는 것을 말하는 것이 아니며 단지 당신의 우선 순위를 공유하지 않는 다른 진영이 있음을 알아야한다는 것입니다.

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

  • 사용자와 사용자의 가치를 파악하십시오.
  • 사용자와 그들이 사용하는 브라우징 환경을 파악하십시오.
  • 각 파일이하는 일과 그 전제 조건이 무엇인지 파악하십시오. 모든 것을 작동시키는 것이 속도와 예쁜 것에 우선합니다.
  • 개발할 때 네트워크 타임 라인을 보여주는 도구를 사용하십시오.
  • 사용자가 사용하는 각 환경에서 테스트하십시오. 동적으로 (페이지를 작성할 때 서버 측) 사용자 환경에 따라로드 순서를 변경해야 할 수도 있습니다.
  • 의심스러운 경우 주문을 변경하고 다시 측정하십시오.
  • 로드 순서에서 스타일과 스크립트를 혼합하는 것이 최적 일 수 있습니다. 모든 것이 아닌 다른 모든 것.
  • 파일을로드하는 순서가 아니라 위치를 테스트하십시오. 머리? 몸에? 시체 후? DOM 준비 /로드 중입니까? 짐을 실은?
  • 적절한 경우 async 및 defer 옵션을 고려하여 사용자가 페이지와 상호 작용할 수 있기 전에 경험하게 될 순 지연을 줄이십시오. 그들이 도움이되는지 아플 지 판단하기 위해 테스트하십시오.
  • 최적의로드 순서를 평가할 때는 항상 고려해야 할 사항이 있습니다. 꽤 대 반응하는 것은 단지 하나입니다.



새로운 브라우저는 Javascript 엔진, 파서 등을 사용하여 일반적인 코드 및 마크 업 문제를 해결하여 <= IE8과 같은 고대 브라우저에서 경험했던 문제가 더 이상 적합하지 않게되었습니다. 마크 업뿐만 아니라 자바 스크립트 변수, 요소 선택기 등의 사용에도 관련이 있습니다. 먼 미래에 기술이 성능이 실제로 더 이상 문제가되지 않는 지점에 도달 한 상황을 볼 수 있습니다.




Links