2011-08-18 33 views
6

Sự khác nhau cơ bản giữa 3 cách này để tải js lười biếng hoặc tải ondemand là gì và tại sao?tải chậm javascript

kịch bản 1:

$.getScript = function(url, callback, cache){ 
    $.ajax({ 
     type: "GET", 
     url: url, 
     success: callback, 
     dataType: "script", 
     cache: cache 
    }); 
}; 

script2:

function require(file, callback) { 
    var script = document.getElementsByTagName('script')[0], 
     newjs = document.createElement('script'); 

    // IE 
    newjs.onreadystatechange = function() { 
     if (newjs.readyState === 'loaded' || newjs.readyState === 'complete') { 
      callback(); 
     } 
    }; 

    // others 
    newjs.onload = function() { 
     callback(); 
    }; 

    newjs.src = file; 
    script.parentNode.insertBefore(newjs, script); 
} 

document.getElementById('id').onclick = function() { 
    require('ondemand.js', function() { 
     extraFunction('loaded from the parent page'); 
     document.body.appendChild(document.createTextNode('done!')); 
    }); 
}; 

script3:

$L = function (c, d) { 
    for (var b = c.length, e = b, f = function() { 
      if (!(this.readyState 
        && this.readyState !== "complete" 
        && this.readyState !== "loaded")) { 
       this.onload = this.onreadystatechange = null; 
       --e || d() 
      } 
     }, g = document.getElementsByTagName("head")[0], i = function (h) { 
      var a = document.createElement("script"); 
      a.async = true; 
      a.src = h; 
      a.onload = a.onreadystatechange = f; 
      g.appendChild(a) 
     }; b;) i(c[--b]) 
}; 
+0

Nếu bạn đã viết các hàm đó, tôi hy vọng bạn nhận ra rằng 'readyState == 'loaded'' xảy ra * trước * tập lệnh được thực hiện và'' complete'' xảy ra * sau *. – zzzzBov

+0

có đúng ... thậm chí tôi đang lên kế hoạch phân tích cú pháp tập lệnh và không thực thi vì việc thực hiện mất nhiều thời gian hơn phân tích cú pháp – paul

Trả lời

7
  1. Sử dụng ajax để tải tập lệnh. Cụ thể hơn, nó sử dụng XHR để tải một số js và có sẵn cho trình duyệt. Không chặn được thực hiện. Nó vẫn thực thi chính sách gốc.
  2. Sửa đổi tiêu đề để chèn tệp .js mới bằng cách tạo phần tử <script/>. Điều này cũng không chặn trình duyệt tải trang.
  3. Có điều tương tự như # 2 nhưng dường như hỗ trợ một loạt các tập lệnh. Nó cũng đặt async thành true mà không gây ra sự chặn nào. Vòng lặp for chỉ gây nhầm lẫn hơn vì nó tạo ra nhiều phương thức nặc danh hơn.
+0

cảm ơn ... được mô tả độc đáo – paul

+0

có vấn đề gì với bộ nhớ đệm khi chúng tôi tiêm tập lệnh không có ajax không? chức năng 1 kể từ XHR của nó, chúng tôi có thể xác định bộ nhớ cache: bộ nhớ cache – paul

+0

Tôi nghĩ rằng tất cả trong số họ có thể có vấn đề đó. Trình duyệt thậm chí có thể lưu trữ các yêu cầu xhr. Bạn có thể chia bộ nhớ cache bằng truy vấn ngẫu nhiên. Nếu bạn kiểm soát máy chủ thì bạn có thể chọn không lưu vào bộ nhớ cache. –

2
  1. vẻ để lấy kịch bản với một XMLHttpRequest và eval() nó. Điều này sẽ không hoạt động nếu tập lệnh không được lưu trữ trên cùng một giao thức/tên miền/cổng.

  2. và 3. dường như cả hai đều làm điều tương tự: chúng tạo thành phần <script src="the script url"></script>, liên kết onload sự kiện trên đó và chèn nó trên trang. Kịch bản được thực thi bởi trình duyệt khi nó được tải và sự kiện onload được kích hoạt.

+0

bạn nghĩ gì về bộ nhớ đệm? kể từ trong chức năng đầu tiên tôi có thể vượt qua một bộ nhớ cache tài sản: bộ nhớ cache trong khi cho 2 trường hợp khác nó sẽ là một vấn đề? – paul

+0

cả hai phương pháp đều thân thiện với bộ nhớ cache, miễn là máy chủ gửi tiêu đề chính xác – arnaud576875

1

bạn nên cố gắng thư viện mới này được gọi là head.js

họ có một số ý tưởng thú vị và apis .. hy vọng nó giúp.

hoặc những gì bạn có thể làm là sử dụng yêu cầu xhr bình thường để lấy tên tệp kịch bản và sử dụng phương pháp như thế này để chèn vào phần .. Tôi cũng đã thêm phần removeScript.

addScript = function(file) 
{ 
    var headID = document.getElementsByTagName("head")[0];   
    var newScript = document.createElement('script'); 
    newScript.type = 'text/javascript'; 
    newScript.src = file; 
    headID.appendChild(newScript); 
}; 
removeScript = function(file) 
{ 
    var headID = document.getElementsByTagName("head")[0].children; 
    for(var i in headID) 
     if(headID[i].tagName == "SCRIPT") 
      if(headID[i].getAttribute('src') == file) 
       headID[i].parentNode.removeChild(headID[i]); 
} 

nếu bạn đang sử dụng một thư viện như jquery bạn không cần phải lo lắng về bất cứ điều gì bạn có thể nhận được đánh dấu html hoặc kịch bản từ máy chủ và sử dụng .html() api để trong chèn nó vào dom

+0

Điều này sẽ là một bình luận vì nó không thực sự trả lời bất cứ điều gì. –

+0

cảm ơn thông tin. :/ – Baz1nga

+0

@zzzz vâng tôi nhìn qua head.js, labjs và controljs nhưng cố gắng tìm ra giải pháp của riêng tôi thay vì sử dụng một thư viện khác – paul

2
  1. Gets kịch bản thông qua ajax, và eval() 's nội dung
  2. Chèn một yếu tố script vào yếu tố head và báo cáo lại khi nó đã được nạp
  3. Tương tự như (2) nhưng chấp nhận và mảng của url script s, và cách viết phức tạp hơn

(2) và (3) cả hai đều có thể không tương thích với các trình duyệt cũ hơn (ví dụ, Firefox 3.x và dưới đây không hỗ trợ).

(1) có lẽ là mạnh mẽ nhất, tương thích khôn ngoan, vì nó chỉ yêu cầu XHR.Nhưng nếu bạn gặp lỗi trong mã bạn tải theo cách đó, giao diện điều khiển của trình duyệt có thể không hữu ích lắm, vì lỗi vừa xảy ra trong "mã được đánh giá" chứ không phải trong một tệp/dòng cụ thể. Điều đó nói rằng, tải chậm thường là một điều tối ưu hóa, vì vậy bạn chỉ có thể bao gồm các kịch bản thông thường, hoặc với bất kỳ phương pháp nào khác trong số 2 phương pháp, trong khi gỡ lỗi.

Các vấn đề liên quan