CSS ควรนำหน้า Javascript มาด้วยเสมอหรือไม่


897

ในสถานที่นับไม่ถ้วนออนไลน์ฉันได้เห็นข้อเสนอแนะเพื่อรวม CSS ก่อนจาวาสคริปต์ เหตุผลโดยทั่วไปของแบบฟอร์มนี้ :

เมื่อพูดถึงการสั่งซื้อ CSS และ JavaScript ของคุณคุณต้องการให้ 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=500ให้ฉันล่าช้า 500 ms ในการถ่ายโอน CSS

ฉันใช้หน้าต่อไปนี้เพื่อทดสอบ

<!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 วินาทีในการแสดงผล:

JavaScript ก่อน

ฉันได้รับผลลัพธ์ที่คล้ายกันใน Chrome, Firefox และ Internet Explorer อย่างไรก็ตามใน Opera การสั่งซื้อก็ไม่สำคัญ

สิ่งที่ดูเหมือนจะเกิดขึ้นคือล่าม JavaScript ไม่ยอมเริ่มจนกว่าจะดาวน์โหลด CSS ทั้งหมด ดังนั้นดูเหมือนว่าการรวม JavaScript ครั้งแรกจะมีประสิทธิภาพมากขึ้นเนื่องจากเธรด JavaScript ทำให้ใช้เวลามากขึ้น

ฉันขาดอะไรไปบ้างข้อเสนอแนะในการวาง CSS รวมไว้ก่อนหน้า JavaScript รวมถึงไม่ถูกต้องหรือไม่

เป็นที่ชัดเจนว่าเราสามารถเพิ่ม async หรือใช้ setTimeout เพื่อเพิ่มเธรดการแสดงผลหรือวางโค้ด JavaScript ในส่วนท้ายหรือใช้ตัวโหลด JavaScript จุดที่นี่คือเกี่ยวกับการจัดลำดับของบิต JavaScript ที่จำเป็นและบิต CSS ในส่วนหัว


120
1511 กับ 1422 แตกต่างกันอย่างมีนัยสำคัญทางสถิติคืออะไร? นั่นคือร้อยละ 6 เกณฑ์ทั่วไปสำหรับความแตกต่างของประสิทธิภาพการทำงานที่โดดเด่นถึงปานกลางโดยเฉลี่ยอยู่ที่ประมาณร้อยละ 20
Jeff Atwood

15
ประเด็นก็คือการจัดลำดับใหม่ช่วยลดความล่าช้าโดยพลการนี้คุณสามารถตั้งค่าการหน่วงเวลาเป็นสิ่งที่คุณต้องการเพียงแค่แสดงตัวอย่างของปัญหา
แซม Saffron

3
คุณล่าช้า 100ms หรือเปล่า ความแตกต่างในภาพหน้าจอของคุณคือ 89ms ใน URL ของคุณคือdelay=400&amp;jsdelay=1000และdelay=500อยู่ที่ไหนใกล้ 100ms หรือ 89ms ฉันเดาว่าฉันไม่แน่ใจว่าคุณกำลังอ้างถึงตัวเลขใด
Jeff Atwood

4
"หาก Javascript มีมาก่อนเอ็นจิ้น Javascript ต้องทำการแยกวิเคราะห์ทั้งหมดก่อนที่จะดำเนินการต่อไปยังทรัพยากรชุดถัดไปซึ่งหมายความว่าเธรดการแสดงผลไม่สามารถแสดงหน้าได้อย่างสมบูรณ์เนื่องจากไม่มีสไตล์ทั้งหมดที่ต้องการ ." - หากมีการรวม JS ไว้ในส่วนหัวแล้ว JS จะถูกดำเนินการก่อนที่จะมีการแสดงผลหน้าโดยไม่คำนึงว่า CSS รวมก่อนหรือหลัง
nnnnnn

162
ไม่แน่ใจว่าคุณได้พิจารณาเรื่องนี้หรือไม่ แต่การรับรู้ถึงความเร็วในการโหลดก็มีความสำคัญเช่นกัน ตัวอย่างเช่นถ้าการโหลด CSS ให้คุณเป็นครั้งแรกแม้เพียงแค่สี / พื้นหลังของหน้ามันก็จะเร็วขึ้น เวลาในการโหลดที่แน่นอนอาจไม่สามารถบ่งบอกถึงสิ่งนี้ได้
Rakesh Pai

คำตอบ:


712

นี่เป็นคำถามที่น่าสนใจมาก ฉันใส่ CSS ของฉันไว้ข้าง<link href="...">หน้า JS <script src="...">ทุกครั้งเพราะ "ฉันอ่านหนึ่งครั้งดีกว่า" ดังนั้นคุณพูดถูก ถึงเวลาแล้วที่เราจะทำการวิจัยจริง!

ฉันตั้งค่าชุดควบคุมการทดสอบของตัวเองในโหนด (รหัสด้านล่าง) โดยทั่วไปฉัน:

  • ตรวจสอบให้แน่ใจว่าไม่มีแคช HTTP ดังนั้นเบราว์เซอร์จะต้องดาวน์โหลดแบบเต็มทุกครั้งที่โหลดหน้าเว็บ
  • เพื่อจำลองความเป็นจริงฉันรวม jQuery และH5BP CSS (ดังนั้นจึงมีจำนวนสคริปต์ / CSS ที่เหมาะสมในการแยกวิเคราะห์)
  • ตั้งค่าสองหน้า - หนึ่งหน้าด้วย CSS ก่อนที่สคริปต์หนึ่งหน้ากับ CSS หลังสคริปต์
  • บันทึกว่าต้องใช้เวลานานเท่าใดสำหรับสคริปต์ภายนอกในการ<head>ดำเนินการ
  • บันทึกไว้นานเท่าใดจึงสำหรับสคริปต์แบบอินไลน์ในการดำเนินการซึ่งจะคล้ายคลึงกับ<body>DOMReady
  • การส่ง CSS และ / หรือสคริปต์ไปยังเบราว์เซอร์ล่าช้า 500ms
  • ทดสอบ 20 ครั้งในเบราว์เซอร์หลัก 3 ตัว

