config.assets.compile = true trong sản xuất Rails, tại sao không?


184

Ứng dụng Rails mặc định được cài đặt rails newconfig.assets.compile = falsetrong sản xuất.

Và cách thông thường để làm mọi thứ là chạy rake assets:precompiletrước khi triển khai ứng dụng của bạn, để đảm bảo tất cả các tài sản đường ống tài sản được biên dịch.

Vì vậy, những gì xảy ra nếu tôi thiết lập config.assets.compile = truetrong sản xuất?

Tôi sẽ không cần phải chạy precompilenữa. Những gì tôi tin sẽ xảy ra là lần đầu tiên một tài sản được yêu cầu, nó sẽ được biên soạn. Đây sẽ là một hit hiệu suất lần đầu tiên (và nó có nghĩa là bạn thường cần một thời gian chạy js trong sản xuất để làm điều đó). Nhưng khác với những nhược điểm này, sau khi tài sản được biên dịch một cách lười biếng, tôi nghĩ rằng tất cả các lần truy cập tiếp theo vào tài sản đó sẽ không có hiệu suất, hiệu suất của ứng dụng sẽ giống hệt như với các tài sản được biên dịch trước sau lần biên dịch lười biếng đầu tiên này. điều này có đúng không

Có thiếu điều gì không? Bất kỳ lý do khác không để thiết lập config.assets.compile = truetrong sản xuất? Nếu tôi có thời gian chạy JS trong sản xuất và sẵn sàng đánh đổi hiệu suất bị suy giảm để có quyền truy cập đầu tiên của một tài sản, đổi lại việc không phải chạy precompile, điều này có hợp lý không?


1
Cảnh báo, các phiên bản cũ hơn của sprockets có lỗi và nếu config.assets.compile được cấu hình thành true thì có nguy cơ bị lỗ hổng trasversal thư mục ( blog.heroku.com/rails-asset-pipeline-vulnerability )
Mauro

Đây chính xác là cách Stackoverflow được cho là hoạt động. Một câu hỏi được viết tốt và một câu trả lời bằng văn bản. Tôi yêu bạn cả op và @ richard-hulse.
schmijos

Câu trả lời:


258

Tôi đã viết một chút của hướng dẫn.

Bạn chắc chắn không muốn sống biên dịch trong sản xuất.

Khi bạn đã biên dịch, đây là những gì xảy ra:

Mọi yêu cầu cho một tệp trong / tài sản được chuyển đến Sprockets. Ngày đầu yêu cầu cho mỗi và mọi tài sản, nó được biên dịch và lưu vào bộ đệm trong bất cứ thứ gì Rails đang sử dụng cho bộ đệm (thường là hệ thống tệp).

Trong các yêu cầu tiếp theo, Sprockets nhận được yêu cầu và phải tra cứu tên tệp được in dấu vân tay, kiểm tra xem tệp (hình ảnh) hoặc tệp (css và js) tạo nên tài sản không bị sửa đổi, và sau đó nếu có phiên bản được lưu trong bộ nhớ cache.

Đó là tất cả mọi thứ trong thư mục tài sản trong bất kỳ thư mục nhà cung cấp / tài sản nào được sử dụng bởi các plugin.

Đó là rất nhiều chi phí vì, thành thật mà nói, mã không được tối ưu hóa cho tốc độ.

Điều này sẽ có tác động đến việc tài sản nhanh chóng chuyển qua dây cho khách hàng và sẽ tác động tiêu cực đến thời gian tải trang của trang web của bạn.

So sánh với mặc định:

Khi tài sản được biên dịch trước và biên dịch tắt, tài sản được biên dịch và lấy dấu vân tay đến public/assets. Sprockets trả về một bảng ánh xạ của tên tệp đơn giản thành dấu vân tay cho Rails và Rails ghi điều này vào hệ thống tập tin. Tệp kê khai (YML trong Rails 3 hoặc JSON có tên ngẫu nhiên trong Rails 4) được tải vào Bộ nhớ bởi Rails khi khởi động và được lưu trong bộ nhớ cache để sử dụng bởi các phương thức của trình trợ giúp tài sản.

Điều này làm cho việc tạo các trang có tài sản được lấy dấu vân tay chính xác rất nhanh và việc phục vụ các tệp chính là hệ thống máy chủ web từ hệ thống tệp nhanh. Cả hai nhanh hơn đáng kể so với biên dịch trực tiếp.

Để có được lợi thế tối đa của đường ống và dấu vân tay, bạn cần đặt các tiêu đề trong tương lai xa trên máy chủ web của mình và bật tính năng nén gzip cho các tệp js và css. Sprockets viết các phiên bản được nén của tài sản mà bạn có thể đặt máy chủ của mình sử dụng, loại bỏ sự cần thiết phải làm như vậy cho mỗi yêu cầu.

