Apakah browser mem-parsing javascript pada setiap halaman memuat?

190

Apakah browser (IE dan Firefox) mem-parsing file javascript yang ditautkan setiap kali halaman disegarkan?

Mereka dapat men-cache file, jadi saya kira mereka tidak akan mencoba mengunduhnya setiap kali, tetapi karena setiap halaman pada dasarnya terpisah, saya berharap mereka untuk merobohkan kode lama dan menguraikannya kembali.

Ini tidak efisien, meskipun sangat bisa dimengerti, tetapi saya bertanya-tanya apakah browser modern cukup pintar untuk menghindari langkah penguraian dalam situs. Saya memikirkan kasus di mana situs menggunakan perpustakaan javascript, seperti ExtJS atau jQuery, dll.

nyata
sumber
4
2c saya: Saya merasa manfaat kinerja dari caching file Javascript yang diuraikan terlalu kecil untuk ini menjadi optimasi yang berarti.
Itay Maman
2
Dari tolok ukur saya, mungkin sebenarnya penting. Misalnya waktu pengambilan jQuery adalah sekitar 30 msecs (pada mesin desktop cepat), di mana 20% hanya mengurai kode menjadi representasi yang dapat dieksekusi, dan sisanya menjalankannya, yaitu menginisialisasi objek jQuery dalam kasus ini. Jika Anda menggunakan ponsel, dan Anda menggunakan dua atau tiga pustaka, penundaan ini mungkin relevan, karena eksekusi JavaScript diblokir, dan halaman tersebut pada dasarnya kosong sampai setiap skrip JS dimuat dalam memori.
djjeck

Jawaban:

338

Ini adalah detail yang bisa saya gali. Perlu dicatat terlebih dahulu bahwa meskipun JavaScript biasanya dianggap ditafsirkan dan dijalankan pada VM, ini tidak benar-benar terjadi dengan penerjemah modern, yang cenderung mengkompilasi sumber secara langsung ke dalam kode mesin (dengan pengecualian IE).


Chrome: Mesin V8

V8 memiliki cache kompilasi. Toko ini mengkompilasi JavaScript menggunakan hash sumber hingga 5 koleksi sampah. Ini berarti bahwa dua bagian kode sumber yang identik akan berbagi entri cache dalam memori terlepas dari bagaimana mereka dimasukkan. Cache ini tidak dihapus ketika halaman dimuat ulang.

Sumber


Pembaruan - 19/03/2015

Tim Chrome telah merilis detail tentang teknik baru mereka untuk streaming dan caching JavaScript .

  1. Streaming Skrip

Script streaming mengoptimalkan penguraian file JavaScript. [...]

Mulai versi 41, Chrome mem-parsing async dan skrip yang ditangguhkan pada utas terpisah segera setelah pengunduhan dimulai. Ini berarti penguraian dapat selesai hanya dalam milidetik setelah pengunduhan selesai, dan menghasilkan pemuatan halaman sebanyak 10% lebih cepat.

  1. Caching kode

Biasanya, mesin V8 mengkompilasi JavaScript halaman pada setiap kunjungan, mengubahnya menjadi instruksi yang dimengerti oleh prosesor. Kode yang dikompilasi ini kemudian dibuang begitu pengguna menavigasi dari halaman karena kode yang dikompilasi sangat tergantung pada keadaan dan konteks mesin pada waktu kompilasi.

Chrome 42 memperkenalkan teknik canggih menyimpan salinan lokal dari kode yang dikompilasi, sehingga ketika pengguna kembali ke halaman, langkah-langkah pengunduhan, penguraian, dan kompilasi semua bisa dilewati. Di semua pemuatan halaman, ini memungkinkan Chrome untuk menghindari sekitar 40% waktu kompilasi dan menghemat baterai berharga pada perangkat seluler.


Opera: Mesin Carakan

Dalam prakteknya ini berarti bahwa setiap kali sebuah program skrip akan dikompilasi, yang kode sumbernya identik dengan beberapa program lain yang baru-baru ini dikompilasi, kami menggunakan kembali output sebelumnya dari kompiler dan melewatkan langkah kompilasi sepenuhnya. Cache ini cukup efektif dalam skenario penelusuran biasa di mana satu memuat halaman demi halaman dari situs yang sama, seperti artikel berita berbeda dari layanan berita, karena setiap halaman sering memuat perpustakaan skrip yang sama, terkadang sangat besar.

Oleh karena itu JavaScript di-cache di seluruh reload halaman, dua permintaan ke skrip yang sama tidak akan menghasilkan kompilasi ulang.

Sumber