ผล

ก่อนอื่นด้วยไฟล์ 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

ต่อไปฉันตั้งค่า jQuery เพื่อหน่วงเวลา 500ms แทน CSS:

     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>ควรไปก่อน<link>ใน<head>หรือไม่

ในเบราว์เซอร์ DESKTOP ที่ทันสมัยดูเหมือนว่าการเชื่อมโยงไปยัง CSS ก่อนอื่นไม่ให้ประสิทธิภาพที่เพิ่มขึ้น การใส่ CSS หลังจากสคริปต์ทำให้คุณได้รับกำไรเล็กน้อยเมื่อทั้ง CSS และสคริปต์ล่าช้า แต่จะให้ผลกำไรจำนวนมากเมื่อ CSS ล่าช้า (แสดงโดยlastคอลัมน์ในชุดผลลัพธ์แรก)

ระบุว่าการเชื่อมโยงไปยัง CSS ที่ผ่านมาดูเหมือนจะไม่เจ็บ แต่ประสิทธิภาพการทำงานที่สามารถให้กำไรภายใต้สถานการณ์บางอย่างที่คุณควรจะเชื่อมโยงไปยังสไตล์ชีตภายนอกหลังจากที่คุณเชื่อมโยงไปสคริปต์ภายนอกเฉพาะในเบราว์เซอร์สก์ท็อปหากประสิทธิภาพการทำงานของเบราว์เซอร์เก่าไม่กังวล อ่านต่อสำหรับสถานการณ์มือถือ

ทำไม?

ในอดีตเมื่อเบราว์เซอร์พบ<script>แท็กที่ชี้ไปยังแหล่งข้อมูลภายนอกเบราว์เซอร์จะหยุดการแยกวิเคราะห์ HTML เรียกสคริปต์เรียกใช้แล้วดำเนินการแยกวิเคราะห์ HTML ต่อไป ในทางตรงกันข้ามหากเบราว์เซอร์พบ<link>สำหรับสไตล์ชีตภายนอกก็จะยังคงแยก HTML ในขณะที่มันเรียกไฟล์ CSS (ในแบบขนาน)

ดังนั้นคำแนะนำที่ใช้ซ้ำ ๆ กันอย่างแพร่หลายในการใส่สไตล์ชีทก่อน - พวกเขาจะดาวน์โหลดก่อนและสคริปต์แรกที่จะดาวน์โหลดสามารถโหลดพร้อมกันได้

อย่างไรก็ตามเบราว์เซอร์ที่ทันสมัย ​​(รวมถึงเบราว์เซอร์ทั้งหมดที่ฉันทดสอบด้วยด้านบน) ได้ใช้การแยกวิเคราะห์เก็งกำไรซึ่งเบราว์เซอร์ "มองไปข้างหน้า" ใน HTML และเริ่มดาวน์โหลดทรัพยากรก่อนที่สคริปต์จะดาวน์โหลดและดำเนินการ

ในเบราว์เซอร์รุ่นเก่าที่ไม่มีการแยกวิเคราะห์แบบเก็งกำไรการวางสคริปต์ก่อนจะส่งผลต่อประสิทธิภาพเนื่องจากจะไม่ดาวน์โหลดแบบขนาน

สนับสนุนเบราว์เซอร์

การแยกวิเคราะห์แบบเก็งกำไรถูกนำมาใช้ครั้งแรกใน: (พร้อมกับเปอร์เซ็นต์ของผู้ใช้เบราว์เซอร์เดสก์ท็อปทั่วโลกที่ใช้รุ่นนี้หรือมากกว่าตั้งแต่มกราคม 2012)

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

โดยรวมแล้วประมาณ 85% ของเบราว์เซอร์เดสก์ท็อปที่ใช้งานในปัจจุบันรองรับการโหลดแบบเก็งกำไร การวางสคริปต์ไว้ก่อน CSS จะมีค่าปรับประสิทธิภาพ 15% ของผู้ใช้ทั่วโลก ; YMMV อิงตามกลุ่มเป้าหมายเฉพาะของไซต์ของคุณ (และจำไว้ว่าจำนวนนั้นกำลังลดลง)

บนเบราว์เซอร์มือถือเป็นการยากขึ้นเล็กน้อยที่จะได้รับตัวเลขที่ชัดเจนเนื่องจากความแตกต่างของเบราว์เซอร์มือถือและแนวนอนของระบบปฏิบัติการ เนื่องจากการเรนเดอร์แบบเก็งกำไรถูกนำไปใช้ใน WebKit 525 (เปิดตัวเมื่อเดือนมีนาคม 2551) และเบราว์เซอร์มือถือที่คุ้มค่าทุกตัวนั้นใช้ WebKit เราจึงสามารถสรุปได้ว่าเบราว์เซอร์มือถือ "ส่วนใหญ่" ควรรองรับ ตามquirksmode , iOS 2.2 / Android 1.0 ใช้ WebKit 525 ฉันไม่รู้ว่า Windows Phone เป็นอย่างไร

อย่างไรก็ตามฉันรันการทดสอบบนอุปกรณ์ Android 4 ของฉันและในขณะที่ฉันเห็นตัวเลขคล้ายกับผลลัพธ์บนเดสก์ท็อปฉันได้เชื่อมต่อกับตัวดีบักระยะไกลตัวใหม่ที่ยอดเยี่ยมใน Chrome สำหรับ Android และแท็บเครือข่ายแสดงว่าเบราว์เซอร์กำลังรอดาวน์โหลด CSS จนกว่า JavaScripts จะถูกโหลดอย่างสมบูรณ์ - กล่าวอีกนัยหนึ่งแม้แต่เวอร์ชั่นล่าสุดของ WebKit สำหรับ Android ก็ไม่ปรากฏว่ารองรับการแยกวิเคราะห์แบบเก็งกำไร ฉันสงสัยว่าอาจถูกปิดเนื่องจาก 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