Điều này đưa tài sản ra cho khách hàng càng nhanh càng tốt và ở kích thước nhỏ nhất có thể, tăng tốc độ hiển thị trang phía khách hàng và giảm các yêu cầu (với tiêu đề trong tương lai xa).

Vì vậy, nếu bạn đang biên dịch trực tiếp thì đó là:

  1. Rất chậm
  2. Thiếu nén
  3. Sẽ tác động đến thời gian kết xuất của trang

Đấu với

  1. Nhanh nhất có thể
  2. Nén
  3. Loại bỏ tình trạng nén quá mức từ máy chủ (tùy chọn).
  4. Giảm thiểu thời gian kết xuất của các trang.

Chỉnh sửa: (Trả lời để theo dõi bình luận)

Đường ống có thể được thay đổi thành tiền biên dịch theo yêu cầu đầu tiên nhưng có một số rào cản lớn để thực hiện. Đầu tiên là phải có một bảng tra cứu tên dấu vân tay hoặc các phương thức trợ giúp quá chậm. Theo một senario biên dịch theo yêu cầu, sẽ cần có một số cách để thêm vào bảng tra cứu vì mỗi tài sản mới được biên dịch hoặc yêu cầu.

Ngoài ra, ai đó sẽ phải trả giá giao tài sản chậm trong một khoảng thời gian không xác định cho đến khi tất cả các tài sản được biên soạn và tại chỗ.

Mặc định, trong đó giá biên dịch mọi thứ được thanh toán ngoại tuyến cùng một lúc, không ảnh hưởng đến khách truy cập công cộng và đảm bảo mọi thứ hoạt động trước khi mọi thứ đi vào hoạt động.

Công cụ thỏa thuận là nó bổ sung rất nhiều sự phức tạp cho các hệ thống sản xuất.

[Chỉnh sửa, tháng 6 năm 2015] Nếu bạn đang đọc điều này bởi vì bạn đang tìm kiếm một giải pháp cho thời gian biên dịch chậm trong quá trình triển khai, thì bạn có thể xem xét việc biên dịch trước các tài sản cục bộ. Thông tin về điều này là trong hướng dẫn đường ống tài sản . Điều này cho phép bạn biên dịch trước cục bộ chỉ khi có thay đổi, cam kết điều đó và sau đó triển khai nhanh mà không có giai đoạn tiền biên dịch.


1
Cảm ơn bạn, tôi đã chấp nhận câu trả lời của bạn. Nhưng bây giờ câu hỏi của tôi là, được rồi, nó không làm điều đó ngay bây giờ, nhưng bạn có thể hình dung rằng Đường ống tài sản có thể có một tính năng mà nó lười biếng biên dịch theo yêu cầu đầu tiên, thực hiện chính xác như tiền biên dịch, bao gồm viết cho ./public và cập nhật Dấu hiệu dấu vân tay?
jrochkind

Xem ở trên. Đây có phải là một vấn đề vì Capistrano không làm việc cho bạn?
Richard Hulse

Tôi không sử dụng Capistrano. Tôi không cần trước đây, sự phức tạp thêm vào không đáng có. Có lẽ đường ống tài sản là rơm làm vỡ lạc đà và đòi hỏi nó. Theo bạn, không thể quản lý Rails triển khai với đường ống tài sản mà không có capistrano hay tương tự? Thật là xấu hổ, đối với các thiết lập đơn giản, nó không phải là một vấn đề lớn để làm điều đó bằng tay.
jrochkind

Bạn thực sự cần Capistrano cho Rails 3.1. Các tài sản được biên dịch trong một thư mục công cộng mới trong khi ứng dụng cũ của bạn vẫn đang chạy. Khi quá trình biên dịch xong, phiên bản mới sẽ được liên kết và máy chủ tự động khởi động lại.
Richard Hulse

"Để có được lợi thế tối đa của đường ống và dấu vân tay, bạn cần đặt các tiêu đề tương lai xa trên máy chủ web của mình và bật nén gzip cho các tệp js và css." - Bạn có thể vui lòng cung cấp một số hướng dẫn hoặc liên kết để biết cách thực hiện điều này?
Isaac Betesh

7

Để có ít chi phí hơn với điều biên dịch trước.

Precompile everything initially with these settings in production.rb
# Precompile *all* assets, except those that start with underscore
config.assets.precompile << /(^[^_\/]|\/[^_])[^\/]*$/

sau đó, bạn có thể chỉ cần sử dụng hình ảnh và bảng định kiểu như "/assets/stylesheet.css" trong * .html.erb hoặc "/assets/web.png"


6

Đối với bất cứ ai sử dụng Heroku:

Nếu bạn triển khai đến Herkou, nó sẽ tự động biên dịch trước cho bạn trong quá trình triển khai nếu không bao gồm tài sản đã biên dịch (nghĩa là public/assetskhông cam kết) nên không cần config.assets.compile = truehoặc cam kết tài sản được biên dịch trước.

Tài liệu của Heroku đang ở đây . Một CDN được khuyến khích để loại bỏ tải trên các tài nguyên Dyno.


1

Nó sẽ không giống như tiền biên dịch, ngay cả sau lần truy cập đầu tiên đó: vì các tệp không được ghi vào hệ thống tệp mà chúng không thể được phục vụ trực tiếp bởi máy chủ web. Một số mã ruby ​​sẽ luôn được tham gia, ngay cả khi nó chỉ đọc một mục lưu trữ.


Hmm, tôi nghĩ rằng với precompile=true, các tài sản được biên dịch sẽ được ghi vào hệ thống tập tin. Bạn có chắc không? Hãy để tôi kiểm tra ...
jrochkind

1
Bah, tôi nghĩ bạn đã đúng - chúng được ghi vào hệ thống tệp, nhưng có vẻ như ở đó tmp/cachechứ public/assetskhông phải là nơi mà máy chủ web có thể nhìn thấy, chúng vẫn sẽ được phục vụ bởi ứng dụng rails máy chủ web. blah đúng không, bạn nghĩ sao?
jrochkind

Chính xác. Sẽ không nhanh như việc máy chủ web chọn chúng ngay. Có thể không quan trọng nếu bạn đặt một cdn như đám mây trước ứng dụng của bạn
Frederick Cheung

1

Bộ config.asset.compile = false

Thêm vào Gemfile của bạn

group :assets do gem 'turbo-sprockets-rails3' end

Cài đặt gói

Chạy rake assets:precompile

Sau đó, khởi động máy chủ của bạn


Theo như tôi đã thiết lập config.asset.compile = true in production.rbtập tin, bởi vì không có cơ chế biên dịch trước được thêm vào. Do đó, mỗi khi chúng tôi khởi động máy chủ, sẽ mất quá nhiều thời gian để tải trang (Khi yêu cầu nhấn cả xử lý yêu cầu và biên dịch tài sản). Bây giờ tôi đã đưa turbo-sprockets-rails3vào Gemfile và chạy lệnh rake assets:precompilenó biên dịch các tài sản trước đó. Bây giờ tôi đặt config.asset.compile = false in production.rbvà khởi động máy chủ, tải trang mà không có bất kỳ sự chậm trễ nào. (Chỉ xử lý yêu cầu mà không cần biên dịch tài sản)
Mohammed Saleem

2
đáng nói turbo-sprockets-rails3là chỉ cần thiết trên Ruby 3
Andre Figueiredo

0

Từ hướng dẫn chính thức :

Trong yêu cầu đầu tiên, các tài sản được biên dịch và lưu vào bộ đệm như được nêu trong quá trình phát triển ở trên và các tên tệp kê khai được sử dụng trong các trợ giúp được thay đổi để bao gồm hàm băm MD5.

Sprockets cũng đặt tiêu đề HTTP Control-Control thành max-age = 31536000. Điều này báo hiệu tất cả các bộ đệm giữa máy chủ của bạn và trình duyệt máy khách rằng nội dung này (tệp được cung cấp) có thể được lưu trong bộ nhớ cache trong 1 năm. Tác dụng của việc này là giảm số lượng yêu cầu cho tài sản này từ máy chủ của bạn; tài sản có cơ hội tốt trong bộ đệm của trình duyệt cục bộ hoặc một số bộ đệm trung gian.

Chế độ này sử dụng nhiều bộ nhớ hơn, hoạt động kém hơn so với mặc định và không được khuyến nghị.

Ngoài ra, bước tiền biên dịch hoàn toàn không gặp rắc rối nếu bạn sử dụng Capistrano cho các triển khai của mình. Nó chăm sóc nó cho bạn. Bạn chỉ cần chạy

cap deploy

hoặc (tùy thuộc vào thiết lập của bạn)

cap production deploy

và bạn đã sẵn sàng. Nếu bạn vẫn không sử dụng nó, tôi khuyên bạn nên kiểm tra nó.


Vì vậy, bạn có nghĩ rằng ngôn ngữ từ hướng dẫn chính thức đồng ý với tôi? Tôi đã xem hướng dẫn đó, tôi không chắc lắm nếu nó có nghĩa là những gì tôi đề xuất ở trên, bạn nghĩ gì? Đó là câu hỏi của tôi.
jrochkind

Vâng, bạn nói về cơ bản điều tương tự. Tôi đề nghị bạn không nên bật trình biên dịch trực tiếp.
Sergio Tulentsev

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.