config.assets.compile = true ในการผลิต Rails ทำไมต้องเป็นเช่นนั้น?


185

เริ่มต้น Rails ติดตั้งแอปโดยrails newมีconfig.assets.compile = falseในการผลิต

และวิธีการทั่วไปในการทำสิ่งต่าง ๆ คือการเรียกใช้rake assets:precompileก่อนที่จะปรับใช้แอปของคุณเพื่อให้แน่ใจว่ามีการรวบรวมสินทรัพย์ไปป์ไลน์ของสินทรัพย์ทั้งหมด

แล้วจะเกิดอะไรขึ้นถ้าฉันเริ่มconfig.assets.compile = trueผลิต

ฉันจะไม่ต้องวิ่งprecompileอีกต่อไป สิ่งที่ฉันเชื่อว่าจะเกิดขึ้นเป็นครั้งแรกที่มีการร้องขอเนื้อหาจะถูกรวบรวม นี่จะเป็นผลงานที่ยอดเยี่ยมในครั้งแรก (และหมายความว่าโดยทั่วไปคุณต้องใช้ js runtime ในการผลิตเพื่อดำเนินการ) แต่นอกเหนือจากข้อเสียเหล่านี้หลังจากที่รวบรวมเนื้อหาอย่างเกียจคร้านฉันคิดว่าการเข้าถึงเนื้อหานั้นในภายหลังจะไม่มีผลกระทบต่อประสิทธิภาพการทำงานของแอปจะเหมือนกับประสิทธิภาพของสินทรัพย์ก่อนคอมไพล์หลังจากการคอมไพล์ครั้งแรกในครั้งแรก จริงหรือ

มีอะไรฉันหายไปไหม มีเหตุผลอื่นใดที่จะไม่ตั้งconfig.assets.compile = trueในการผลิต? ถ้าฉันใช้งานจริงในการผลิต JS และยินดีที่จะแลกเปลี่ยนประสิทธิภาพที่ลดลงสำหรับการเข้าถึงสินทรัพย์ครั้งแรกเพื่อเป็นการตอบแทนที่ไม่ต้องทำงานprecompileสิ่งนี้สมเหตุสมผลหรือไม่


1
คำเตือนเฟืองที่เก่ากว่ามีข้อผิดพลาดและหาก config.assets.compile ได้รับการกำหนดค่าให้เป็นจริงอาจมีความเสี่ยงที่ช่องโหว่ของไดเรกทอรี trasversal ( blog.heroku.com/rails-asset-pipeline-vulnerability )
Mauro

นี่เป็นวิธีที่ Stackoverflow ควรทำงาน คำถามที่เขียนดีและคำตอบที่เป็นลายลักษณ์อักษร ฉันรักคุณทั้ง op และ @ richard-hulse
schmijos

คำตอบ:


259

ฉันเขียนคำแนะนำเล็กน้อยนั้น

คุณไม่ต้องการรวบรวมการผลิตจริง ๆ

เมื่อคุณคอมไพล์แล้วนี่คือสิ่งที่เกิดขึ้น:

ทุกคำขอสำหรับไฟล์ใน / เนื้อหาจะถูกส่งไปยังเฟือง ในการร้องขอครั้งแรกสำหรับสินทรัพย์แต่ละรายการนั้นจะถูกรวบรวมและเก็บไว้ใน Rails ที่ใช้สำหรับแคช (โดยปกติคือระบบไฟล์)

ในการร้องขอครั้งต่อไปเฟืองจะได้รับคำขอและต้องค้นหาชื่อไฟล์ลายนิ้วมือให้ตรวจสอบว่าไฟล์ (ภาพ) หรือไฟล์ (css และ js) ที่ประกอบขึ้นเป็นเนื้อหาไม่ได้ถูกแก้ไขและหากมีเวอร์ชันแคชไว้

นั่นคือทุกอย่างในโฟลเดอร์สินทรัพย์และในโฟลเดอร์ผู้ขาย / สินทรัพย์ที่ใช้โดยปลั๊กอิน

นั่นคือค่าใช้จ่ายจำนวนมากตามความจริงแล้วรหัสไม่ได้รับการปรับให้เหมาะกับความเร็ว

สิ่งนี้จะมีผลกระทบต่อความรวดเร็วในการโอนทรัพย์สินของลูกค้าและจะส่งผลเสียต่อเวลาในการโหลดหน้าเว็บไซต์ของคุณ

เปรียบเทียบกับค่าเริ่มต้น:

สินทรัพย์ที่ precompiled public/assetsและรวบรวมปิดสินทรัพย์จะถูกรวบรวมและพิมพ์ลายนิ้วมือไป Sprockets ส่งคืนตารางการแมปของชื่อไฟล์ธรรมดาไปยังลายนิ้วมือไปยัง Rails และ Rails เขียนสิ่งนี้ลงในระบบไฟล์ ไฟล์รายการ (YML ใน Rails 3 หรือ JSON ที่มีชื่อแบบสุ่มใน Rails 4) ถูกโหลดลงในหน่วยความจำโดย Rails เมื่อเริ่มต้นและแคชเพื่อใช้งานโดยวิธีการช่วยเหลือของสินทรัพย์

สิ่งนี้ทำให้การสร้างเพจด้วยสินทรัพย์ที่มีลายนิ้วมือที่ถูกต้องรวดเร็วและการให้บริการไฟล์เองนั้นเป็นระบบเว็บเซิร์ฟเวอร์จากระบบไฟล์ที่รวดเร็ว ทั้งสองอย่างรวดเร็วกว่าการคอมไพล์สด

เพื่อให้ได้ประโยชน์สูงสุดจากไปป์ไลน์และลายนิ้วมือคุณต้องตั้งค่าส่วนหัวในอนาคตอันไกลบนเว็บเซิร์ฟเวอร์ของคุณและเปิดใช้งานการบีบอัด gzip สำหรับไฟล์ js และ css Sprockets เขียนเนื้อหารุ่น gzipped ซึ่งคุณสามารถตั้งค่าเซิร์ฟเวอร์ของคุณให้ใช้งานได้โดยไม่จำเป็นต้องทำเช่นนั้นสำหรับแต่ละคำขอ

สิ่งนี้ทำให้ทรัพย์สินออกไปยังลูกค้าอย่างรวดเร็วที่สุดเท่าที่จะเป็นไปได้และในขนาดที่เล็กที่สุดเท่าที่จะเป็นไปได้การเร่งการแสดงผลฝั่งไคลเอ็นต์ของหน้าเว็บและลดคำขอ (ด้วยส่วนหัวในอนาคต)

ดังนั้นหากคุณกำลังรวบรวมสดมันคือ:

  1. ช้ามาก
  2. ไม่มีการบีบอัด
  3. จะส่งผลกระทบต่อเวลาแสดงผลของหน้าเว็บ

กับ

  1. ให้เร็วที่สุด
  2. การบีบอัด
  3. ลบการบีบอัดได้ยินจากเซิร์ฟเวอร์ (ไม่บังคับ)
  4. ลดเวลาในการเรนเดอร์หน้า

แก้ไข: (ตอบคำถามเพื่อติดตามความคิดเห็น)

ไปป์ไลน์สามารถเปลี่ยนเป็นคอมไพล์ก่อนคำขอแรก แต่มีสิ่งกีดขวางบนถนนที่สำคัญที่จะทำเช่นนั้น อย่างแรกคือต้องมีตารางการค้นหาชื่อลายนิ้วมือหรือวิธีช่วยเหลือช้าเกินไป ภายใต้ Senario แบบคอมไพล์ตามความต้องการจะต้องมีวิธีต่อท้ายตารางการค้นหาเนื่องจากเนื้อหาใหม่แต่ละรายการจะถูกรวบรวมหรือร้องขอ

นอกจากนี้บางคนจะต้องจ่ายราคาของการส่งมอบสินทรัพย์ที่ช้าเป็นระยะเวลาที่ไม่รู้จักจนกว่าสินทรัพย์ทั้งหมดจะถูกรวบรวมและในสถานที่

ค่าเริ่มต้นซึ่งราคาการรวบรวมทุกอย่างจะถูกจ่ายแบบออฟไลน์ในครั้งเดียวจะไม่ส่งผลกระทบต่อผู้เข้าชมสาธารณะและทำให้มั่นใจได้ว่าทุกอย่างใช้งานได้ก่อนที่สิ่งต่างๆจะปรากฏจริง

ดีลเลอร์ตัวจัดการคือมันเพิ่มความซับซ้อนให้กับระบบการผลิต

[แก้ไข, มิถุนายน 2558]หากคุณกำลังอ่านสิ่งนี้อยู่เพราะคุณกำลังมองหาวิธีการรวบรวมเวลาที่ช้าในระหว่างการปรับใช้คุณสามารถพิจารณารวบรวมข้อมูลในเครื่องล่วงหน้า ข้อมูลเกี่ยวกับเรื่องนี้อยู่ในคู่มือท่อสินทรัพย์ สิ่งนี้ช่วยให้คุณสามารถคอมไพล์ล่วงหน้าโลคัลเฉพาะเมื่อมีการเปลี่ยนแปลงยอมรับว่าและจากนั้นมีการปรับใช้อย่างรวดเร็วโดยไม่มีสเตจการคอมไพล์ล่วงหน้า