137
นี่คือคำตอบที่ยอดเยี่ยมขอบคุณที่ใช้วิทยาศาสตร์! ตามผลลัพธ์ของคุณ"ในเบราว์เซอร์สมัยใหม่ดูเหมือนว่าการลิงก์ไปยัง CSS ก่อนจะไม่ให้ประสิทธิภาพเพิ่มขึ้น"ฉันคิดว่าคำตอบของคำถามคือใช่คำแนะนำเก่าของ CSS แรกนั้นไม่ถูกต้องชัดเจน
Jeff Atwood

เกี่ยวกับการอัปเดตของ @ josh3736 เกี่ยวกับสิ่งที่ตรงกันข้ามบนมือถือ ... นี่เป็นกรณีที่จะไม่กระโดดปืนกับการเปลี่ยนแปลงที่สำคัญนี้ ฉันอยากรู้ว่าเบราว์เซอร์มือถืออื่น ๆ ทำงานอย่างไร (webkit, ตุ๊กแก, presto, ตรีศูล ฯลฯ ) เนื่องจากประสิทธิภาพในมือถือมักมีความสำคัญมากกว่า
scunliffe

1
คุณควรลองเพิ่มความเชื่องช้าเพื่อพิมพ์ css / js เพื่อจำลองความเร็วของเซิร์ฟเวอร์ที่ช้า
kirb

1
"ก่อนอื่นสิ่งสำคัญคือต้องทราบว่าฉันทำงานภายใต้สมมติฐานที่ว่าคุณมีสคริปต์อยู่ใน<head>เอกสารของคุณ (ตรงข้ามกับตอนท้าย<body>)" ผมจะเน้นที่มากก่อนหน้านี้ในคำตอบเหมือนที่ด้านบน การรวมไฟล์scriptในheadที่อ้างถึงไฟล์ภายนอกนั้นแทบไม่เคยถูกต้องจากมุมมองใด ๆ (แน่นอนไม่ใช่ประสิทธิภาพ) ฉันจำไม่ได้ว่าเคยต้องทำในชีวิตจริง สคริปต์แบบอินไลน์หรือคี่สองบรรทัดอาจจะ แต่นั่นคือทั้งหมด เริ่มต้นโดยไม่ต้องมากด้วยเหตุผลทางตรงกันข้ามที่ดีควรจะเป็นจุดสิ้นสุดของร่างกาย
TJ Crowder

1
jQuery ที่ไม่ได้รับการโหวตไม่ได้เป็น JavaScript และมีการขยายหน้าเท่านั้นดังนั้นผลลัพธ์ที่ใช้จึงไม่ใช่วัตถุประสงค์
จอห์น

303

เหตุผลหลักสองข้อในการใส่ CSS ไว้หน้า JavaScript

  1. เบราว์เซอร์รุ่นเก่า (Internet Explorer 6-7, Firefox 2 ฯลฯ ) จะบล็อกการดาวน์โหลดที่ตามมาทั้งหมดเมื่อพวกเขาเริ่มดาวน์โหลดสคริปต์ ดังนั้นหากคุณa.jsตามมาb.cssพวกเขาจะถูกดาวน์โหลดตามลำดับ: ก่อนอื่นจากนั้น b หากคุณb.cssตามมาa.jsพวกเขาจะถูกดาวน์โหลดแบบขนานเพื่อให้หน้าโหลดได้เร็วขึ้น

  2. ไม่มีการสร้างการแสดงผลจนกว่าสไตล์ชีททั้งหมดจะถูกดาวน์โหลดซึ่งเป็นจริงในเบราว์เซอร์ทั้งหมด สคริปต์แตกต่างกัน - บล็อกการแสดงผลขององค์ประกอบ DOM ทั้งหมดที่อยู่ด้านล่างแท็กสคริปต์ในหน้า หากคุณวางสคริปต์ไว้ในส่วนหัวก็หมายความว่าหน้าเว็บทั้งหน้าถูกปิดกั้นไม่ให้แสดงผลจนกว่าสไตล์ทั้งหมดและสคริปต์ทั้งหมดจะถูกดาวน์โหลด แม้ว่าจะเหมาะสมที่จะบล็อกการแสดงผลทั้งหมดสำหรับ stylesheets (เพื่อให้คุณใส่สไตล์ที่ถูกต้องในครั้งแรกและหลีกเลี่ยงการแฟลชของเนื้อหาที่ไม่มีการจัดรูปแบบ FOUC) แต่ก็ไม่เหมาะสมที่จะบล็อกการแสดงผลทั้งหน้าสำหรับสคริปต์ บ่อยครั้งที่สคริปต์ไม่ส่งผลกระทบต่อองค์ประกอบ DOM หรือเพียงบางส่วนขององค์ประกอบ DOM เป็นการดีที่สุดที่จะโหลดสคริปต์ให้อยู่ในระดับต่ำที่สุดเท่าที่จะทำได้หรือโหลดได้เร็วขึ้นแบบอะซิงโครนัส

สนุกมันจะสร้างตัวอย่างกับCuzillion ตัวอย่างเช่นหน้านี้มีสคริปต์ในส่วนหัวเพื่อให้หน้าทั้งหมดว่างเปล่าจนกว่าจะดาวน์โหลดเสร็จ อย่างไรก็ตามหากเราย้ายสคริปต์ไปยังจุดสิ้นสุดของบล็อก BODY ส่วนหัวของหน้าแสดงผลเนื่องจากองค์ประกอบ DOM เหล่านั้นเกิดขึ้นเหนือแท็ก SCRIPT ดังที่คุณเห็นในหน้านี้


10
Steve ให้เกียรติฉันตอบคำถาม แต่ฉันจะเพิ่มบทความที่เกี่ยวข้องกับสิ่งที่เขากล่าวถึง: stevesouders.com/blog/2009/04/27/…
Juan Pablo Buritica

4
ดูว่าเบราว์เซอร์ใดasyncบ้างที่สนับสนุนคุณสมบัติซึ่ง Steve แนะนำไว้ที่นี่เมื่อเขาบอกว่า "ดีกว่าโหลดแบบอะซิงโครนัส" - stackoverflow.com/questions/1834077/…
Jeff Atwood

