Khi nào tôi nên sử dụng Inline so với Javascript bên ngoài?


129

Tôi muốn biết khi nào tôi nên bao gồm các tập lệnh bên ngoài hoặc viết chúng nội tuyến với mã html, về hiệu suất và dễ bảo trì.

Thực tiễn chung cho việc này là gì?

Kịch bản trong thế giới thực - Tôi có một số trang html cần xác thực mẫu phía máy khách. Đối với điều này, tôi sử dụng một plugin jQuery mà tôi bao gồm trên tất cả các trang này. Nhưng câu hỏi là, tôi có:

  • Viết các bit của mã cấu hình tập lệnh này nội tuyến?
  • bao gồm tất cả các bit trong một tệp được chia sẻ giữa tất cả các trang html này?
  • bao gồm mỗi bit trong một tệp bên ngoài riêng biệt, một cho mỗi trang html?

Cảm ơn.

Câu trả lời:


114

Tại thời điểm câu trả lời này ban đầu được đăng (2008), quy tắc rất đơn giản: Tất cả các tập lệnh nên ở bên ngoài. Cả hai để bảo trì và hiệu suất.

(Tại sao hiệu suất? Bởi vì nếu mã riêng biệt, trình duyệt có thể được lưu trữ dễ dàng hơn.)

JavaScript không thuộc về mã HTML và nếu nó chứa các ký tự đặc biệt (chẳng hạn như ) <, >nó thậm chí sẽ tạo ra các vấn đề.

Ngày nay, khả năng mở rộng web đã thay đổi. Việc giảm số lượng yêu cầu đã trở thành một sự cân nhắc hợp lệ do độ trễ của việc thực hiện nhiều yêu cầu HTTP. Điều này làm cho câu trả lời phức tạp hơn: trong hầu hết các trường hợp, vẫn nên sử dụng JavaScript bên ngoài . Nhưng đối với một số trường hợp nhất định, đặc biệt là các đoạn mã rất nhỏ, việc đưa chúng vào HTML của trang web có ý nghĩa.


6
@Nick: hầu hết các vấn đề có thể được khắc phục. Tốt hơn là không tạo ra chúng ở nơi đầu tiên, mặc dù.
Konrad Rudolph

17
Đôi khi bạn có được hiệu suất tốt hơn khi nội tuyến. Nhìn vào nguồn google.com . Họ biết những gì họ đang làm.
callum

13
@callum Google có trường hợp sử dụng khác với 99.999999% trang web. Tất nhiên họ đo lường cực kỳ cẩn thận và ngay cả những vấn đề khác biệt nhỏ nhất. Nhưng chỉ vì họ thấy rằng trong trường hợp sử dụng cụ thể của mình, nội tuyến hoạt động tốt hơn (có lẽ vì tập lệnh thay đổi rất thường xuyên?) Không có nghĩa là chúng ta có thể rút ra một quy tắc chung từ đó, hoặc thậm chí là chúng ta nên coi nhẹ quy tắc thông thường. quy tắc (để kịch bản bên ngoài).
Konrad Rudolph

8
@KonradRudolph - Đồng ý, không nên áp dụng quy tắc chung nào từ phương pháp của Google. Tôi chỉ nói rằng đó là một gợi ý rằng nó có thể đáng để đặt câu hỏi về quy tắc trong câu trả lời của bạn. Dù sao, tôi nghĩ lý do Google làm điều đó là để giảm các yêu cầu HTTP và điều này có thể mang lại lợi ích cho hơn 0,000001% trang web. Băng thông ngày càng cao nhưng thời gian khứ hồi vẫn giữ nguyên. Xóa toàn bộ yêu cầu HTTP nối tiếp đôi khi tốt hơn lợi ích bộ đệm của JS bên ngoài. Tất nhiên phụ thuộc vào kích thước của JS của bạn.
callum

