Khi nào nên ưu tiên ng-if so với ng-show / ng-hide?


516

Tôi hiểu điều đó ng-showng-hideảnh hưởng đến lớp được đặt trên một phần tử và ng-ifđiều khiển xem một phần tử có được hiển thị như một phần của DOM hay không.

Có hướng dẫn về việc chọn ng-ifhơn ng-show/ ng-hidehoặc ngược lại không?



1
Không liên quan đến ngôn ngữ phi tiêu .
naXa

Câu trả lời:


703

Phụ thuộc vào trường hợp sử dụng của bạn nhưng để tóm tắt sự khác biệt:

  1. ng-ifsẽ xóa các phần tử khỏi DOM. Điều này có nghĩa là tất cả các trình xử lý của bạn hoặc bất kỳ thứ gì khác được gắn vào các phần tử đó sẽ bị mất. Ví dụ: nếu bạn ràng buộc trình xử lý nhấp chuột với một trong các phần tử con, khi ng-ifđánh giá thành false, phần tử đó sẽ bị xóa khỏi DOM và trình xử lý nhấp chuột của bạn sẽ không hoạt động nữa, ngay cả sau khi ng-ifđánh giá thành đúng và hiển thị phần tử. Bạn sẽ cần gắn lại trình xử lý.
  2. ng-show/ng-hidekhông loại bỏ các thành phần khỏi DOM. Nó sử dụng các kiểu CSS để ẩn / hiển thị các thành phần (lưu ý: bạn có thể cần thêm các lớp của riêng mình). Bằng cách này, xử lý của bạn đã được gắn liền với trẻ em sẽ không bị mất.
  3. ng-iftạo một phạm vi con trong khi ng-show/ng-hidekhông

Các yếu tố không có trong DOM có tác động hiệu suất ít hơn và ứng dụng web của bạn có thể xuất hiện nhanh hơn khi sử dụng ng-ifso với ng-show/ng-hide. Theo kinh nghiệm của tôi, sự khác biệt là không đáng kể. Ảnh động có thể khi sử dụng cả hai ng-show/ng-hideng-if, với các ví dụ cho cả hai trong tài liệu Angular.

Cuối cùng, câu hỏi bạn cần trả lời là liệu bạn có thể xóa phần tử khỏi DOM hay không?


19
Bạn có thể sử dụng hoạt hình CSS3 với ng-if. Kiểm tra đoạn Ảnh động và ví dụ trong tài liệu . Ngoài ra với ng-hide/ng-showcác bộ chọn css như :first-childhoặc :nth-childkhông hoạt động chính xác vì các yếu tố ẩn cũng sẽ được tính.
Łukasz Wojciechowski

4
Dịch vụ hoạt hình trong angular.dart tương đối mới. Tại thời điểm viết bài này, nó không có sẵn.
markovuksanovic

44
Điểm đầu tiên của bạn là không thành vấn đề nếu bạn đang sử dụng các lệnh (như ng-click) để ràng buộc các trình xử lý, như bạn nên làm.
Kevin C.

9
Ngoài ra, ng-iftạo một phạm vi mới trong khi ng-showkhông.
martin

8
Cũng cần đề cập rằng việc thêm và xóa các thành phần khỏi DOM có thể phải chịu chi phí hiệu năng cao nếu được thực hiện thường xuyên.
Kevin C.

130

Xem ở đây để biết CodePen thể hiện sự khác biệt trong cách hoạt động của ng-if / ng-show, DOM-khôn ngoan.

