เหตุการณ์การโหลด Turbolinks ไม่ทำงานเมื่อโหลดเพจ

ฉันมีปัญหากับเหตุการณ์โหลดที่แนะนำโดย turbolinks เริ่มต้นปัจจุบัน:

document.addEventListener('turbolinks:load', function() {
  …
});

สิ่งที่เกิดขึ้นคือสิ่งนี้ไม่เริ่มทำงานบน Safari เมื่อโหลดเพจ ดังนั้นฉันจึงต่อท้าย Turbolinks.dispatch("turbolinks:load"); ถึง application.js

ดูเหมือนว่ามันจะทำงานได้ดี. แต่บน Chrome มันเริ่มทำงานโดยอัตโนมัติ ดังนั้นสิ่งที่เกิดขึ้นคือเหตุการณ์ turbolinks:load เกิดขึ้นสองครั้ง

การแก้ไขแรกของฉันคือให้เริ่มทำงาน turbolinks:load บนเบราว์เซอร์ที่ไม่ใช่ Chrome เท่านั้น

แต่อย่างใด แม้แต่บน Chrome มุมมองบางส่วนก็ไม่ทริกเกอร์ turbolinks:load โดยอัตโนมัติ ดังนั้นฉันจึงต้องยิงมันในมุมมองที่เฉพาะเจาะจงด้วย

วิธีแก้ปัญหาสุดท้ายที่ฉันพบคือการใช้:

$(document).on('ready turbolinks:load', function() {
  …
});

ดูเหมือนว่าจะแก้ไขปัญหาทั้งหมดได้เนื่องจากเริ่มทำงานเมื่อโหลดหน้าแรกหรือโหลดซ้ำและเมื่อฉันคลิกลิงก์ นอกจากนี้ยังเริ่มทำงานบน Chrome และ Safari

มีวิธีที่ดีกว่าในการจัดการเรื่องนี้หรือไม่

เอกสารบอกว่าเวอร์ชันแรกนั้นถูกต้อง แต่ดูเหมือนจะไม่เป็นเช่นนั้น

ฉันพลาดอะไรบางอย่างไปหรือเปล่า?

(หมายเหตุ: การใช้ jQuery ไม่ใช่ข้อเสียสำหรับฉัน และฉันรู้ว่าฉันสามารถนำไปใช้กับ document.addEventListener สองสามรายการได้)


person lucasarruda    schedule 01.05.2018    source แหล่งที่มา
comment
คุณเพลิดเพลินกับ Turbolinks แค่ไหน? เช่น แท็กสคริปต์ของคุณอยู่ที่ไหนบนหน้าเว็บ และคุณใช้ async บน <script> หรือไม่   -  person Dom Christie    schedule 02.05.2018
comment
ฉันกำลังโหลดทางรถไฟแบบปกติ บนไปป์ไลน์สินทรัพย์ จากนั้นฉันก็ย้ายมันจากตัวหนึ่งไปอีกตัวหนึ่งและเพิ่มอะซิงก์ลงไป กำลังโหลดทั้งหมดในที่เดียว js (application.js) ดังนั้นฉันจึงไม่มีปัญหาเรื่อง async   -  person lucasarruda    schedule 02.05.2018


คำตอบ (1)


ตามที่ระบุไว้ในความคิดเห็น คุณกำลังโหลด Turbolinks ด้วย async ปัจจุบัน Turbolinks ทำงานได้ไม่ดีเมื่อโหลดแบบอะซิงโครนัส คำแนะนำที่ดีที่สุดในขณะนี้คือการลบแอตทริบิวต์ async ออกจากแท็กสคริปต์ หรือใช้ defer แทน

ทำไม

Turbolinks รับฟังเหตุการณ์ DOMContentLoaded ในการโหลดครั้งแรก จากนั้นจึงทริกเกอร์ turbolinks:load การโหลดแบบอะซิงโครนัสอาจเป็นไปได้ว่าสคริปต์โหลด/ดำเนินการเสร็จสิ้น หลังจาก HTML ถูกแยกวิเคราะห์และ DOMContentLoaded เริ่มทำงานแล้ว ในกรณีนี้ turbolinks:load จะไม่ถูกไล่ออก

ขณะนี้มีปัญหา GitHub เพื่อหารือเกี่ยวกับวิธีแก้ปัญหาที่เป็นไปได้สำหรับไลบรารีที่จะนำไปใช้: https://github.com/turbolinks/turbolinks/issues/281