เฮ้คุณบอกฉันได้ไหมว่าทำไมทุกคนจะเชื่อมโยงไฟล์ CSS กับ@importคำสั่ง?
Josh Stodola

6
แหล่งที่มาของ 2) คืออะไรและถ้าเป็นจริงคุณสามารถอธิบายได้ว่าทำไมในบางครั้งหน้าจะโหลดเนื้อหาเสร็จแล้ว CSS จะถูกนำไปใช้ในสองหรือสองภายหลัง (นี้ได้เกิดขึ้นแทบบนหน้าเว็บของตัวเองที่ CSS อยู่ใน <head> แท็ก)
Izkata

2
ดังนั้นเราควรใส่jQuery+ jQuery UI+ $(document).ready(function () { });ที่ส่วนท้ายของหน้า? มันจะทำงานได้ตามปกติหรือไม่
Olivier Pons

42

ฉันจะไม่เน้นมากเกินไปกับผลลัพธ์ที่คุณได้รับฉันเชื่อว่ามันเป็นอัตนัย แต่ฉันมีเหตุผลที่จะอธิบายให้คุณทราบว่ามันจะดีกว่าที่จะใส่ใน CSS ก่อน js

ในระหว่างการโหลดเว็บไซต์ของคุณมีสองสถานการณ์ที่คุณจะเห็น:

กรณีที่ 1: หน้าจอสีขาว> เว็บไซต์ Unstyled> เว็บไซต์สไตล์> ปฏิสัมพันธ์> สไตล์และเว็บไซต์โต้ตอบ

กรณีที่ 2: หน้าจอสีขาว> เว็บไซต์ Unstyled> ปฏิสัมพันธ์> เว็บไซต์สไตล์> สไตล์และการโต้ตอบเว็บไซต์


ผมไม่สามารถจินตนาการทุกคนเลือกกรณีที่ 2 นี้จะหมายถึง ผู้เข้าชมที่ใช้การเชื่อมต่ออินเทอร์เน็ตที่ช้าจะต้องเผชิญกับเว็บไซต์ที่ไม่มีการจัดรูปแบบที่ช่วยให้พวกเขาสามารถโต้ตอบกับมันโดยใช้ Javascript (เนื่องจากมีการโหลดแล้ว) นอกจากนี้เวลาที่ใช้ในการดูเว็บไซต์ที่ไม่มีการจัดรูปแบบจะถูกขยายให้ใหญ่สุดด้วยวิธีนี้ ทำไมทุกคนต้องการสิ่งนั้น

นอกจากนี้ยังทำงานได้ดีขึ้นในขณะที่jQuery ระบุ

"เมื่อใช้สคริปต์ที่ต้องพึ่งพาค่าของคุณสมบัติสไตล์ CSS สิ่งสำคัญคือการอ้างอิงสไตล์ชีตภายนอกหรือองค์ประกอบสไตล์ฝังก่อนอ้างอิงสคริปต์"

เมื่อโหลดไฟล์ในลำดับที่ไม่ถูกต้อง (JS แรกจากนั้น CSS) โค้ด Javascript ใด ๆ ที่ใช้คุณสมบัติที่ตั้งค่าไว้ในไฟล์ CSS (ตัวอย่างเช่นความกว้างหรือความสูงของ div) จะไม่ถูกโหลดอย่างถูกต้อง ดูเหมือนว่าด้วยลำดับการโหลดที่ไม่ถูกต้องคุณสมบัติที่ถูกต้องคือ 'บางครั้ง' ที่รู้จักกันใน Javascript (อาจเกิดจากสภาพการแข่งขันหรือไม่) เอฟเฟกต์นี้ดูเหมือนว่าใหญ่กว่าหรือเล็กกว่าขึ้นอยู่กับเบราว์เซอร์ที่ใช้


2
คุณจะรับประกันเกี่ยวกับ css ทั้งหมดที่โหลดก่อนที่ javascript จะทำงานได้อย่างไร? คุณสามารถ? หรือจาวาสคริปต์ของคุณควรแข็งแกร่งเพียงพอที่จะจัดการกับสถานการณ์ที่อาจไม่สามารถโหลดสไตล์ได้
Jonnio

@Jonnio หาก JS ของคุณมีการอ้างอิงคุณควรทำการอ้างอิงนั้นอย่างชัดเจน มิฉะนั้นคุณจะมีปัญหาเกี่ยวกับการกำหนดเวลาที่หายากอยู่เสมอ โมดูล ES6 เป็นวิธีที่ดีในการทำให้เกิดขึ้น แต่มีห้องสมุดจำนวนมากที่สามารถใช้ได้เช่นกัน
kmkemp

26

มีการทดสอบของคุณกับคอมพิวเตอร์ส่วนบุคคลของคุณหรือบนเว็บเซิร์ฟเวอร์หรือไม่? มันเป็นหน้าว่างหรือเป็นระบบออนไลน์ที่ซับซ้อนที่มีรูปภาพฐานข้อมูลและอื่น ๆ ? สคริปต์ของคุณมีการดำเนินการเหตุการณ์โฮเวอร์แบบง่ายหรือไม่หรือเป็นองค์ประกอบหลักในการที่เว็บไซต์ของคุณแสดงผลและโต้ตอบกับผู้ใช้หรือไม่ มีหลายสิ่งที่ต้องพิจารณาที่นี่และความเกี่ยวข้องของคำแนะนำเหล่านี้มักจะกลายเป็นกฎเมื่อคุณร่วมในการพัฒนาเว็บที่มีความสามารถสูง

วัตถุประสงค์ของการ "ใส่สไตล์ชีตที่ด้านบนและสคริปต์ที่ด้านล่าง" กฎคือว่าโดยทั่วไปก็เป็นวิธีที่ดีที่สุดเพื่อให้บรรลุที่ดีที่สุดการแสดงผลความก้าวหน้า ,ซึ่งมีความสำคัญต่อประสบการณ์ของผู้ใช้