5
@callum Mặc dù điều này là đúng, nhưng quan điểm về bộ nhớ đệm vẫn còn và vẫn quan trọng. Việc giảm số vòng tròn chỉ quan trọng nếu khách truy cập của bạn không quay lại (và sau đó bạn sẽ không nhận đủ số lần truy cập trang để làm cho vấn đề đó) hoặc nếu nội dung của bạn thay đổi thường xuyên đến mức việc lưu các tệp tập lệnh không có lợi.
Konrad Rudolph

31

Khả năng bảo trì chắc chắn là một lý do để giữ chúng bên ngoài, nhưng nếu cấu hình là một lớp lót (hoặc nói chung ngắn hơn chi phí HTTP bạn sẽ nhận được để làm cho các tệp đó ở bên ngoài) thì tốt hơn hết là giữ cho chúng hoạt động. Luôn nhớ rằng, mỗi yêu cầu HTTP tạo ra một số chi phí về thời gian thực hiện và lưu lượng.

Tất nhiên, tất cả điều này trở nên không liên quan vào thời điểm mã của bạn dài hơn một vài dòng và không thực sự cụ thể cho một trang. Thời điểm bạn muốn có thể sử dụng lại mã đó, làm cho nó bên ngoài. Nếu bạn không, hãy nhìn vào kích thước của nó và quyết định sau đó.


5
Đó là một trong những mối quan tâm của tôi. Có một yêu cầu HTTP riêng cho một vài dòng mã có vẻ lãng phí.
Dan Burzo

Có lẽ bạn có thể gửi một cấu hình mẫu cho mã của bạn? IMO nếu dưới 300 ký tự và hoàn toàn cụ thể theo trang, hãy nội tuyến nó.
Horst Gutmann

Đây phải là câu trả lời hàng đầu imo
sgarcia.dev 8/8/2016

@Dan nhớ rằng yêu cầu riêng biệt chỉ xảy ra lần đầu tiên. Nếu bạn mong muốn người dùng của mình tải trang nhiều lần, bộ nhớ cache bên ngoài (thậm chí cho một vài dòng) rõ ràng nhanh hơn việc chờ đợi byte cho vài dòng trên dây khi tải trang n = 2 +.
jinglểula

@HorstGutmann làm thế nào để có viện trợ bên ngoài với khả năng bảo trì? Cá nhân tôi thích js bên ngoài bất cứ khi nào có thể, nhưng có điều gì khách quan giúp duy trì dễ dàng hơn không?
jinglểula

21

Bên ngoài javascript là một trong những quy tắc hiệu suất của yahoo: http://developer.yahoo.com/performance/rules.html#external

Mặc dù quy tắc khó và nhanh mà bạn nên luôn luôn ngoại tác các tập lệnh nói chung sẽ là một lựa chọn tốt, trong một số trường hợp bạn có thể muốn nội tuyến một số tập lệnh và kiểu. Tuy nhiên, bạn chỉ nên những thứ nội tuyến mà bạn biết sẽ cải thiện hiệu suất (vì bạn đã đo lường điều này).


1
Tôi nghĩ rằng Yahoo cũng khuyên bạn nên thêm tất cả Javascript vào một cuộc gọi HTTP - điều này không có nghĩa là tất cả các tập lệnh phải nằm trong cùng một tệp trong quá trình phát triển
Paul Shannon

Ngoài ra, như đã lưu ý ở trên, HTTP / 2 cũng thay đổi cách thực hành "1 cuộc gọi".
jingl salonula

19

Nếu bạn chỉ quan tâm đến hiệu suất, hầu hết các lời khuyên trong chủ đề này đều sai và ngày càng trở nên sai lầm trong kỷ nguyên SPA, nơi chúng ta có thể cho rằng trang này vô dụng nếu không có mã JS. Tôi đã dành vô số giờ để tối ưu hóa thời gian tải trang SPA và xác minh các kết quả này với các trình duyệt khác nhau. Trên bảng, hiệu suất tăng bằng cách sắp xếp lại html của bạn, có thể khá ấn tượng.

