Lỗi Javascript phổ biến ảnh hưởng nghiêm trọng đến hiệu suất? [đóng cửa]


10

Tại một cuộc họp UI / UX gần đây mà tôi tham dự, tôi đã đưa ra một số phản hồi trên một trang web sử dụng Javascript (jQuery) cho tương tác và giao diện người dùng của nó - đó là hoạt hình và thao tác khá đơn giản, nhưng hiệu suất trên một máy tính tốt là rất kinh khủng.

Nó thực sự nhắc nhở tôi về rất nhiều trang web / chương trình mà tôi đã thấy với cùng một vấn đề, trong đó một số hành động nhất định chỉ phá hủy hoàn toàn hiệu suất. Nó chủ yếu trong các tình huống (hoặc ít nhất là đáng chú ý hơn) trong đó Javascript gần như đóng vai trò thay thế Flash. Điều này trái ngược hoàn toàn với một số ứng dụng web mà tôi đã sử dụng có nhiều Javascript và chức năng hơn nhưng hoạt động rất trơn tru (COGNOS của IBM là thứ tôi có thể nghĩ ra khỏi đỉnh đầu).

Tôi muốn biết một số vấn đề phổ biến không được xem xét khi phát triển JS sẽ giết chết hiệu suất của trang web.


Có khả năng giống như với mọi chương trình khác: Thực hiện nhiều công việc hơn mức cần thiết và thực hiện cùng một công việc nhiều lần, thường là hàng trăm lần.

1
@delnan điều đó rất đúng, nhưng có vẻ như nó phổ biến hơn rất nhiều trong JS. Nhận thức có lẽ?
Nic

1
Sẽ hơi khó để nói về 'trang web' khi nói về JavaScript. Nó ở khắp mọi nơi và được sử dụng cho mọi thứ trong những ngày này.
Adam Crossland

@Adam Crossland bạn hoàn toàn đúng - trong trường hợp tương tự, tôi nghĩ rằng tôi đã giúp một nhà phát triển với một ứng dụng gốc cũng phụ thuộc rất nhiều vào jQuery.
Nic

1
Không chính xác là một câu trả lời cho câu hỏi của bạn, vì vậy tôi đưa ra nhận xét: Tôi đã trải qua các tình huống trong đó JavaScript thực hiện rất nhiều kết xuất và nó thực sự là công cụ kết xuất của trình duyệt sử dụng hết giây. Do đó, để xử lý nút cổ chai hiệu năng, trước tiên tôi sẽ tìm các hoạt động kết xuất không cần thiết.
user281377

Câu trả lời:


8

Một kẻ giết người hiệu suất phổ biến đang kêu gọi .lengthHTMLCollection trong một forvòng lặp:

function foo(collection) {
    for (var index = 0; index < collection.length; index++) {
        // do something awesome here
    }
}

Mô hình chống đó làm cho kích thước của bộ sưu tập được tính trên mỗi lần đi qua vòng lặp. Cách tiếp cận tốt hơn là tính toán độ dài bên ngoài vòng lặp:

function foo(collection) {
    var collectionLen = collection.length;
    for (var index = 0; index < collectionLen; index++) {
        // do something awesome here
    }
}

3
Phụ thuộc vào trình duyệt. Lấy điểm chuẩn này làm ví dụ: Trong FF 5, phiên bản "bình thường" chạy cùng lúc với phiên bản "tối ưu hóa". Và ngay cả trong các trình duyệt thực sự cũ và lỗi, một cái gì đó như thế này có thể sẽ không phải là nút cổ chai nếu JS thực sự làm bất cứ điều gì quan tâm với các yếu tố.

1
Hừm! Có lẽ các trình biên dịch JIT tối ưu hóa cao hiện nay đang làm cho chút khôn ngoan này trở nên lỗi thời.
Adam Crossland

4
Tôi không phải là một chuyên gia thực sự ở đây, nhưng từ ECMA, có vẻ như chiều dài chỉ là một thuộc tính của đối tượng mảng. Vì vậy, gọi nó chỉ trả về giá trị thay vì đếm tất cả các yếu tố. Không biết tất cả các triển khai có tuân theo thông số kỹ thuật không, nhưng nếu có, mã của bạn hoàn toàn không cải thiện hiệu suất.
Jacek Prucia

4
@JacekPrucia Ông nói bộ sưu tập , không phải mảng - thông thường, trong mã thực, điều này có nghĩa là một danh sách các phần tử DOM được trả về bởi các hàm như document.getElementsByTagName. Hàm trả về một live nodeListmà tính lại độ dài của nó mỗi khi thuộc .lengthtính được truy cập.
Yi Jiang

2
@JacekPrucia điểm chuẩn đó là một cải tiến hiệu suất. Tra cứu tài sản không rẻ.
Raynos

4

Không, vấn đề không đến từ JS được sử dụng làm thay thế flash. Nếu bạn không bị thuyết phục với điều đó, hãy ghi lại cho bạn về bản mô tả: nó rất gần với JS.

