Acara pemuatan turbolink tidak berfungsi pada pemuatan halaman

Saya mengalami masalah dengan peristiwa pemuatan rekomendasi turbolink default saat ini:

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

Apa yang terjadi adalah ini tidak aktif di Safari saat halaman dimuat. Oleh karena itu saya menambahkan Turbolinks.dispatch("turbolinks:load"); ke application.js.

Tampaknya berfungsi dengan baik. Namun di Chrome, ini diaktifkan secara otomatis, sehingga yang akhirnya terjadi adalah peristiwa turbolinks:load yang terjadi dua kali.

Perbaikan pertama saya adalah mengaktifkan turbolinks:load hanya di browser non-Chrome.

Namun entah bagaimana, bahkan di Chrome, beberapa tampilan tidak memicu turbolinks:load secara otomatis. Jadi saya akhirnya harus mengaktifkannya pada tampilan tertentu juga.

Solusi terakhir yang saya temukan adalah menggunakan:

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

Ini sepertinya memperbaiki semua masalah karena aktif saat halaman pertama dimuat atau dimuat ulang dan saat saya mengeklik tautan. Itu juga aktif di Chrome dan Safari.

Apakah ada cara yang lebih baik untuk menangani hal ini?

Dokumen mengatakan bahwa versi pertama benar, tetapi tampaknya tidak demikian.

Apakah saya melewatkan sesuatu?

(catatan: menggunakan jQuery bukanlah kerugian bagi saya dan saya tahu saya bisa menerapkannya dengan beberapa document.addEventListener)


person lucasarruda    schedule 01.05.2018    source sumber
comment
Bagaimana Anda memuat di Turbolinks? yaitu di mana tag skrip Anda di halaman tersebut dan apakah Anda menggunakan async di <script>?   -  person Dom Christie    schedule 02.05.2018
comment
Saya memuat dengan cara Rails normal, pada pipa aset. Lalu saya memindahkannya dari badan ke kepala dan menambahkan async di dalamnya. Memuat semua dalam satu js (application.js), jadi saya tidak memiliki masalah async.   -  person lucasarruda    schedule 02.05.2018


Jawaban (1)


Seperti disebutkan di komentar, Anda memuat Turbolinks dengan async. Turbolink saat ini tidak berfungsi dengan baik ketika dimuat secara asinkron. Jadi saran terbaik saat ini adalah menghapus atribut async dari tag skrip, atau gunakan defer sebagai gantinya.

Mengapa?

Turbolinks mendengarkan peristiwa DOMContentLoaded pada pemuatan pertama untuk kemudian memicu turbolinks:load. Dengan memuatnya secara asinkron, ada kemungkinan skrip selesai memuat/dieksekusi setelah HTML diuraikan dan DOMContentLoaded diaktifkan. Dalam hal ini, turbolinks:load tidak akan dipecat.

Saat ini ada masalah GitHub untuk membahas beberapa kemungkinan solusi yang dapat diterapkan oleh perpustakaan: https://github.com/turbolinks/turbolinks/issues/281

person Dom Christie    schedule 03.05.2018
comment
Mengerti, terima kasih atas jawabannya. Jadi, bahkan memuat turbolink di dalam application.js itu (semuanya dibundel di sana) bermasalah dengan async. Haruskah saya menggunakan penundaan? Jika tidak, saya harus memindahkannya dari sundulan yang tidak menghasilkan poin. - person lucasarruda; 03.05.2018
comment
Ya. Turbolink bergantung pada peristiwa DOMContentLoaded, yang mungkin diaktifkan sebelum application.js dimuat dan dieksekusi. Menggunakan defer seharusnya tidak masalah, karena DOMContentLoaded diaktifkan setelah skrip dimuat dan dieksekusi. Perlu dicatat bahwa bahkan tanpa defer, skrip application.js hanya akan memblokir pada pemuatan pertama. Pemuatan Turbolink berikutnya tidak akan terpengaruh. FWIW, menurut saya pengembang Turbolinks tidak menggunakan defer. Hindari meletakkan application.js Anda di ‹body›. - person Dom Christie; 04.05.2018
comment
Terima kasih balasannya. Kekhawatiran saya adalah menempatkan di kepala, tanpa defer akan menyebabkan pemuatan pertama kali meningkat, skor Google / SEO menurun, dan lho sejarahnya. Saya akan melakukan tes dengan defer kalau begitu. - person lucasarruda; 04.05.2018
comment
Secara pribadi, saya tidak akan terlalu terlalu khawatir tentang menempatkan skrip Anda di ‹head› kecuali jika ukuran filenya besar. - person Dom Christie; 09.05.2018
comment
Memang tidak besar, di bawah 300kb, tapi menurut saya ini adalah rekomendasi kuat dari Google dalam hal SEO/optimasi halaman. - person lucasarruda; 09.05.2018
comment
OKE. Mungkin ada baiknya melakukan audit kinerja/SEO di Chrome untuk melihat seberapa besar dampaknya. FWIW pada aplikasi utama yang saya kerjakan, kami tidak menunda pemuatan skrip, dan menerima skor SEO 89, dan skor kinerja 82, sehingga mungkin tidak membuat perbedaan besar pada cara Google memberi peringkat pada laman Anda. Namun file application.js hanya berukuran 81,3 KB (diperkecil/gzip) - person Dom Christie; 11.05.2018
comment
Akan melakukan itu. Saya ingin tahu apakah Anda tidak melihat rekomendasi tersebut di alat Kecepatan Laman Google. - person lucasarruda; 11.05.2018
comment
Ya, itu adalah rekomendasi, tetapi mengingat skor kinerja/SEO yang cukup tinggi, ini menunjukkan bahwa ini mungkin bukan masalah besar (dalam kasus saya). - person Dom Christie; 11.05.2018
comment
Oh oke, mengerti. Saat ini kita berada di tahun 90an jadi saya rasa itu membantu. - person lucasarruda; 11.05.2018
comment
Saya belum menguji satu versi vs versi lainnya, tetapi saya mengalami beberapa masalah intermiten yang terkadang menyebabkan kode di dalam $(document).on('ready turbolinks:load', function() { dipanggil dua kali. Dan sekarang memindahkan async ke defer membuat document.addEventListener('turbolinks:load', function() { berfungsi dengan baik dan hanya diaktifkan sekali, dalam semua kasus diuji. Jadi yang pasti, pendekatan yang benar di sini (dengan defer atau tanpa apa pun). Terima kasih atas semua bantuannya! - person lucasarruda; 15.05.2018