นอกเหนือจากทั้งหมด: สมมติว่าการทดสอบของคุณถูกต้องและคุณกำลังสร้างผลลัพธ์ที่ตรงข้ามกับกฎที่เป็นที่นิยมจริง ๆ แล้วมันก็ไม่แปลกใจเลย ทุกเว็บไซต์ (และทุกสิ่งที่ใช้ในการทำให้ทุกอย่างปรากฏบนหน้าจอของผู้ใช้) นั้นแตกต่างกันและอินเทอร์เน็ตก็มีวิวัฒนาการอย่างต่อเนื่อง


1
ฉันซาบซึ้งในจุดที่คุณกำลังกล้า แต่ OP กำลังพูดถึงสิ่งที่เกิดขึ้นเมื่อคุณสั่งซื้อที่แตกต่างกันทั้งด้านบนและด้านล่าง
nnnnnn

1
ดังนั้น "สมมติว่าการทดสอบ [ของเขา] นั้นถูกต้อง"
skippr

21

ฉันรวมไฟล์ CSS ไว้ก่อน Javascript ด้วยเหตุผลอื่น

หากจาวาสคริปต์ของฉันต้องทำการปรับขนาดแบบไดนามิกขององค์ประกอบหน้าบางอย่าง (สำหรับมุมกรณีเหล่านั้นที่ CSS เป็นหลักที่ด้านหลังจริงๆ) จากนั้นโหลด CSS หลังจากที่ JS กำลัง russing สามารถนำไปสู่สภาพการแข่งขันที่องค์ประกอบถูกปรับขนาดก่อนสไตล์ CSS ถูกนำไปใช้และดูแปลก ๆ เมื่อสไตล์เริ่มเข้ามาหากฉันโหลด CSS ล่วงหน้าฉันสามารถรับประกันได้ว่าสิ่งต่าง ๆ จะทำงานตามลำดับที่ตั้งใจและเลย์เอาต์สุดท้ายคือสิ่งที่ฉันต้องการให้เป็น


2
จะทำให้เบราว์เซอร์บางวันหยุดลงหนึ่งวัน ฉันไม่ได้คาดเดา
jcolebrand

1
jcolebrand: ใช่ฉันคิดว่าฉันดื่มกาแฟไม่พอเมื่อฉันเขียนสิ่งนี้ (ในการหวนกลับฉันเดาว่าสิ่งสำคัญคือเพียงเพื่อหลีกเลี่ยงการโหลดแบบไดนามิกของ CSS และวาง JS ในเหตุการณ์ domReady หากคุณจำเป็นต้องทำการปรับขนาดแบบไดนามิก)
hugomg

สคริปต์ไม่ควรเปลี่ยนการแสดงผลใด ๆ นั่นคืองาน CSS HTML = เนื้อหา, CSS = วิธีแสดงเนื้อหา, จาวาสคริปต์เปลี่ยนเนื้อหาแบบไดนามิก นอกจากนี้ js ควรดำเนินการหลังจาก (หรือขณะที่) DOMContentLoaded ถูกไล่ออกด้วยสถานการณ์เล็กน้อย แต่มีความเฉพาะเจาะจงมาก
brunoais

@brunoais: บางเลย์เอาต์สามารถสร้างได้ด้วย Javascript เท่านั้น ตัวอย่างเช่นสิ่งใดก็ตามที่จำเป็นต้องปรับขนาดแบบไดนามิกต้องทำผ่าน Javascript และบางสิ่ง (เช่นมีขนาด 100% - 20px) จำเป็นต้องใช้ Javascript ในแบบเบราว์เซอร์ในแบบเก่า
hugomg

@missingno ในกรณีเหล่านั้นเพียงใช้เหตุการณ์ DOMContentLoaded แต่ฉันเข้าใจความหมายของคุณ (Stupid IE!)
brunoais

10

คำแนะนำในการรวม CSS ไว้ก่อน JavaScript ไม่ถูกต้องหรือไม่

ไม่ใช่ถ้าคุณปฏิบัติต่อมันเป็นเพียงคำแนะนำ แต่ถ้าคุณคิดว่ามันเป็นกฎที่ยากและรวดเร็วใช่มันไม่ถูกต้อง

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

Stylesheet ทำการโหลดสคริปต์การบล็อกดังนั้นหากคุณมีหน้า<script> หลังจากการ<link rel="stylesheet" ...>แยกวิเคราะห์ไม่เสร็จ - และ DOMContentLoaded จะไม่เริ่มทำงานจนกว่าจะโหลดสไตล์ชีท

ดูเหมือนว่าคุณจำเป็นต้องรู้ว่าแต่ละสคริปต์อาศัยและตรวจสอบให้แน่ใจว่าการดำเนินการของสคริปต์ล่าช้าจนกว่าจะเสร็จสิ้นเหตุการณ์ที่ถูกต้อง หากสคริปต์อาศัยใน DOM เท่านั้นสคริปต์สามารถดำเนินการต่อใน ondomready / domcontentloaded หากอาศัยภาพที่จะโหลดหรือสไตล์ชีตที่จะนำไปใช้ดังนั้นถ้าฉันอ่านการอ้างอิงข้างต้นอย่างถูกต้องรหัสนั้นจะต้องรอจนกระทั่งเหตุการณ์ onload

ฉันไม่คิดว่าขนาดถุงเท้าเดียวเหมาะกับทุกคนแม้ว่าจะเป็นวิธีที่พวกเขาขายและฉันรู้ว่าขนาดรองเท้าเดียวไม่พอดีทั้งหมด ฉันไม่คิดว่าจะมีคำตอบที่ชัดเจนสำหรับการโหลดรูปแบบหรือสคริปต์ก่อน มันเป็นเรื่องของการตัดสินใจในแต่ละกรณีว่าจะต้องโหลดอะไรในลำดับและสิ่งที่สามารถเลื่อนออกไปได้จนกว่าจะไม่ได้อยู่ใน "เส้นทางวิกฤติ"