Firefox: Mesin SpiderMonkey

SpiderMonkey menggunakan Nanojitsebagai back-end aslinya, kompiler JIT. Proses kompilasi kode mesin dapat dilihat di sini . Singkatnya, tampaknya mengkompilasi ulang skrip saat dimuat. Namun, jika kita melihat lebih dalam pada internal Nanojitkita melihat bahwa monitor tingkat yang lebih tinggi jstracer, yang digunakan untuk melacak kompilasi dapat transisi melalui tiga tahap selama kompilasi, memberikan manfaat untuk Nanojit:

Keadaan awal jejak monitor adalah pemantauan. Ini berarti spidermonkey sedang menerjemahkan bytecode. Setiap kali spidermonkey menginterpretasikan bytecode back-jump-jump, monitor mencatat berapa kali nilai program-counter-target (PC) lompat-target telah dilompati-ke. Nomor ini disebut Hitungan Hitungan untuk PC. Jika jumlah hit PC tertentu mencapai nilai ambang, target dianggap panas.

Ketika monitor memutuskan bahwa PC target sedang panas, monitor akan melihat hashtable fragmen untuk melihat apakah ada fragmen yang menyimpan kode asli untuk PC target tersebut. Jika ia menemukan fragmen seperti itu, ia beralih ke mode eksekusi. Kalau tidak, transisi ke mode perekaman.

Ini berarti bahwa untuk hotfragmen kode kode asli di-cache. Berarti tidak perlu dikompilasi ulang. Tidak diperjelas apakah bagian asli hash ini dipertahankan di antara refresh halaman. Tetapi saya akan berasumsi bahwa mereka memang demikian. Jika ada yang bisa menemukan bukti pendukung untuk ini, maka sangat bagus.

EDIT : Sudah menunjukkan bahwa pengembang Mozilla Boris Zbarsky telah menyatakan bahwa Gecko tidak tembolok dikompilasi script belum . Diambil dari jawaban SO ini .


Safari: Mesin JavaScriptCore / SquirelFish

Saya pikir jawaban terbaik untuk implementasi ini sudah diberikan oleh orang lain .

Kami saat ini tidak men-cache bytecode (atau kode asli). Ini adalah
opsi yang kami pertimbangkan, namun, saat ini, pembuatan kode adalah
bagian sepele dari waktu eksekusi JS (<2%), jadi kami tidak mengejar
ini saat ini.

Ini ditulis oleh Maciej Stachowiak , pengembang utama Safari. Jadi saya pikir kita bisa menganggap itu benar.

Saya tidak dapat menemukan informasi lain tetapi Anda dapat membaca lebih lanjut tentang peningkatan kecepatan SquirrelFish Extrememesin terbaru di sini , atau menelusuri kode sumber di sini jika Anda merasa ingin bertualang.


IE: Mesin Chakra

Tidak ada informasi terkini tentang JavaScript Engine (Chakra) IE9 di bidang ini. Jika ada yang tahu sesuatu, silakan komentar.

Ini cukup tidak resmi, tetapi untuk implementasi mesin IE yang lebih lama, Eric Lippert ( pengembang MS dari JScript ) menyatakan dalam sebuah balasan blog di sini bahwa:

JScript Classic bertindak seperti bahasa yang dikompilasi dalam arti bahwa sebelum program JScript Classic berjalan, kami sepenuhnya sintaks memeriksa kode, menghasilkan parse tree penuh, dan menghasilkan bytecode. Kami kemudian menjalankan bytecode melalui interpreter bytecode. Dalam arti itu, JScript setiap bit "dikompilasi" sebagai Java. Perbedaannya adalah bahwa JScript tidak memungkinkan Anda untuk bertahan atau memeriksa bytecode milik kami . Juga, bytecode jauh lebih tinggi daripada byvec JVM - bahasa bytecode JScript Classic sedikit lebih dari linierisasi pohon parse, sedangkan bytecode JVM jelas dimaksudkan untuk beroperasi pada mesin tumpukan tingkat rendah.

Ini menunjukkan bahwa bytecode tidak bertahan dengan cara apa pun, dan dengan demikian bytecode tidak di-cache.