Để có được hiệu suất tốt nhất, bạn phải nghĩ về các trang như tên lửa hai giai đoạn. Hai giai đoạn xấp xỉ tương ứng với <head><body>giai đoạn, nhưng suy nghĩ của họ thay vì như <static><dynamic>. Phần tĩnh về cơ bản là một hằng số chuỗi mà bạn đẩy xuống ống phản ứng nhanh nhất có thể. Điều này có thể hơi khó khăn nếu bạn sử dụng nhiều phần mềm trung gian để đặt cookie (những phần này cần được đặt trước khi gửi nội dung http), nhưng về nguyên tắc, nó chỉ cần xóa bộ đệm phản hồi, hy vọng trước khi nhảy vào một số mã tạo khuôn mẫu (dao cạo, php, v.v.) trên máy chủ. Điều này nghe có vẻ khó khăn, nhưng sau đó tôi chỉ giải thích nó sai, bởi vì nó gần tầm thường. Như bạn có thể đoán, phần tĩnh này sẽ chứa tất cả các javascript được gạch chân và rút gọn. Nó sẽ trông giống như

<!DOCTYPE html>
     <html>
         <head>
             <script>/*...inlined jquery, angular, your code*/</script>
             <style>/* ditto css */</style>
         </head>
         <body>
             <!-- inline all your templates, if applicable -->
             <script type='template-mime' id='1'></script>
             <script type='template-mime' id='2'></script>
             <script type='template-mime' id='3'></script>

Vì chi phí của bạn bên cạnh không có gì để gửi phần này xuống dây, bạn có thể mong đợi rằng khách hàng sẽ bắt đầu nhận được phần này ở đâu đó khoảng 5ms + độ trễ sau khi kết nối với máy chủ của bạn. Giả sử máy chủ đóng hợp lý độ trễ này có thể trong khoảng từ 20ms đến 60ms. Các trình duyệt sẽ bắt đầu xử lý phần này ngay khi họ nhận được và thời gian xử lý thường sẽ chi phối thời gian chuyển theo hệ số 20 trở lên, hiện là cửa sổ khấu hao của bạn để xử lý <dynamic>phần phía máy chủ .

Phải mất khoảng 50ms cho trình duyệt (chrome, phần còn lại có thể chậm hơn 20%) để xử lý jquery nội tuyến + signalr + angular + ng animate + ng touch + ng tuyến + lodash. Điều đó khá tuyệt vời trong chính nó. Hầu hết các ứng dụng web có ít mã hơn tất cả các thư viện phổ biến được đặt cùng nhau, nhưng giả sử bạn có nhiều như vậy, vì vậy chúng tôi sẽ giành được độ trễ + 100ms xử lý trên máy khách (chiến thắng độ trễ này đến từ khối chuyển khoản thứ hai). Vào thời điểm đoạn thứ hai đến, chúng tôi đã xử lý tất cả các mã và mẫu js và chúng tôi có thể bắt đầu thực hiện các biến đổi dom.

Bạn có thể phản đối rằng phương thức này trực giao với khái niệm nội tuyến, nhưng không phải vậy. Nếu bạn, thay vì nội tuyến, liên kết đến cdns hoặc máy chủ của riêng bạn, trình duyệt sẽ phải mở (các) kết nối khác và thực hiện trì hoãn. Vì việc thực thi này về cơ bản là miễn phí (vì phía máy chủ đang nói chuyện với cơ sở dữ liệu) nên rõ ràng rằng tất cả các bước nhảy này sẽ có giá cao hơn so với việc không thực hiện bước nhảy nào. Nếu có một sự giải quyết trình duyệt cho biết js bên ngoài thực thi nhanh hơn, chúng ta có thể đo được yếu tố nào chiếm ưu thế. Các phép đo của tôi chỉ ra rằng các yêu cầu bổ sung sẽ giết chết hiệu suất ở giai đoạn này.