เพื่อพูดคุยกับผู้สังเกตการณ์ที่ให้ความเห็นว่าเป็นการดีกว่าที่จะชะลอความสามารถของผู้ใช้ในการโต้ตอบจนกว่าแผ่นงานจะสวย มีพวกคุณหลายคนที่อยู่ตรงนั้นและรบกวนคู่ของคุณที่รู้สึกตรงกันข้าม พวกเขามาที่ไซต์เพื่อบรรลุวัตถุประสงค์และล่าช้าในความสามารถในการโต้ตอบกับไซต์ในขณะที่รอสิ่งที่ไม่สำคัญที่จะเสร็จสิ้นการโหลดจะทำให้หงุดหงิดมาก ฉันไม่ได้บอกว่าคุณผิดเพียงเพื่อคุณเท่านั้นที่ควรตระหนักว่ามีอีกฝ่ายที่มีอยู่ซึ่งไม่ได้ให้ความสำคัญกับคุณ

คำถามนี้ใช้กับโฆษณาทั้งหมดที่วางอยู่บนเว็บไซต์โดยเฉพาะ ฉันจะรักมันหากผู้เขียนเว็บไซต์แสดงผลเพียงตัวยึดตำแหน่ง div สำหรับเนื้อหาโฆษณาและตรวจสอบให้แน่ใจว่าเว็บไซต์ของพวกเขาถูกโหลดและโต้ตอบได้ก่อนที่จะแทรกโฆษณาในเหตุการณ์ onload แม้กระนั้นฉันก็อยากจะเห็นโฆษณาที่โหลดแบบซีเคียวริตี้แทนทั้งหมดในคราวเดียวเพราะมันส่งผลต่อความสามารถของฉันในการเลื่อนเนื้อหาของไซต์ในขณะที่โฆษณาที่โหลดไม่เต็ม แต่นั่นเป็นเพียงมุมมองหนึ่งคน

  • รู้ว่าผู้ใช้ของคุณและสิ่งที่พวกเขาให้คุณค่า
  • รู้จักผู้ใช้ของคุณและพวกเขาใช้สภาพแวดล้อมการเรียกดูอะไร
  • รู้ว่าแต่ละไฟล์ทำอะไรและมีข้อกำหนดเบื้องต้นอะไรบ้าง การทำทุกอย่างจะสำคัญกว่าทั้งความเร็วและความสวย
  • ใช้เครื่องมือที่แสดงเส้นเวลาของเครือข่ายเมื่อพัฒนา
  • ทดสอบในแต่ละสภาพแวดล้อมที่ผู้ใช้ของคุณใช้ มันอาจจำเป็นต้องใช้แบบไดนามิก (ฝั่งเซิร์ฟเวอร์เมื่อสร้างหน้า) เปลี่ยนลำดับของการโหลดขึ้นอยู่กับสภาพแวดล้อมของผู้ใช้
  • เมื่อมีข้อสงสัยให้เปลี่ยนลำดับและวัดอีกครั้ง
  • เป็นไปได้ว่ารูปแบบและการผสมระหว่างสคริปต์ในลำดับการโหลดจะเหมาะสมที่สุด ไม่ทั้งหมดอย่างใดอย่างหนึ่งแล้วทั้งหมดอื่น ๆ
  • ทดลองไม่เพียงแค่สิ่งที่สั่งโหลดไฟล์ แต่ที่ ศีรษะ? ในร่างกาย? หลังจากที่ร่างกาย? DOM พร้อม / โหลดแล้วหรือยัง โหลด?
  • พิจารณาตัวเลือก async และ defer เมื่อเหมาะสมเพื่อลดความล่าช้าสุทธิที่ผู้ใช้จะได้สัมผัสก่อนที่จะสามารถโต้ตอบกับหน้าเว็บได้ ทดสอบเพื่อดูว่าพวกเขาช่วยหรือทำร้าย
  • จะมีการแลกเปลี่ยนเพื่อพิจารณาเมื่อประเมินผลคำสั่งโหลดที่ดีที่สุด สวยกับการตอบสนองที่เป็นเพียงหนึ่งเดียว

1
บทความที่เชื่อมโยงไม่ได้อ้างสิทธิ์ "การเรียกใช้ Stylesheet load block script execution" อีกต่อไป นั่นไม่จริงอีกต่อไปหรือ
เกร็ก

@Greg - มันยังคงเป็นจริง สคริปต์ต้องสามารถสืบค้นแอตทริบิวต์ DOM. สไตล์ของ DOM ดังนั้นสไตล์ชีทยังคงบล็อกการเรียกใช้สคริปต์ พวกเขาอาจไม่บล็อกการโหลดสคริปต์หากพวกเขาฉลาด แต่พวกเขาจะบล็อก script.onLoad เหตุการณ์
Jimmy Breck-McKye

10

อัปเดตเมื่อวันที่ 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 สุทธิ -> น้ำตก

<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 dev -> ประสิทธิภาพ


เมื่อคำนึงถึงข้างต้นแล้วผลลัพธ์ใน 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:                                                                                                                                            

นั่นคือเหตุผลที่ document.write () เป็นหนึ่งในแนวคิดที่เลวร้ายที่สุดที่เคยทำกับ HTMLDOM
brunoais

1
The reason is that the script may want to get coordinates and other style-dependent properties of elements, like in the example above. Naturally, it has to wait for styles to load. javascript.info/…เหตุใดจึงไม่ใช้สมมติฐานเดียวกันนี้ในกรณีของ JS ก่อน ไม่สมเหตุสมผลสำหรับฉันลำดับของการดำเนินการ JS ไม่ได้บอกอะไรเกี่ยวกับจุดประสงค์ของมัน
Thorsten Schöning

4

ฉันไม่แน่ใจว่าเวลาในการ 'แสดงผล' ของการทดสอบของคุณเป็นอย่างไรโดยใช้จาวาสคริปต์ อย่างไรก็ตามให้พิจารณาเรื่องนี้