@markovuksanovic đã trả lời tốt câu hỏi. Nhưng tôi sẽ xem xét nó từ một khía cạnh khác: Tôi luôn luôn sử dụng ng-ifvà đưa các yếu tố đó ra khỏi DOM, trừ khi:

  1. vì một số lý do, bạn cần các ràng buộc dữ liệu và $watch-es trên các yếu tố của bạn để duy trì hoạt động trong khi chúng vô hình. Các biểu mẫu có thể là một trường hợp tốt cho điều này, nếu bạn muốn có thể kiểm tra tính hợp lệ trên các đầu vào hiện không hiển thị, để xác định xem toàn bộ biểu mẫu có hợp lệ hay không.
  2. Bạn đang sử dụng một số logic trạng thái thực sự phức tạp với các trình xử lý sự kiện có điều kiện, như đã đề cập ở trên. Điều đó nói rằng , nếu bạn thấy mình đính kèm và tách các trình xử lý theo cách thủ công, như vậy bạn sẽ mất trạng thái quan trọng khi bạn sử dụng ng-if, hãy tự hỏi liệu trạng thái đó sẽ được biểu diễn tốt hơn trong mô hình dữ liệu hay không và trình xử lý được áp dụng theo điều kiện bất cứ khi nào phần tử được kết xuất. Nói cách khác, sự hiện diện / vắng mặt của người xử lý là một dạng dữ liệu trạng thái. Lấy dữ liệu đó ra khỏi DOM và vào một mô hình. Sự hiện diện / vắng mặt của các trình xử lý nên được xác định bởi dữ liệu và do đó dễ dàng tạo lại.

Angular được viết thực sự tốt. Thật nhanh chóng, xem xét những gì nó làm. Nhưng những gì nó làm là cả một nhóm phép thuật làm cho những thứ cứng (như liên kết dữ liệu 2 chiều) trông dễ dàng một cách tầm thường. Làm cho tất cả những điều đó trông dễ dàng đòi hỏi một số hiệu suất trên đầu. Bạn có thể bị sốc khi nhận ra có bao nhiêu hàng trăm hoặc hàng nghìn lần một hàm setter được đánh giá trong $digestchu kỳ trên một khối DOM mà thậm chí không ai nhìn vào. Và sau đó bạn nhận ra rằng bạn có hàng tá hoặc hàng trăm yếu tố vô hình đều làm điều tương tự ...

Máy tính để bàn thực sự có thể đủ mạnh để hiển thị hầu hết các vấn đề về tốc độ thực thi của JS. Nhưng nếu bạn đang phát triển cho thiết bị di động, sử dụng ng-if bất cứ khi nào có thể thì con người sẽ là một người không có trí tuệ. Tốc độ JS vẫn là vấn đề trên bộ xử lý di động. Sử dụng ng-if là một cách rất dễ dàng để có được tối ưu hóa có ý nghĩa tiềm năng với chi phí rất, rất thấp.


6
Rất tốt đẹp cho câu trả lời trên. Đưa ra với một số bối cảnh tốt, cũng giúp đưa ra quyết định. Cảm ơn.
Sean

1
ng-showcó thể hữu ích khi bạn có, giả sử các tab có nhiều nội dung cần nhiều thời gian để hiển thị. Sau kết xuất đầu tiên, việc di chuyển giữa các tab sẽ diễn ra tức thì, trong khi đó ng-ifsẽ yêu cầu kết xuất lại, các sự kiện ràng buộc, v.v ... Nhược điểm như bạn nói, là tạo ra các đồng hồ thực thi trong nền. Góc rất cầnng-ifshowwatch
poshest

53

Từ kinh nghiệm của tôi:

1) Nếu trang của bạn có một chuyển đổi sử dụng ng-if / ng-show để hiển thị / ẩn thứ gì đó, ng-if gây ra nhiều sự chậm trễ của trình duyệt (chậm hơn). Ví dụ: nếu bạn có một nút được sử dụng để chuyển đổi giữa hai chế độ xem, ng-show dường như nhanh hơn.

2) ng-if sẽ tạo / hủy phạm vi khi đánh giá là đúng / sai. Nếu bạn có một bộ điều khiển gắn liền với ng-if, mã bộ điều khiển đó sẽ được thực thi mỗi khi ng-if ước tính là true. Nếu bạn đang sử dụng ng-show, mã điều khiển chỉ được thực thi một lần. Vì vậy, nếu bạn có một nút chuyển đổi giữa nhiều chế độ xem, sử dụng ng-if và ng-show sẽ tạo ra sự khác biệt lớn trong cách bạn viết mã điều khiển.


5
Đó là một sự thật lớn! ng-if không nhất thiết làm cho frontend của bạn nhanh hơn. Nó phụ thuộc vào nhu cầu của bạn. Trên thực tế, nó có thể làm cho cách khác xung quanh nếu bạn đang sử dụng trong tình huống sai.
Thiago C. S Ventura