Tôi làm việc rất nhiều với việc tối ưu hóa các ứng dụng SPA. Mọi người thường nghĩ rằng khối lượng dữ liệu là một vấn đề lớn, trong khi độ trễ thực tế và việc thực thi thường chiếm ưu thế. Các thư viện rút gọn mà tôi liệt kê thêm tối đa 300kb dữ liệu và đó chỉ là 68 kb được nén, hoặc tải xuống 200ms trên điện thoại 2mbit 3g / 4g, chính xác là độ trễ mà nó sẽ sử dụng trên cùng một điện thoại để kiểm tra NẾU có cùng dữ liệu trong bộ đệm của nó đã có, ngay cả khi nó được lưu trong bộ đệm proxy, vì thuế độ trễ di động (độ trễ từ điện thoại đến tháp) vẫn được áp dụng. Trong khi đó, các kết nối máy tính để bàn có độ trễ bước đầu tiên thấp hơn thường có băng thông cao hơn.

Nói tóm lại, ngay bây giờ (2014), tốt nhất là nội tuyến tất cả các tập lệnh, kiểu và mẫu.

EDIT (tháng 5 năm 2016)

Khi các ứng dụng JS tiếp tục phát triển và một số tải trọng của tôi hiện xếp chồng lên tới hơn 3 megabyte mã được rút gọn, rõ ràng là tại các thư viện rất phổ biến nhất sẽ không còn được nội tuyến nữa.


Tôi đã không nhận được cửa sổ hiện được khấu hao của bạn để xử lý phía máy chủ của phần <động> - Máy chủ xử lý những gì nó cần và chỉ sau đó phục vụ toàn bộ html (phần đầu + thân), xử lý máy chủ khác có cần thiết sau đó không?
Sinh ra ToCode

@BornToCode Ý tưởng là cung cấp cho khách hàng một việc cần làm đồng thời phía máy chủ có việc phải làm. Bởi vì các thư viện máy khách cần được giải thích - tốt hơn là bắt đầu quá trình đó trước khi thực hiện bất kỳ tính toán nào trên máy chủ. Cửa sổ khấu hao là thời gian khách hàng xử lý JS. Bạn nhận được cửa sổ đó miễn phí, nếu bạn bố trí một tên lửa 2 tầng.
Gleno


9

Trên thực tế, có một trường hợp khá chắc chắn để sử dụng javascript nội tuyến. Nếu js đủ nhỏ (một lớp), tôi có xu hướng thích nội tuyến javascript vì hai yếu tố:

  • Địa phương . Không cần điều hướng một tệp bên ngoài để xác thực hành vi của một số javascript
  • AJAX . Nếu bạn đang làm mới một số phần của trang thông qua AJAX, bạn có thể mất tất cả các trình xử lý DOM (onclick, v.v.) cho phần đó, tùy thuộc vào cách bạn liên kết chúng. Ví dụ, bằng cách sử dụng, jQuerybạn có thể sử dụng livehoặc delegatephương thức để phá vỡ điều này, nhưng tôi thấy rằng nếu js đủ nhỏ thì tốt hơn là chỉ nên đặt nội tuyến.

5

Một lý do khác khiến bạn phải luôn sử dụng các tập lệnh bên ngoài là để chuyển đổi dễ dàng hơn sang Chính sách bảo mật nội dung (CSP) . CSP mặc định cấm tất cả các tập lệnh nội tuyến, làm cho trang web của bạn chống lại các cuộc tấn công XSS hơn.


4

Tôi sẽ xem mã yêu cầu và chia nó thành nhiều tệp riêng biệt nếu cần. Mỗi tệp js sẽ chỉ giữ một "tập hợp logic" các chức năng, v.v. một tập tin cho tất cả các chức năng liên quan đến đăng nhập.

Sau đó, trong quá trình phát triển trang web trên mỗi trang html, bạn chỉ bao gồm những trang cần thiết. Khi bạn phát trực tiếp với trang web của mình, bạn có thể tối ưu hóa bằng cách kết hợp mỗi tệp js mà một trang cần thành một tệp.


4

Cách bảo vệ duy nhất tôi có thể cung cấp cho javascipt nội tuyến là khi sử dụng các chế độ xem được gõ mạnh với .net MVC, bạn có thể tham khảo các biến c # mid javascript mà tôi thấy hữu ích.