หน้าเดียวในไซต์ของคุณคือ 50k ซึ่งไม่สมเหตุสมผล ผู้ใช้อยู่บนชายฝั่งตะวันออกในขณะที่เซิร์ฟเวอร์ของคุณอยู่ทางทิศตะวันตก MTU ไม่ใช่ 10k แน่นอนดังนั้นจะมีการเดินทางไปมาไม่กี่ครั้ง อาจใช้เวลา 1/2 วินาทีในการรับหน้าและสไตล์ของคุณ โดยทั่วไป (สำหรับฉัน) javascript (ผ่าน jquery plugin และอื่น ๆ ) นั้นมีอะไรมากกว่า CSS นอกจากนี้ยังมีสิ่งที่เกิดขึ้นเมื่อการเชื่อมต่ออินเทอร์เน็ตของคุณเกิดขึ้นกลางหน้า แต่ให้เพิกเฉยต่อสิ่งนั้น (เกิดขึ้นกับฉันเป็นครั้งคราวและฉันเชื่อว่า css แสดงผล แต่ฉันไม่แน่ใจ 100%)

เนื่องจาก css อยู่ในหัวอาจมีการเชื่อมต่อเพิ่มเติมเพื่อให้ได้ซึ่งหมายความว่ามันอาจเสร็จก่อนที่หน้า อย่างไรก็ตามในระหว่างประเภทที่เหลือของหน้าจะใช้เวลาและไฟล์จาวาสคริปต์ (ซึ่งเป็นจำนวนมากไบต์) หน้าจะไม่มีการจัดรูปแบบซึ่งทำให้เว็บไซต์ / การเชื่อมต่อปรากฏช้า

แม้กระทั่งถ้าล่าม JS ปฏิเสธที่จะเริ่มต้นจนกว่า CSS จะทำเวลาในการดาวน์โหลดรหัสจาวาสคริปต์โดยเฉพาะอย่างยิ่งเมื่อห่างไกลจากเซิร์ฟเวอร์ที่ถูกตัดเป็นเวลา css ซึ่งจะทำให้เว็บไซต์ดูไม่สวย

มันเป็นการเพิ่มประสิทธิภาพขนาดเล็ก แต่นั่นคือเหตุผลสำหรับมัน


1
เซิร์ฟเวอร์อยู่บนชายฝั่งตะวันออก fwiw เห็นได้ชัดว่าคุณไม่รู้ถึงความจริงที่ว่าตอนนี้พวกเขาใช้ CDN
jcolebrand

3

นี่คือสรุปคำตอบที่สำคัญทั้งหมดข้างต้น (หรืออาจต่ำกว่าในภายหลัง :)

สำหรับเบราว์เซอร์ที่ทันสมัยใส่ CSS ทุกที่ที่คุณต้องการ พวกเขาจะวิเคราะห์ไฟล์ html ของคุณ (ซึ่งเรียกว่าการแยกวิเคราะห์เก็งกำไร ) และเริ่มดาวน์โหลด css ควบคู่ไปกับการแยกวิเคราะห์ html

สำหรับเบราว์เซอร์รุ่นเก่าวาง css ไว้ด้านบน (หากคุณไม่ต้องการแสดงหน้าเว็บที่เปลือย แต่มีการโต้ตอบก่อน)

สำหรับเบราว์เซอร์ทั้งหมดให้วาง javascript ลงในหน้าเว็บให้ไกลที่สุดเนื่องจากจะหยุดการแยกวิเคราะห์ html ของคุณ ดาวน์โหลดแบบอะซิงโครนัสได้ดีกว่า (เช่นการโทร ajax)

นอกจากนี้ยังมีบางผลการทดลองสำหรับกรณีเฉพาะที่อ้างว่าใส่จาวาสคริปต์ก่อน (ตรงข้ามกับภูมิปัญญาดั้งเดิมของการใส่ CSS ก่อน) ให้ประสิทธิภาพที่ดีขึ้น แต่ไม่มีเหตุผลเชิงตรรกะที่กำหนดไว้และขาดการตรวจสอบเกี่ยวกับการบังคับใช้อย่างแพร่หลาย ไม่สนใจตอนนี้

ดังนั้นเพื่อตอบคำถาม: ใช่ คำแนะนำในการรวม CSS ไว้ก่อน JS ไม่ถูกต้องสำหรับเบราว์เซอร์สมัยใหม่ ใส่ CSS ทุกที่ที่คุณต้องการและวาง JS ไว้ท้ายที่สุดเท่าที่จะทำได้


1

Steve Souders ได้ให้คำตอบที่ชัดเจนแล้ว แต่ ...

ฉันสงสัยว่ามีปัญหากับทั้งการทดสอบดั้งเดิมของแซมและการทำซ้ำของ Josh

การทดสอบทั้งคู่ดูเหมือนจะเกิดขึ้นในการเชื่อมต่อเวลาแฝงต่ำซึ่งการตั้งค่าการเชื่อมต่อ TCP จะมีค่าใช้จ่ายเล็กน้อย

สิ่งนี้มีผลต่อผลลัพธ์ของการทดสอบอย่างไรฉันไม่แน่ใจและฉันต้องการดูน้ำตกสำหรับการทดสอบผ่านการเชื่อมต่อที่ 'ปกติ' แต่ ...

ไฟล์แรกที่ดาวน์โหลดควรได้รับการเชื่อมต่อที่ใช้สำหรับหน้า html และไฟล์ที่สองที่ดาวน์โหลดมาจะได้รับการเชื่อมต่อใหม่ (ล้างการเปลี่ยนแปลงช่วงต้นที่มีการเปลี่ยนแปลง แต่ไม่ได้ทำที่นี่)

ในเบราว์เซอร์ที่ใหม่กว่าการเชื่อมต่อ TCP ที่สองจะเปิดขึ้นโดยเฉพาะดังนั้นค่าใช้จ่ายในการเชื่อมต่อจะลดลง / หายไปในเบราว์เซอร์รุ่นเก่าสิ่งนี้ไม่เป็นความจริงและการเชื่อมต่อที่สองจะมีค่าเปิด

