2012-03-29 35 views
9

Tôi đang cố gắng viết một ứng dụng vẽ đơn giản dựa trên html (mã đơn giản được đính kèm dưới đây). Tôi đã thử nghiệm điều này trên các thiết bị sau:Sự kiện chạm Javascript chậm trên Android

  • iPad 1 và 2: Các công trình lớn
  • ASUS T101 chạy Windows: Các công trình lớn
  • Samsung Galaxy Tab: Vô cùng chậm và chắp vá - không sử dụng được.
  • Lenovo IdeaPad K1: Cực kỳ chậm và chắp vá - không sử dụng được.
  • Asus Transformer Prime: Độ trễ đáng chú ý so với iPad - gần với khả năng sử dụng.

Máy tính bảng Asus đang chạy ICS, các máy tính bảng Android khác đang chạy phiên bản 3.1 và 3.2. Tôi đã thử nghiệm bằng trình duyệt Android chứng khoán. Tôi cũng đã thử Android Chrome Beta, nhưng điều đó thậm chí còn tồi tệ hơn.

Dưới đây là một đoạn video trong đó chứng tỏ vấn đề: http://www.youtube.com/watch?v=Wlh94FBNVEQ

Câu hỏi của tôi là tại sao các máy tính bảng Android để làm chậm? Tôi đang làm điều gì đó sai hoặc là một vấn đề kế thừa với hệ điều hành Android hoặc trình duyệt, hoặc có bất cứ điều gì tôi có thể làm về nó trong mã của tôi?

multi.html:

<html> 
<body> 

