2012-04-11 15 views
9

Tôi đã luôn tin tưởng (mặc dù bây giờ tôi nghi ngờ tính xác thực của những niềm tin) rằng:Động cơ bộ chọn đọc chính xác theo hướng nào?

div.name 

Là nhanh hơn:

.name 

Tuy nhiên tôi đã đọc gần đây mà hầu hết các động cơ CSS selector đọc từ phải sang trái, trong trường hợp nào thì ví dụ đầu tiên thực sự sẽ chậm hơn? Khi công cụ chọn sẽ đơn giản tìm mọi phần tử với một lớp tên, và sau đó phải xác định phần tử nào trong số đó là div s?

Cách nào công cụ chọn công cụ chọn CSS nói chung? Trái sang phải hoặc phải sang trái? Và nếu họ thường đọc từ phải sang trái, có thể ai đó vui lòng cung cấp cho tôi lời giải thích về lý do tại sao (tôi không thể hiểu được cách đọc từ phải sang trái về công cụ chọn).

+0

Dường như câu hỏi này đã được hỏi: http://stackoverflow.com/questions/5797014/css-selectors-parsed-right-to-left-why – Joe

+0

Đầu tiên nói "Kiểm tra tên lớp" tên trong tất cả các phần tử DIV ", phần thứ hai nói" Kiểm tra tên lớp 'tên' trong ** TẤT CẢ các phần tử ** ". có ý nghĩa với tôi đầu tiên sẽ nhanh hơn không? – rlemon

+1

Câu hỏi được liên kết giải thích tại sao bộ chọn được đọc từ phải sang trái nói chung, vì vậy '#foo ul.round.fancy li.current' được đọc' li.current, ul.round.fancy, # foo', nhưng nó có phải là thực sự đọc từ phải sang trái trong mỗi phần tử ('.current, li, .fancy, .round, ul, # foo')? Nó phải được? –

Trả lời

10

Tuy nhiên tôi đã đọc gần đây mà hầu hết các động cơ chọn CSS đọc từ phải sang trái, trong trường hợp này sẽ không phải là ví dụ đầu tiên thực sự là chậm?

Cách nào để công cụ chọn CSS đọc nói chung? Trái sang phải hoặc phải sang trái? Và nếu họ thường đọc từ phải sang trái, có thể ai đó vui lòng cung cấp cho tôi lời giải thích về lý do tại sao (tôi không thể hiểu được cách đọc từ phải sang trái về công cụ chọn).

Thẳng thắn, không thể biết bộ chọn nào sẽ chậm hơn trong một trình duyệt cụ thể, ít hơn nhiều trên các trình duyệt. Hiệu suất có xu hướng dao động và không thể đoán trước, đặc biệt là ở quy mô vi mô như vậy và với cấu trúc tài liệu không thể đoán trước. Ngay cả khi chúng ta nói về hiệu suất lý thuyết, nó cuối cùng phụ thuộc vào việc thực hiện. Khi đã nói rằng, như được hiển thị trong Boris Zbarsky's answer to this other question và trong Guffa's answer to yours, một trình duyệt điển hình (điều này đúng với tất cả các công cụ bố cục chính) sẽ lấy một phần tử và đánh giá tất cả các bộ chọn ứng cử viên để xem nó phù hợp với gì hơn là tìm kiếm thiết lập các yếu tố phù hợp với một bộ chọn nhất định. Đây là một sự khác biệt tinh tế nhưng rất quan trọng. Boris đưa ra một lời giải thích kỹ thuật không chỉ vô cùng chi tiết, mà còn có thẩm quyền (khi anh ta làm việc trên Gecko, công cụ được Firefox sử dụng), vì vậy tôi khuyên bạn nên đọc nó.

Nhưng tôi nghĩ tôi nên giải quyết những gì có vẻ là một mối quan tâm trong câu hỏi của bạn:

Là công cụ chọn chỉ đơn giản là sẽ tìm thấy tất cả các phần tử với một lớp tên, và sau đó phải xác định được trong số đó là div s?

Cũng như Patrick McElhaney's comment:

Câu hỏi liên quan giải thích tại sao selectors được đọc từ phải sang trái nói chung, vì vậy #foo ul.round.fancy li.current được đọc li.current, ul.round.fancy, #foo, nhưng nó thực sự đọc từ phải sang trái trong mỗi phần tử (.current, li, .fancy, .round, ul, #foo)? Nó phải được?

Tôi chưa bao giờ triển khai CSS, cũng như không thấy các trình duyệt khác triển khai nó như thế nào. Chúng tôi biết từ những câu trả lời liên kết ở trên mà trình duyệt sử dụng từ phải sang trái phù hợp để đi bộ trên combinators trong bộ chọn, chẳng hạn như > combinators trong ví dụ này:

section > div.second > div.third 

Nếu một phần tử không phải là một div.third, sau đó không có điểm kiểm tra nếu cha mẹ của nó là div.second có cha mẹ là section.