จะเกิดผลอย่างไรกับการทดสอบที่ฉันไม่แน่ใจ


ไม่ทำตามเว้นแต่ว่าคุณมี pipelining ซึ่งหายากอย่างเหลือเชื่อคุณไม่น่าจะลดการตั้งค่าการเชื่อมต่อ ... เห็นด้วยว่าควรทำการทดสอบซ้ำในเวลาแฝงที่ต่ำ
Sam Saffron

ถ้าคุณดูที่น้ำตกแห่งนี้คุณสามารถดูได้ว่า Chrome เปิดการเชื่อมต่อครั้งที่สองไว้ที่ใดก่อนที่มันจะต้องการwebpagetest.org/result/ (IE9 ทำเช่นเดียวกัน) ... ฉันคิดว่าเวลาแฝงปกติสำหรับจุดประสงค์ TCP มากกว่าระดับต่ำ สิ่งแวดล้อมได้ทำการทดสอบหรือไม่
Andy Davies

2
Re: "Steve Souders ได้ให้คำตอบที่ชัดเจนแล้ว แต่ ... " สิ่งที่มีวิวัฒนาการของเว็บก็คือไม่มีคำตอบที่ชัดเจน :) มี 3-4 วิธีในการโหลดสคริปต์และสิ่งต่าง ๆ เปลี่ยนไป ที่เกิดขึ้นจริงที่ถูกต้องความหมายควรได้รับจริงสตีฟจะพูดว่า "CSS ใส่ก่อน Synchronous JavaScript" มิฉะนั้นคนที่ได้รับมันผิดโดย generalizing ขณะที่มันเป็นกฎสำหรับสคริปต์ทั้งหมด ...
hexalys

ใช่ แต่คนส่วนใหญ่เพียงรวมสคริปต์ไว้ด้วยกันดังนั้นคำแนะนำของ Steve ก็ดีต่อผู้ที่ไม่ได้ฝึกหัด
Andy Davies

1

ฉันคิดว่านี่จะไม่เป็นจริงสำหรับทุกกรณี เพราะ css จะดาวน์โหลดแบบขนาน แต่ js ไม่สามารถ พิจารณากรณีเดียวกัน

แทนที่จะมี css เดี่ยวให้ใช้ 2 หรือ 3 css และลองใช้วิธีเหล่านี้

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

ฉันแน่ใจว่า css .. cs .. js จะให้ผลลัพธ์ที่ดีกว่าคนอื่น ๆ ทั้งหมด


0

เราต้องจำไว้ว่าเบราว์เซอร์ใหม่ทำงานบนเอ็นจิ้น Javascript, parsers และอื่น ๆ , การเพิ่มประสิทธิภาพของรหัสทั่วไปและปัญหามาร์กอัพในลักษณะที่ปัญหาที่พบในเบราว์เซอร์โบราณเช่น <= IE8 ไม่เกี่ยวข้องกันอีกต่อไป เกี่ยวกับมาร์กอัป แต่รวมถึงการใช้ตัวแปร JavaScript ตัวเลือกองค์ประกอบ ฯลฯ ฉันสามารถมองเห็นได้ในอนาคตที่ไม่ไกลจากสถานการณ์ที่เทคโนโลยีได้มาถึงจุดที่ประสิทธิภาพไม่ได้เป็นปัญหาอีกต่อไป


ประสิทธิภาพเป็นปัญหาเสมอ ฉันเกือบจะเพิกเฉยต่อเบราว์เซอร์ที่ไม่เป็นไปตามข้อกำหนดที่มีอยู่ ฉันเพิ่งเตรียมโค้ดของฉันเพื่อให้คนที่ติดตามงานจำเพาะด้วยความเร็วเต็มพิกัดและคนอื่น ๆ ที่ฉันเพิ่งทำก็จะทำงาน ตัวอย่างเช่นถ้ามันใช้งานได้ใน IE8 เท่านั้น ok ทั้งหมด
brunoais

-5

โดยส่วนตัวแล้วฉันจะไม่ให้ความสำคัญกับ "ภูมิปัญญาพื้นบ้าน" มากเกินไป สิ่งที่อาจเป็นจริงในอดีตอาจไม่เป็นจริงในขณะนี้ ฉันจะสมมติว่าการดำเนินการทั้งหมดที่เกี่ยวข้องกับการตีความและการแสดงผลของหน้าเว็บนั้นไม่ตรงกันทั้งหมด ("การดึงข้อมูล" และ "การดำเนินการ" เป็นสองสิ่งที่แตกต่างอย่างสิ้นเชิงที่อาจถูกจัดการโดยเธรดที่แตกต่างกันฯลฯ ) และ ไม่ว่าในกรณีใดก็ตามที่อยู่นอกเหนือการควบคุมหรือข้อกังวลของคุณ

ฉันจะใส่การอ้างอิง CSS ในส่วน "หัว" ของเอกสารพร้อมกับการอ้างอิงใด ๆ กับสคริปต์ภายนอก (สคริปต์บางตัวอาจต้องการที่จะอยู่ในร่างกายและถ้าเป็นเช่นนั้นบังคับพวกเขา)

นอกเหนือจากนั้น ... หากคุณสังเกตว่า "สิ่งนี้ดูเหมือนจะเร็วกว่า / ช้ากว่าบนเบราว์เซอร์นี้ /" ถือว่าการสังเกตนี้เป็นความอยากรู้ที่น่าสนใจ แต่ไม่เกี่ยวข้องและไม่ปล่อยให้มันมีอิทธิพลต่อการตัดสินใจออกแบบของคุณ หลายสิ่งหลายอย่างเปลี่ยนแปลงไปเร็วเกินไป (ทุกคนต้องการวางเดิมพันใด ๆ ว่าจะใช้เวลากี่นาทีก่อนที่ทีม Firefox จะออกมาพร้อมกับอีกผลิตภัณฑ์ที่วางจำหน่ายชั่วคราวของพวกเขาใช่ไหมฉันไม่ใช่)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.