person Dom Christie    schedule 03.05.2018
comment
เข้าใจแล้ว ขอบคุณสำหรับคำตอบ ดังนั้นแม้แต่การโหลด turbolinks ภายใน application.js นั้น (มันรวมอยู่ในนั้นทั้งหมด) ก็เป็นปัญหากับ async ฉันควรใช้ defer หรือไม่? ไม่อย่างนั้นผมคงต้องย้ายมันออกจากส่วนหัวที่เอาชนะจุดนั้นไป - person lucasarruda; 03.05.2018
comment
ใช่. Turbolinks ขึ้นอยู่กับเหตุการณ์ DOMContentLoaded ซึ่งอาจเริ่มทำงานก่อนที่ application.js จะโหลดและดำเนินการ การใช้ defer ควรจะไม่เป็นไร เนื่องจาก DOMContentLoaded เริ่มทำงานหลังจากที่สคริปต์โหลดและดำเนินการแล้ว เป็นที่น่าสังเกตว่าแม้ไม่มี defer สคริปต์ application.js จะบล็อกเฉพาะการโหลดครั้งแรกเท่านั้น โหลด Turbolinks ครั้งต่อไปจะไม่ได้รับผลกระทบ FWIW ฉันไม่คิดว่าผู้พัฒนา Turbolinks ใช้ defer หลีกเลี่ยงการใส่ application.js ของคุณใน ‹body› - person Dom Christie; 04.05.2018
comment
ขอบคุณสำหรับการตอบกลับ. ความกังวลของฉันคือการใส่หัวโดยไม่มี defer จะทำให้การโหลดครั้งแรกเพิ่มขึ้น คะแนน Google / SEO ลดลง และคุณรู้ประวัติแล้ว ฉันจะทำการทดสอบกับ defer แล้ว - person lucasarruda; 04.05.2018
comment
โดยส่วนตัวแล้ว ฉันไม่ต้องกังวล มากเกินไป กับการวางสคริปต์ของคุณใน ‹head› เว้นแต่ว่าไฟล์จะมีขนาดใหญ่มาก - person Dom Christie; 09.05.2018
comment
ขนาดไม่ใหญ่มาก ต่ำกว่า 300kb แต่ฉันคิดว่านี่เป็นคำแนะนำที่ดีจาก Google ในแง่ของ SEO / การเพิ่มประสิทธิภาพเพจ - person lucasarruda; 09.05.2018
comment
ตกลง. การดำเนินการตรวจสอบประสิทธิภาพ/SEO ใน Chrome อาจคุ้มค่าเพื่อดูว่าสิ่งนี้มีผลกระทบมากเพียงใด FWIW ในแอปหลักที่ฉันทำงานอยู่ เราไม่เลื่อนการโหลดสคริปต์ และได้รับคะแนน SEO 89 คะแนน และคะแนนประสิทธิภาพ 82 คะแนน ดังนั้นจึงไม่สามารถสร้างความแตกต่างอย่างมากต่ออันดับหน้าเว็บของคุณของ Google อย่างไรก็ตาม ไฟล์ application.js มีขนาดเพียง 81.3 KB (ย่อเล็กสุด/gzipped) - person Dom Christie; 11.05.2018
comment
จะทำอย่างนั้น. ฉันอยากรู้ว่าถ้าคุณไม่เห็นคำแนะนำนั้นในเครื่องมือ Google Page Speed - person lucasarruda; 11.05.2018
comment
ใช่ มันเป็นคำแนะนำ แต่เมื่อพิจารณาจากคะแนนประสิทธิภาพ/SEO ที่สูงพอสมควร ก็แสดงให้เห็นว่ามันอาจจะไม่ใช่เรื่องใหญ่อะไร (ในกรณีของฉัน) - person Dom Christie; 11.05.2018
comment
โอเค เข้าใจแล้ว ขณะนี้เราอยู่ในยุค 90 ดังนั้นฉันเดาว่ามันช่วยได้ - person lucasarruda; 11.05.2018
comment
ฉันยังไม่ได้ทดสอบเวอร์ชันใดเวอร์ชันหนึ่งเทียบกับเวอร์ชันอื่น แต่ฉันประสบปัญหาเป็นระยะ ๆ ซึ่งบางครั้งโค้ดภายใน $(document).on('ready turbolinks:load', function() { จะถูกเรียกสองครั้ง และตอนนี้การย้าย async ไปที่ defer ทำให้ document.addEventListener('turbolinks:load', function() { ทำงานได้อย่างถูกต้องและจะเริ่มทำงานเพียงครั้งเดียวเท่านั้น ในทุกกรณีที่ผ่านการทดสอบ แน่นอนว่าแนวทางที่ถูกต้องที่นี่ (มี defer หรือไม่มีอะไรเลย) ขอบคุณสำหรับความช่วยเหลือทั้งหมด! - person lucasarruda; 15.05.2018