Là kẻ giết người biểu diễn, bạn có thể tìm thấy một số thực hành xấu:

  • Đính kèm trình xử lý sự kiện vào sự kiện liên tục, như cuộn, vuốt chuột hoặc những thứ tương tự. Điều này có 2 nhược điểm: nếu sự kiện không được kích hoạt đủ, ứng dụng của bạn sẽ không phản ứng. Nếu nó được kích hoạt quá nhiều, bạn sẽ có một tải CPU lớn mà không có gì.
  • Thực hiện các cuộc gọi AJAX đồng bộ. Javascript không phải là đa luồng, sau đó, khi một phần của JS đang chờ một cái gì đó, ứng dụng của bạn bị đóng băng. Bạn nên sử dụng các cuộc gọi AJAX không đồng bộ tốt hơn và cùng một cách sử dụng setTimeout / setInterval để phân chia giai đoạn tính toán dài và giữ cho ứng dụng của bạn hoạt động trở lại.
  • Độ phức tạp thuật toán cao như trong bất kỳ ngôn ngữ khác.

Tôi đã thấy nhiều hơn một vài ứng dụng cố gắng xoay, làm dịu hoặc làm động các hình ảnh toàn trình duyệt và thất bại thảm hại trong quá trình - đó là nơi nhận xét thay thế Flash bắt nguồn từ :)
Nic

Vì chữ A đầu tiên trong AJAX là viết tắt của không đồng bộ, về mặt kỹ thuật, nó không phải là AJAX nếu nó đồng bộ, nhưng quan điểm của bạn vẫn là một điểm tốt.
Karl Bielefeldt

Đúng, nó không hoàn toàn là AJAX. Nhưng dù sao, điều này phải tránh: D
deadalnix

3

Tôi đã đưa ra một số phản hồi trên một trang web sử dụng Javascript (jQuery) cho tương tác và giao diện người dùng của nó - đó là hình ảnh động và thao tác khá đơn giản, nhưng hiệu suất trên một máy tính tốt là rất khủng khiếp.

Một vấn đề lớn nhất với hiệu năng là sử dụng các khái niệm trừu tượng mức cao (như jQuery) mà không hiểu mô hình DOM cơ bản và mô hình hoạt hình CSS3 (hoặc canvas hoặc svg).

Nếu bạn không biết cách thực hiện mà không có sự trừu tượng thì bạn hoàn toàn không có kiến thức về kỹ thuật nào nhanh hay chậm.

Tìm hiểu JavaScript, Tìm hiểu DOM. Một khi bạn biết hai điều đó và bạn biết những gì trừu tượng của bạn làm dưới mui xe thì bạn có thể sử dụng chúng một cách hiệu quả. Tất nhiên hầu hết thời gian bạn nhận ra sự trừu tượng là làm chậm và chỉ cần thực hiện thủ công mà không cần thư viện.


1

Cái hay và nhược điểm của Javascript là nó cực kỳ linh hoạt. Điều đó đang được nói, nó thực sự cho phép bạn làm những việc mà có lẽ bạn không nên làm trong nhiều trường hợp.

Từ các đánh giá mã mà tôi đã tham gia, các mối quan tâm chính có xu hướng liên quan đến kết xuất CSS. Đối với các nhà phát triển JS mới hơn, chúng ta có xu hướng thấy quá nhiều biến được sử dụng trong phạm vi toàn cầu.

Ngoài ra, đóng cửa không đúng cách thường có thể gây rò rỉ bộ nhớ. Tuy nhiên, hầu hết các khung Javascript hiện đại đều ngăn chặn các loại sự cố này miễn là mã của bạn tuân theo khung.


0

Đây là một liên kết nhanh mà tôi đã tìm thấy cách đây một năm về việc viết mã jquery tốt hơn: http://net.tutsplus.com/tutorials/javascript-ajax/10-ways-to-instantly-increas-your-jquery-performance /

Một điều tôi vừa tìm thấy trong một mã đồng nghiệp đang giết chết hiệu năng là bộ nhớ đệm dữ liệu không cần lưu vào bộ nhớ cache.

Thí dụ:

var table = $("#data").dataTable(.....);

DataTables là một trình cắm thêm jQuery mà chúng tôi sử dụng để tạo các lưới tốt. Dù sao, bảng có gần 5k hàng trong đó, áp dụng trình cắm DataTables và sau đó lưu nó vào biến bảng thực sự khiến cả FireFox và IE cảnh báo rằng một tập lệnh mất quá nhiều thời gian. Đạo đức của câu chuyện, chỉ lưu trữ dữ liệu nếu bạn cần.


1
Âm thanh như DataTables là một plugin thực sự kém hiệu quả / kém hơn là một vấn đề với bộ nhớ đệm. 5k là gì.
Raynos

@Raynos: Anh nói 5k hàng chứ không phải 5 kilobyte dữ liệu. Một "hàng" có thể là một điều rất lớn.
Nông dân Chris

@ChrisFarmer Nếu một "hàng" là một thứ rất lớn thì bạn đã gặp một vấn đề khác .
Raynos

-1

Từ những gì tôi nghe thấy forcác vòng lặp được tính toán nhanh hơn so với jQuery $.each().


3
Đây có phải là một câu trả lời đùa?
Raynos
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.