2013-03-05 19 views
5

Tôi có một số mã javascript/jquery (cho một trang web nội bộ) mà có rất nhiều xử lý phía khách hàng trên một bảng lớn. Nó chạy chậm một chút, nhưng đó là OK.Làm thế nào để cho javascript "hơi thở"

Vấn đề là nó đóng băng trình duyệt trong khi chạy qua các vòng mà nó cần thực hiện. Điều này có hai hiệu ứng không mong muốn:

  1. Trình xử lý spinner (ảnh động gif, nhưng tôi cũng cố spin.js và có cùng sự cố) bị treo.
  2. Nếu có đủ hàng trong bảng, các vòng mất nhiều thời gian và trình duyệt báo cáo một kịch bản không đáp ứng

Có cách nào tôi có thể có một số loại của một "hơi thở" tuyên bố trong các mã, sao cho mỗi (nói) 100 lần lặp lại, nó tạm dừng để cho phép quay quay và trình duyệt biết rằng tập lệnh vẫn đang hoạt động trên đó? Giống như (pseudo code):

for (i=0;i<20000;i++) 
{ 
    fnProcessRow(); 
    if (i % 100 == 0) breath(); 
} 
+3

Bạn có thể đăng mã thích hợp mà bạn gặp sự cố về hiệu suất không? Có lẽ điều đó có thể được tối ưu hóa trước tiên trước khi xem xét các cấu trúc "chờ đợi" nhân tạo khác –

+0

Có, nhưng chỉ khi bạn đang sử dụng một chức năng tự thực thi thay vì một vòng lặp for. Bạn cũng có thể di chuyển điều này đến một webworker trong các trình duyệt hỗ trợ nó. –

+0

có thể thực hiện bất kỳ thao tác nào trên máy chủ để làm giảm tải trên giao diện người dùng không? – Evan

Trả lời

1

Một cách để chia tay javascript của bạn là để chia chế biến bạn thành những phần và sử dụng setTimeout() để thực hiện các "đoạn" bên cạnh

Hãy cho tôi biết nếu bạn cần một số mã để cho bạn thấy những gì tôi có ý nghĩa.

+0

tiếc là điều này là không thể trong tình huống này vì tôi không có quyền kiểm soát mã xử lý để làm điều này, trừ khi kích thước chunk là 1 :) –

+0

Nếu bạn không thể chia nhỏ quá trình xử lý thành các bit nhỏ hơn thì bạn chỉ là khu nghỉ mát là sử dụng nhân viên web. Điều này sẽ không làm cho nó tương thích với tất cả các trình duyệt hiện có (tại thời điểm này, anyway) –

1

Không có phương pháp thiết lập để làm điều này vì nó phụ thuộc rất cụ thể vào mã của bạn. Một cái gì đó như thế này sẽ hoạt động:

fnProcessRows(0, 10000); 

function fnProcessRows(start, end) { 
    /* do row processing */ 

    if (end < totalRows) { 
     setTimeout(function() { 
      fnProcessRows(start + 10000, end + 10000); 
     }, 1000); 
    } 
}); 

Điều này sẽ xử lý 10000 hàng có ngắt một giây ở giữa. Điều này có thể có các hiệu ứng phụ tiềm ẩn như hiển thị các hàng "đã xử lý" có hàng "chưa xử lý", có thể không mong muốn. Nếu không, thì đây sẽ là một giải pháp khá đơn giản để giúp đỡ.

Tất nhiên, bạn có thể giảm 10000 xuống mức khác nếu đó là vẫn còn không phản hồi; nó sẽ không phản hồi chỉ trong một khoảng thời gian rất ngắn mà người dùng sẽ gặp khó khăn khi nhận thấy.

+0

Thật không may (không rõ ràng từ ví dụ đơn giản của tôi) việc xử lý được thực hiện thông qua một cuộc gọi lại cũng nằm ngoài tầm kiểm soát của tôi, vì vậy tôi không thể sử dụng setTimeouts để xử lý hàng loạt các cuộc gọi lại. Tôi có thể sử dụng một setTimeout trên mỗi cuộc gọi mặc dù, có thể làm việc. –

0

Xem this question.

Nếu bạn không muốn đi setTimeout/đường setInterval, hãy thử thêm:

if (i % 100) { $("selector for your animated image").width(); } 

Trên một số người (nhất?) Trình duyệt sẽ buộc nó để tái bố trí và render.

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