3

Ba cân nhắc:

  • Bạn cần bao nhiêu mã (đôi khi các thư viện là người tiêu dùng hạng nhất)?
  • Tính cụ thể: mã này chỉ có chức năng trong ngữ cảnh của tài liệu hoặc thành phần cụ thể này?
  • Mỗi mã bên trong tài liệu có xu hướng làm cho nó dài hơn và do đó chậm hơn. Bên cạnh đó, các cân nhắc về SEO làm cho nó trở nên rõ ràng, rằng bạn giảm thiểu kịch bản nội bộ ...

2

Các tập lệnh bên ngoài cũng dễ dàng hơn để gỡ lỗi bằng cách sử dụng Fireorms. Tôi muốn Đơn vị kiểm tra JavaScript của tôi và có tất cả các trợ giúp bên ngoài. Tôi ghét nhìn thấy JavaScript trong mã PHP và HTML, nó trông giống như một mớ hỗn độn lớn đối với tôi.


2

Về quan điểm giữ JavaScript bên ngoài:

ASP.NET 3.5SP1 gần đây đã giới thiệu chức năng để tạo tài nguyên tập lệnh hỗn hợp (hợp nhất một loạt các tệp js thành một). Một lợi ích khác cho điều này là khi nén Webserver được bật, tải xuống một tệp lớn hơn một chút sẽ có tỷ lệ nén tốt hơn sau đó nhiều tệp nhỏ hơn (cũng ít chi phí http, roundtrip, v.v.). Tôi đoán điều này sẽ tiết kiệm cho tải trang ban đầu, sau đó bộ nhớ đệm trình duyệt khởi động như đã đề cập ở trên.

Bỏ qua ASP.NET, screencast này giải thích các lợi ích chi tiết hơn: http://www.asp.net/learn/3.5-SP1/video-296.aspx


2

Một lợi ích tiềm ẩn khác của các tập lệnh bên ngoài là bạn có thể dễ dàng chạy chúng thông qua trình kiểm tra cú pháp như jslint . Điều đó có thể cứu bạn khỏi rất nhiều lỗi đau lòng, khó tìm, IE6.


1

Trong kịch bản của bạn, có vẻ như viết nội dung bên ngoài vào một tệp được chia sẻ giữa các trang sẽ tốt cho bạn. Tôi đồng ý với tất cả những gì đã nói ở trên.


1

Trong quá trình tạo mẫu sớm, giữ cho mã của bạn nội tuyến vì lợi ích của việc lặp nhanh, nhưng hãy chắc chắn làm cho tất cả bên ngoài vào thời điểm bạn đạt được sản xuất.

Tôi thậm chí dám nói rằng nếu bạn không thể đặt tất cả Javascript của mình ra bên ngoài, thì bạn có một thiết kế xấu dưới tay bạn và bạn nên cấu trúc lại dữ liệu và tập lệnh của mình


1

Google đã bao gồm thời gian tải vào các phép đo xếp hạng trang của nó, nếu bạn nội tuyến nhiều, các con nhện sẽ mất nhiều thời gian hơn để thu thập thông tin qua trang của bạn, điều này có thể ảnh hưởng đến thứ hạng trang của bạn nếu bạn phải đưa vào nhiều. trong mọi trường hợp, các chiến lược khác nhau có thể có ảnh hưởng đến thứ hạng của bạn.


1

Tôi nghĩ rằng bạn nên sử dụng nội tuyến khi tạo các trang web đơn vì các tập lệnh sẽ không cần phải chia sẻ trên nhiều trang


-3

Luôn cố gắng sử dụng Js bên ngoài vì js nội tuyến luôn khó bảo trì.

Hơn nữa, bạn cần phải sử dụng một js bên ngoài vì phần lớn các nhà phát triển khuyên bạn nên sử dụng js bên ngoài.

Bản thân tôi sử dụng js bên ngoài.


2
Yêu cầu chuyên môn? Tại sao? Ai nói vậy?
Siyah
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.