Jivings
sumber
10
+1, langganan yang sangat baik. Namun, mengenai Firefox, silakan lihat pertanyaan StackOverflow ini di mana Pengembang Mozilla Boris Zbarsky menjelaskan bahwa Gecko saat ini tidak melakukan ini.
cha0site
Terima kasih, saya melihat itu dalam perjalanan saya tetapi tidak dapat menemukan bukti pendukung lainnya. Saya akan mengedit jawabannya.
Jivings
1
Perhatikan bahwa apa yang dikatakan tentang IE dikatakan pada tahun 2003: Mesin JS pertama IE9 dirilis pada IE9 pada tahun 2011.
gsnedders
Juga, Opera membuat cache bytecode JS lebih dari sekadar memuat ulang. (Namun, kode mesin yang dihasilkan tidak di-cache).
gsnedders
2
@Jivings Ambil yang di atas sebagai sumber. (Saya salah satu dari orang-orang di tim Carakan.)
gsnedders
12

Opera melakukannya, seperti yang disebutkan dalam jawaban lain. ( sumber )

Firefox (mesin SpiderMonkey) tidak menyimpan bytecode cache. ( sumber )

WebKit (Safari, Konqueror) tidak tidak cache yang bytecode. ( sumber )

Saya tidak yakin tentang IE [6/7/8] atau V8 (Chrome), saya pikir IE mungkin melakukan semacam caching sementara V8 mungkin tidak. IE adalah sumber tertutup jadi saya tidak yakin, tetapi dalam V8 mungkin tidak masuk akal untuk men-cache kode "dikompilasi" karena mereka mengkompilasi langsung ke kode mesin.

situs cha0
sumber
1
IE6-8 hampir pasti tidak akan. IE9 mungkin, tapi saya juga tidak punya bukti. JS yang dikompilasi kemungkinan tidak di-cache di mana pun karena cukup sering cukup besar.
gsnedders
@gsnedders: Saya tidak yakin bahwa IE8 secara teknis tidak bisa melakukannya, tampaknya terlalu mengkompilasi untuk bytecode (tidak resmi tapi dekat), jadi tidak ada alasan teknis untuk tidak men-cache itu. IE9 tampaknya menambahkan JIT untuk dikompilasi ke kode asli.
cha0site
2
Bytecode telah digunakan oleh IE untuk ... selamanya. Bukan hal yang baru di IE8. Hanya saja, jika diberikan seorang penerjemah, kinerja penerjemah jauh lebih lambat daripada waktu parse, itu sama sekali tidak relevan. IE9 memiliki mesin JS yang sepenuhnya baru (dari awal), jadi tidak ada yang mengikuti di antara keduanya.
gsnedders
3

Sejauh yang saya ketahui, hanya Opera yang meng-cache JavaScript yang diuraikan. Lihat bagian "Program terkompilasi dalam cache" di sini .

gsnedders
sumber
terima kasih, apakah Anda memiliki detail lebih lanjut tentang keluarga browser lain juga?
ajreal
2

Tidak ada artinya Google Dart secara eksplisit menangani masalah ini melalui "Snapshots" - tujuannya adalah untuk mempercepat inisialisasi dan memuat waktu dengan memuat versi kode yang telah disiapkan.

InfoQ memiliki langgan yang baik @ http://www.infoq.com/articles/google-dart

igrigorik
sumber
0

Saya pikir jawaban yang benar adalah "tidak selalu." Dari apa yang saya mengerti, baik browser dan server berperan dalam menentukan apa yang di-cache. Jika Anda benar-benar membutuhkan file untuk dimuat ulang setiap kali, maka saya pikir Anda harus dapat mengonfigurasinya dari dalam Apache (misalnya). Tentu saja, saya kira browser pengguna dapat dikonfigurasikan untuk mengabaikan pengaturan itu, tapi itu mungkin tidak mungkin.

Jadi saya akan membayangkan bahwa dalam kebanyakan kasus praktis, file javascript itu sendiri di-cache, tetapi secara dinamis ditafsirkan kembali setiap kali halaman dimuat.

Zachary Murray
sumber
0

Browser pasti menggunakan caching tetapi ya, browser mem-parsing JavaScript setiap kali halaman di-refresh. Karena setiap kali halaman dimuat oleh browser, itu membuat 2 pohon 1.Content tree dan 2.render tree.

Pohon render ini terdiri dari informasi tentang tata letak visual elemen dom. Jadi, setiap kali halaman dibuka, javascript diuraikan dan setiap perubahan dinamis oleh javascript akan menyukai posisi elemen dom, tampilkan / sembunyikan elemen, tambahkan / hapus elemen akan menyebabkan browser membuat ulang pohon render. Tapi broswers modern seperti FF dan chrome menanganinya sedikit berbeda, mereka memiliki konsep render tambahan, sehingga setiap kali ada perubahan dinamis oleh js seperti yang disebutkan di atas, itu hanya akan menyebabkan elemen-elemen tersebut untuk membuat dan mengecat kembali.

Abhidev
sumber