1
ขอบคุณฉันตอบรับแล้ว แต่ตอนนี้คำถามของฉันคือโอเคมันไม่ได้ทำตอนนี้ แต่คุณคิดหรือไม่ว่าท่อส่งทรัพย์สินอาจมีคุณสมบัติที่มันรวบรวมคอมไพล์ในคำขอแรกทำมันเหมือน precompile รวมทั้งเขียนถึง. /public และปรับปรุง รายการลายนิ้วมือ?
jrochkind

ดูด้านบน. นี่เป็นปัญหาหรือไม่เนื่องจาก Capistrano ใช้งานไม่ได้สำหรับคุณ
Richard Hulse

ฉันไม่ได้ใช้ Capistrano ฉันไม่จำเป็นต้องมาก่อนความซับซ้อนที่เพิ่มเข้ามาก็ไม่คุ้มค่า บางทีท่อส่งทรัพย์สินคือฟางที่ทำให้อูฐแตกและต้องการมัน ในความเห็นของคุณเป็นไปไม่ได้ที่จะจัดการ Rails ปรับใช้ระบบท่อโดยไม่ต้องมี capistrano หรือคล้ายกัน? มันเป็นเรื่องน่าละอายสำหรับการตั้งค่าแบบง่าย ๆ ที่เคยเป็นปัญหาใหญ่ที่ต้องทำด้วยมือ
jrochkind

คุณจำเป็นต้องใช้ Capistrano สำหรับ Rails 3.1 มีการรวบรวมเนื้อหาในไดเรกทอรีสาธารณะใหม่ในขณะที่แอปเก่าของคุณยังคงทำงานอยู่ เมื่อทำการคอมไพล์เสร็จแล้วเวอร์ชันใหม่จะถูกเชื่อมโยงและเซิร์ฟเวอร์จะรีสตาร์ทโดยอัตโนมัติ
Richard Hulse

"เพื่อให้ได้ประโยชน์สูงสุดจากไปป์ไลน์และลายนิ้วมือคุณต้องตั้งค่าส่วนหัวในอนาคตอันไกลบนเว็บเซิร์ฟเวอร์ของคุณและเปิดใช้งานการบีบอัด gzip สำหรับไฟล์ js และ css" - คุณสามารถให้คำแนะนำหรือลิงค์เกี่ยวกับวิธีการทำ นี้?
Isaac Betesh

7

ที่จะมีค่าใช้จ่ายน้อยลงด้วยสิ่งที่รวบรวมล่วงหน้า

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

จากนั้นคุณสามารถใช้รูปภาพและสไตล์ชีทเป็น "/assets/stylesheet.css" ใน * .html.erb หรือ "/assets/web.png"


6

สำหรับทุกคนที่ใช้ Heroku:

หากคุณปรับใช้กับ Herkou มันจะทำการเตรียมคอมไพล์ให้คุณโดยอัตโนมัติในระหว่างการปรับใช้หากไม่ได้รวมสินทรัพย์ที่คอมไพล์แล้ว (เช่นpublic/assetsไม่ได้คอมมิท) ดังนั้นจึงไม่จำเป็นต้องใช้config.assets.compile = trueหรือคอมไพล์สินทรัพย์ที่คอมไพล์แล้ว

เอกสารของ Heroku อยู่ที่นี่แล้ว CDNจะแนะนำให้เอาภาระในทรัพยากรไดโน


1

มันจะไม่เหมือนกับ precompiling แม้ว่าหลังจากการโจมตีครั้งแรก: เนื่องจากไฟล์ไม่ได้ถูกเขียนไปยังระบบไฟล์พวกเขาไม่สามารถให้บริการโดยตรงจากเว็บเซิร์ฟเวอร์ รหัสทับทิมบางตัวจะเกี่ยวข้องเสมอแม้ว่าจะเป็นเพียงแค่อ่านรายการแคช


อืมฉันคิดว่าด้วยprecompile=trueไฟล์ที่รวบรวมจะถูกเขียนไปยังระบบไฟล์ คุณแน่ใจไหม? ให้ฉันตรวจสอบ ...
jrochkind