Tuy nhiên, tôi không tin rằng lệnh từ phải sang trái này sẽ đi xuống đến mức chọn đơn giản. Nói cách khác, tôi không tin rằng các trình duyệt sử dụng đánh giá từ phải sang trái cho từng phần của chuỗi chọn đơn giản (còn được gọi là bộ chọn hợp chất) trong đánh giá từ phải sang trái qua một loạt của bộ chọn hợp chất được phân cách bởi các combinators.

Ví dụ, hãy xem xét giả tạo và rất phóng đại selector này:

div.name[data-foo="bar"]:nth-child(5):hover::after 

Bây giờ, không có đảm bảo trình duyệt sẽ thiết kiểm tra các điều kiện cho một yếu tố theo thứ tự sau:

  1. Con trỏ trên phần tử này?
  2. Yếu tố này có phải là con thứ 5 của cha mẹ không?
  3. Phần tử này có thuộc tính data-foo với giá trị bar không?
  4. Phần tử này có lớp name không?
  5. Đây có phải là yếu tố div không?

Cũng sẽ chọn này, đó là chức năng giống hệt đến trên ngoại trừ với selectors đơn giản của nó lộn xộn xung quanh, thiết được đánh giá theo thứ tự sau:

div:hover[data-foo="bar"].name:nth-child(5)::after 
  1. là yếu tố này đứa con thứ 5 của cha mẹ?
  2. Phần tử này có lớp name không?
  3. Phần tử này có thuộc tính data-foo với giá trị bar không?
  4. Con trỏ trên phần tử này?
  5. Đây có phải là yếu tố div không?

Chỉ đơn giản là không có lý do gì để một lệnh như vậy sẽ được thực thi vì lý do hiệu suất. Trong thực tế, tôi nghĩ rằng hiệu suất sẽ được tăng cường bằng cách chọn một số loại bộ chọn đơn giản đầu tiên, bất kể chúng ở đâu trong chuỗi. (Bạn cũng sẽ nhận thấy rằng ::after không được tính - đó là vì các phần tử giả không phải là các công cụ chọn đơn giản và thậm chí không bao giờ nhập vào phương trình phù hợp.)

Ví dụ, rất nổi tiếng là bộ chọn ID là nhanh nhất. Vâng, Boris nói điều này trong đoạn cuối cùng của câu trả lời cho câu hỏi được liên kết:

Cũng lưu ý rằng có các trình tối ưu hóa khác đã làm để tránh thậm chí cố gắng khớp các quy tắc chắc chắn không khớp. Ví dụ: nếu bộ chọn ngoài cùng bên phải có id và id đó không khớp với id của phần tử thì sẽ không có nỗ lực nào khớp với bộ chọn đó so với phần tử đó trong Gecko: tập hợp "bộ chọn có ID" đã được thử xuất phát từ tra cứu có thể bắt đầu trên ID của phần tử. Vì vậy, đây là 70% các quy tắc có cơ hội khá tốt để khớp với số vẫn còn không khớp sau khi chỉ xem xét thẻ/lớp/id của bộ chọn ngoài cùng bên phải.

Nói cách khác, cho dù bạn có một selector đó trông như thế này:

div#foo.bar:first-child 

Hoặc này:

div.bar:first-child#foo 

Gecko sẽ luôn kiểm tra ID và lớp đầu tiên, bất kể vị trí của nó trong chuỗi. Nếu phần tử không có ID và lớp khớp với bộ chọn thì nó sẽ bị loại bỏ ngay lập tức. Khá darn nhanh chóng nếu bạn hỏi tôi.

Đó chỉ là Gecko làm ví dụ. Điều này có thể khác nhau giữa các lần triển khai (ví dụ: Gecko và WebKit có thể làm điều đó khác với Trident hoặc thậm chí Presto). Có những chiến lược và cách tiếp cận chung được các nhà cung cấp nhất trí, tất nhiên (không có khả năng là một sự khác biệt trong việc kiểm tra ID trước), nhưng các chi tiết nhỏ có thể khác nhau.

6

Công cụ chọn không tìm kiếm phần tử để áp dụng quy tắc, nó sẽ tìm các quy tắc áp dụng cho một phần tử cụ thể. Vì vậy nó có ý nghĩa để đọc các bộ chọn từ phải sang trái.

Một bộ chọn như thế này:

div span.text a.demo 

sẽ làm cho động cơ chọn làm những kiểm tra xem nếu chọn áp dụng cho một phần tử:

  • Có một yếu tố a với lớp demo?
  • Tổ chức có tổ tiên là một phần tử span với lớp text không?
  • Phần tử đó có tổ tiên là phần tử div không?
+1

+1 mặc dù nó không thực sự giải quyết cho dù thứ tự từ phải sang trái được thực hiện trên mức chọn đơn giản/hợp chất. – BoltClock

+0

@ BoltClock'saUnicorn: Kết luận sẽ là không quan trọng.Vì động cơ chỉ xem xét một phần tử tại một thời điểm, nên không có sự khác biệt về hiệu suất có liên quan giữa việc kiểm tra loại phần tử hoặc thuộc tính phần tử. – Guffa

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