1
Nhưng theo tôi là ng-if không hiển thị trên DOM nên nó nhanh so với ng-show / hide. Có phải tôi sai xin vui lòng cho tôi sửa tại điểm đó.
Pardeep Jain

1
ng-if sẽ nhanh hơn nếu nó đánh giá là sai, vì như bạn nói, không có gì cần phải chèn vào DOM. Nhưng, nếu đó là sự thật thì bạn có chi phí chèn phần tử - có thể khá phức tạp - vào DOM.
Mawg nói rằng phục hồi Monica

"2) ng-if sẽ tạo / hủy phạm vi khi đánh giá là đúng / sai. Nếu bạn có bộ điều khiển gắn liền với ng-if, mã bộ điều khiển đó sẽ được thực thi mỗi khi"
Red Pea

35

Câu trả lời là không đơn giản:

Nó phụ thuộc vào các máy mục tiêu (di động so với máy tính để bàn), nó phụ thuộc vào bản chất dữ liệu của bạn, trình duyệt, HĐH, phần cứng mà nó chạy trên ... bạn sẽ cần phải điểm chuẩn nếu bạn thực sự muốn biết.

Đây chủ yếu là vấn đề về bộ nhớ và tính toán ... vì với hầu hết các vấn đề về hiệu năng, sự khác biệt có thể trở nên quan trọng với các yếu tố lặp lại (n) như danh sách, đặc biệt là khi lồng nhau (nxn hoặc tệ hơn) và loại tính toán nào bạn chạy bên trong các yếu tố này :

  • ng-show : Nếu những yếu tố tùy chọn đó thường xuất hiện (dày đặc), như nói 90% thời gian, có thể nhanh hơn để chúng sẵn sàng và chỉ hiển thị / ẩn chúng, đặc biệt nếu nội dung của chúng rẻ (chỉ là văn bản đơn giản, không có gì để tính toán hoặc tải). Điều này tiêu tốn bộ nhớ vì nó lấp đầy DOM với các yếu tố ẩn, nhưng chỉ hiển thị / ẩn thứ gì đó đã tồn tại có khả năng là một hoạt động rẻ tiền cho trình duyệt.

  • ng-if : Nếu các yếu tố trái ngược có khả năng không được hiển thị (thưa thớt) chỉ cần xây dựng chúng và phá hủy chúng trong thời gian thực, đặc biệt là nếu nội dung của chúng tốn kém để có được (tính toán / sắp xếp / lọc, hình ảnh, hình ảnh được tạo). Điều này lý tưởng cho các yếu tố hiếm hoặc 'theo yêu cầu', nó tiết kiệm bộ nhớ trong điều kiện không lấp đầy DOM nhưng có thể tốn rất nhiều tính toán (tạo / hủy phần tử) và băng thông (lấy nội dung từ xa). Nó cũng phụ thuộc vào mức độ bạn tính toán trong chế độ xem (lọc / sắp xếp) so với những gì bạn đã có trong mô hình (dữ liệu được sắp xếp trước / được lọc trước).


2
Câu trả lời khác cho sự thật kỹ thuật. Cái này cho trí tuệ. Bạn đã xây dựng rõ ràng các ứng dụng Angular không tầm thường thưa ông! +1
tốt nhất

Vấn đề này vượt ra ngoài góc cạnh, nó là một vấn đề cơ bản trong khoa học máy tính, có một điểm mà trên một phương pháp này hiệu quả hơn phương pháp kia. Thông thường điều này có thể được tìm thấy thông qua một số điểm chuẩn. Vì vậy, bạn thậm chí có thể chuyển đổi giữa một phương thức và phương pháp khác tùy thuộc vào số lượng vật phẩm ... Chủ đề tương tự: math.stackexchange.com/questions/1632739/ Kẻ
Roussy

12

Một lưu ý quan trọng:

ng If (không giống ngShow) thường tạo ra phạm vi con có thể tạo ra kết quả không mong muốn.

Tôi có một vấn đề liên quan đến vấn đề này và tôi đã dành nhiều thời gian để tìm hiểu chuyện gì đang xảy ra.