<style media="screen"> 
    canvas { border: 1px solid #CCC; } 
</style> 

<canvas style="" id="draw" height="450" width="922"></canvas> 

<script class="jsbin" src="jquery.js"></script> 
<script src="multi.js"></script> 

</body> 
</html> 

multi.js:

var CanvasDrawr = function(options) { 
    // grab canvas element 
    var canvas = document.getElementById(options.id), 
    ctxt = canvas.getContext("2d"); 

canvas.style.width = '100%' 
    canvas.width = canvas.offsetWidth; 
    canvas.style.width = ''; 

    // set props from options, but the defaults are for the cool kids 
    ctxt.lineWidth = options.size || Math.ceil(Math.random() * 35); 
    ctxt.lineCap = options.lineCap || "round"; 
    ctxt.pX = undefined; 
    ctxt.pY = undefined; 

    var lines = [,,]; 
    var offset = $(canvas).offset(); 

    var eventCount = 0; 

    var self = { 
    // Bind click events 
    init: function() { 
     // Set pX and pY from first click 
     canvas.addEventListener('touchstart', self.preDraw, false); 
     canvas.addEventListener('touchmove', self.draw, false); 
    }, 

    preDraw: function(event) { 
     $.each(event.touches, function(i, touch) { 

     var id = touch.identifier; 

     lines[id] = { x  : this.pageX - offset.left, 
         y  : this.pageY - offset.top, 
         color : 'black' 
        }; 
     }); 

     event.preventDefault(); 
    }, 

    draw: function(event) { 
     var e = event, hmm = {}; 

     eventCount += 1; 
     $.each(event.touches, function(i, touch) { 
     var id = touch.identifier, 
     moveX = this.pageX - offset.left - lines[id].x, 
     moveY = this.pageY - offset.top - lines[id].y; 

     var ret = self.move(id, moveX, moveY); 
     lines[id].x = ret.x; 
     lines[id].y = ret.y; 
     }); 

     event.preventDefault(); 
    }, 

    move: function(i, changeX, changeY) { 
     ctxt.strokeStyle = lines[i].color; 
     ctxt.beginPath(); 
     ctxt.moveTo(lines[i].x, lines[i].y); 

     ctxt.lineTo(lines[i].x + changeX, lines[i].y + changeY); 
     ctxt.stroke(); 
     ctxt.closePath(); 

     return { x: lines[i].x + changeX, y: lines[i].y + changeY }; 
    }, 
    }; 

    return self.init(); 
}; 


$(function(){ 
    var drawr = new CanvasDrawr({ id: "draw", size: 5 }); 
}); 

Trả lời

8

Nhìn vào mã của bạn, bạn nên làm một số tối ưu hóa. Ngay từ dơi, không bao giờ sử dụng $ .each() của jQuery để làm các vòng lặp. Ngoài ra, mỗi khi bạn thăm dò ý kiến ​​bên trái, trên cùng, chiều rộng hoặc chiều cao của một cái gì đó, bạn đang khiến trình duyệt dừng hoạt động của nó, vẽ lại toàn bộ màn hình và tìm cho bạn giá trị chính xác nhất. Lưu trữ các giá trị này trong biến javascript thay thế. Sử dụng tính năng dòng thời gian của google chrome để tìm và loại bỏ các loại sơn và bản vẽ không cần thiết. Dưới đây là một số liên kết hữu ích:

Nicholas C. Zakas cung cấp cho bạn một số mẹo tránh phản xạ. http://oreilly.com/server-administration/excerpts/even-faster-websites/writing-efficient-javascript.html

Dưới đây là Zakas cho bài thuyết trình của mình để các lập trình viên của Google: http://www.youtube.com/watch?v=mHtdZgou0qU

Paul Irish Tăng tốc JavaScript chậm trước mắt bạn: http://www.youtube.com/watch?v=Vp524yo0p44 Xin lưu ý, tại thời điểm video đó, dòng thời gian là một tính năng beta trong Chrome. Nó bây giờ là tiêu chuẩn trong Chrome 20. Nếu bạn không nhìn thấy nó, hãy cập nhật Chrome của bạn.

Thật không may ... Ngay cả với tất cả những tối ưu hóa ... như năm 2012 ...

thiết bị Android MOST VẪN :-(CHẬM

Các sự kiện liên lạc không bắn càng nhanh cũng như các thiết bị của Apple vì các thiết bị của Apple chỉ có phần cứng tốt hơn so với hầu hết các thiết bị chạy hệ điều hành Android. Các thiết bị của Apple có các chip và chip đồ họa nổi đặc biệt ngoài CPU chính. Nhiều thiết bị Android không chứa các phần tử mở rộng đó ra các con chip, thay vào đó chúng có các chip toán học dấu phẩy động ảo.

Điều duy nhất bạn có thể làm để phù hợp với các thiết bị Android chậm hơn là phát hiện chúng và giảm thiểu trải nghiệm người dùng một cách duyên dáng. Ví dụ: tôi đã tạo băng chuyền sản phẩm có thể kéo được. Đối với Android, tôi loại bỏ tùy chọn kéo và thêm các mũi tên cuộn có thể nhấp để di chuyển băng chuyền sang trái hoặc phải một tập hợp các pixel cố định tại một thời điểm.

+0

Có gì sai với $ .each() của jQuery để liệt kê một bộ sưu tập? – simbolo

+0

Nếu bạn đang làm điều gì đó hiếm khi xảy ra, như sau một domReady hoặc pageResize, thì không có gì sai với $ .each(). Tuy nhiên, nếu bạn đang thực hiện một hoạt ảnh, $ .each() quá chậm. Nó là một bao vây, do đó, nó đã thiết lập một đối tượng, làm một số crud, sau đó loại bỏ các đối tượng. Zakas đưa ra một lời giải thích tốt trong bài thuyết trình của mình cho các lập trình viên của Google (xem ở trên). – mrbinky3000

+0

Cảm ơn, tôi đã xem xét một số kết quả jsPerf (http://jsperf.com/jquery-each-vs-regular-for-vs-optimized-for-vs-foreach/3) ví dụ: $ .each có vẻ như chậm hơn nhiều so với sử dụng các phương thức JavaScript gốc. – simbolo

3

Cách duy nhất để thực sự biết ở đâu và tại sao mã của bạn là kém là để cấu hình nó.

Chrome Mobile cho phép bạn connect to the WebKit inspector from your desktop, cấp cho bạn quyền truy cập vào các công cụ gỡ lỗi tuyệt vời mà bạn đã sử dụng trong Công cụ dành cho nhà phát triển của Chrome.

Khi bạn đã kết nối với Chrome Mobile, hãy lập cấu hình tập lệnh của bạn và xem những chức năng nào đang nhai thời gian CPU. Sau đó, bạn sẽ có thể bắt đầu tìm ra cách tối ưu hóa các chức năng đó.

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