1
Bah ผมคิดว่าคุณกำลังขวา - พวกเขาจะเขียนให้เป็นระบบไฟล์ แต่มันดูเหมือนว่าในtmp/cacheมากกว่าpublic/assetsจึงไม่สถานที่ที่เว็บเซิร์ฟเวอร์สามารถดูพวกเขายังคงไปได้เสิร์ฟโดยทางรถไฟ app ไม่ได้เป็น เว็บเซิร์ฟเวอร์ blah ถูกต้องคุณคิดว่า?
jrochkind

แก้ไข. จะไม่เร็วเท่ากับการให้เว็บเซิร์ฟเวอร์มารับทันที อาจไม่สำคัญว่าคุณจะใส่ cdn เหมือน cloudfront ไว้ตรงหน้าแอปของคุณหรือไม่
Frederick Cheung

1

ชุด config.asset.compile = false

เพิ่ม Gemfile ของคุณ

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

ติดตั้งมัด

วิ่ง rake assets:precompile

จากนั้นเริ่มเซิร์ฟเวอร์ของคุณ


เท่าที่ฉันมีconfig.asset.compile = true in production.rbไฟล์ชุดเพราะไม่มีกลไกก่อนคอมไพล์ถูกเพิ่ม เนื่องจากว่าทุกครั้งที่เราเริ่มต้นเซิร์ฟเวอร์จะใช้เวลามากเกินไปในการโหลดหน้าเว็บ (เมื่อมีการร้องขอทั้งการประมวลผลคำขอและการรวบรวมเนื้อหา) ตอนนี้ฉันรวมอยู่turbo-sprockets-rails3ใน Gemfile และเรียกใช้คำสั่งrake assets:precompileของมันรวบรวมสินทรัพย์ก่อน ตอนนี้ฉันตั้งค่าconfig.asset.compile = false in production.rbและเริ่มเซิร์ฟเวอร์หน้าโหลดโดยไม่ล่าช้า (ดำเนินการตามคำขอโดยไม่มีการรวบรวมเนื้อหาเท่านั้น)
Mohammed Saleem

2
คุ้มค่าที่turbo-sprockets-rails3จะบอกว่าจำเป็นสำหรับ Ruby 3 เท่านั้น
Andre Figueiredo

0

จากคู่มืออย่างเป็นทางการ:

ในการร้องขอครั้งแรกสินทรัพย์จะถูกรวบรวมและแคชตามที่ระบุไว้ในการพัฒนาข้างต้นและชื่อรายการที่ใช้ในผู้ช่วยเหลือจะถูกเปลี่ยนแปลงเพื่อรวมแฮ MD5

เฟืองยังตั้งค่าส่วนหัว Cache-Control HTTP เป็น max-age = 31536000 สิ่งนี้จะส่งสัญญาณแคชทั้งหมดระหว่างเซิร์ฟเวอร์ของคุณและเบราว์เซอร์ไคลเอ็นต์ว่าเนื้อหานี้ (ไฟล์ที่ให้บริการ) นั้นสามารถแคชได้เป็นเวลา 1 ปี ผลกระทบของสิ่งนี้คือการลดจำนวนคำขอสำหรับเนื้อหานี้จากเซิร์ฟเวอร์ของคุณ สินทรัพย์มีโอกาสที่ดีที่จะอยู่ในแคชเบราว์เซอร์ท้องถิ่นหรือแคชระดับกลางบางส่วน

โหมดนี้ใช้หน่วยความจำมากกว่าทำงานได้ไม่ดีกว่าค่าเริ่มต้นและไม่แนะนำ

นอกจากนี้ขั้นตอนการพรีคอมไพล์ก็ไม่เป็นปัญหาหากคุณใช้Capistranoในการปรับใช้ มันดูแลมันให้คุณ คุณเพิ่งวิ่ง

cap deploy

หรือ (ขึ้นอยู่กับการตั้งค่าของคุณ)

cap production deploy

และคุณพร้อมแล้ว หากคุณยังไม่ได้ใช้ฉันขอแนะนำให้ตรวจสอบ


คุณคิดว่าภาษาจากคำแนะนำอย่างเป็นทางการเห็นด้วยกับฉันไหม ฉันเคยเห็นมัคคุเทศก์นั้นฉันไม่แน่ใจว่ามันหมายถึงสิ่งที่ฉันแนะนำข้างต้นคุณคิดอย่างไร? นั่นคือคำถามของฉัน
jrochkind

ใช่คุณพูดโดยทั่วไปในสิ่งเดียวกัน ฉันแนะนำให้คุณอย่าเปิดการคอมไพล์สด
Sergio Tulentsev

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.