(Chỉ thị của tôi đã viết các giá trị mô hình của nó vào phạm vi sai.)

Vì vậy, để cứu tóc bạn chỉ cần sử dụng ngShow trừ khi bạn chạy quá chậm.

Sự khác biệt về hiệu suất hầu như không đáng chú ý và tôi không chắc chắn về sự ưu ái của ai mà không cần thử nghiệm ...


8
Sử dụng $parent.scopevartrong các ràng buộc dữ liệu trong một ngNếu sẽ khắc phục những thứ như các vấn đề phạm vi con khi sử dụng ng If
meconroy

2
Điều này không hoàn toàn đúng (nhận xét ban đầu của @ user2173353). Nếu bạn tuân thủ các thực hành tốt, bạn sẽ không gặp rắc rối. Đó là một quy tắc khá cơ bản: "nếu không có dấu chấm, bạn đang làm sai". Xem ở đây để xem bản demo về cách thức hoạt động của nó: bit.ly/1SPv4wL . Một tài liệu tham khảo tuyệt vời khác (xem lỗi # 2): bit.ly/1QfFeWd > (Chỉ thị của tôi đã viết các giá trị mô hình của nó vào phạm vi sai.) Đây là kết quả của việc không tuân thủ thực tiễn trên.
piotr.d

1
@ piotr.d Bạn nói đúng, nhưng đó không phải là điều mà người mới bắt đầu có thể cần tập trung vào và có một cách thực hành tốt nhất khác nói rằng tốt hơn hết là để cải thiện hiệu suất cho đến cuối (đặc biệt là cải tiến hiệu suất có thể không phải là cải tiến trong thực tế ). Tôi đã thấy mọi người đặt ngIfkhắp nơi tin rằng điều này sẽ cải thiện hiệu suất. Điều này chỉ đơn giản là không đúng sự thật và người ta không thể nói cái nào là tốt nhất, ngIfhoặc ngShow, không có bài kiểm tra hoặc phân tích sâu trong trường hợp cụ thể. Vì vậy, tôi vẫn khuyên bạn nên quên đi ngIf, cho đến khi một người thấy hiệu suất kém hoặc biết anh ta đang làm gì
user2173353

2
Điểm tốt. Nhưng việc sử dụng bộ điều khiểnAs làm cho điều này không thành vấn đề. Xem, ví dụ, John Papa đảm nhận bộ điều khiểnAs và vm .
jsruok

4

ng-if trên ng-gộp và trên ng-điều khiển sẽ có tác động lớn đến ng-bao gồm nó sẽ không tải một phần yêu cầu và không xử lý trừ khi cờ là đúng trên ng-điều khiển, nó sẽ không tải bộ điều khiển trừ khi cờ là đúng nhưng vấn đề là khi một cờ bị sai trong ng-nếu nó sẽ xóa khỏi DOM khi cờ trở lại đúng thì nó sẽ tải lại DOM trong trường hợp này ng-show là tốt hơn, trong một lần hiển thị ng-if là tốt hơn


4

Nếu bạn dùng ng-show or ng-hide nội dung (ví dụ: hình thu nhỏ từ máy chủ) sẽ được tải bất kể giá trị của biểu thức nhưng sẽ được hiển thị dựa trên giá trị của biểu thức.

Nếu bạn sử dụng ng-ifnội dung sẽ chỉ được tải nếu biểu thức của ng-if ước tính là trung thực.

Sử dụng ng-if là một ý tưởng tốt trong tình huống bạn sẽ tải dữ liệu hoặc hình ảnh từ máy chủ và chỉ hiển thị những thông tin đó tùy thuộc vào sự tương tác của người dùng. Bằng cách này, tải trang của bạn sẽ không bị chặn bởi các tác vụ chuyên sâu không cần thiết.


Điều này đặc biệt hữu ích vì hầu hết các trình duyệt sẽ tải hình ảnh ngay cả khi CSS ẩn các thùng chứa DOM của chúng. Họ thường chỉ tìm kiếm srcthuộc tính của imgthẻ, khi hiện tại nó được tải!
Barshe Roussy
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.