it-swarm.asia

Ağ üzerinden göndermeden önce JavaScript neden bayt koduna derlenmiyor?

Sıklıkla JavaScript'in aslında orada olması gerekmeyen tüm gereksiz şeylerle web üzerinden taşındığını görüyorsunuz - Yorumlar, özellikle lisans içerenler, girinti ( '\ t' , '\ n' ), vs. Bir JavaScript bayt kodu daha büyük bir soruna neden olur mu veya henüz kimse bunu düşünmedi mi?

155
Vivek Yadav

Ağ üzerinden göndermeden önce JavaScript neden bayt koduna derlenmiyor?

Arka plan: 1990'ların sonunda ECMAScript teknik komitesindeydim ve Microsoft'un JScript motorunun uygulayıcılarından biriydim.

"Neden olmasın?" İle karşılaştığımda hep söylediğimi söyleyerek başlayayım. soru: dil tasarımcılarının, birilerinin sevdiği bir özellik için yüz milyonlarca başka insanın dolarını neden harcamadıklarına dair iyi nedenler belirtmeleri gerekmez. Aksine, bu özelliğe sahip olan kişinin, bu zamanı, çabayı ve parayı harcamanın en iyi yolu için iyi nedenler belirtmesi gerekir. Rakam kodunun bant genişliği açısından maliyetten tasarruf edilebileceği hiçbir sayı eklenmemiş bir argüman yaptınız. Sizi bazı gerçek sayılar geliştirmeye ve bunu başka bir dil yaratmanın maliyetleriyle karşılaştırmaya teşvik ediyorum; bu maliyetler önemlidir. Analizinizde "uygulamanın" en küçük maliyetlerden biri olduğunu unutmayın. Ayrıca analizinize kimlerin tasarruf ettiğini parayı kimin harcadığını harcadığını (---) harcadığını ve parayı harcayanların onu kurtaranlar değil; teşvikler önemlidir.

Dedi ki, bu daha makul "neden olmasın?" çünkü bu sebeplerle düşündüğümüz ve reddettiğimiz bir özellik.

Hem Microsoft hem de TC düzeyinde böyle bir planı düşündük; JScript zaten iyi tasarlanmış, ilkeli bir bytecode diline derleme olarak uygulandığından, bunu standart olarak önermek bizim için basit olurdu ve bunu yapmayı düşündük.

Aşağıdakileri içeren çeşitli nedenlerle:

  • Kutsal iyilik JavaScript'i standartlaştırmak için yeterince zordu. Herkes ve köpekleri bir bytecode dilinin ideal özelliklerinin ne olduğu hakkında bir fikre sahip olacaklardı ve birkaç yıl bisiklet sürmek olurdu. Kimse gerçekten oraya gitmek istemedi.
  • Pahalı bir sorunu olmayan pahalı bir çözümdü. Bir bayt kodu dilinin boyutta veya hızda daha verimli olacağını varsaymak için hiçbir neden yoktur. JavaScript zaten oldukça iyi küçülüyor ve oldukça sıkıştırılabilir.
  • Verimli, uyumlu bir JS uygulaması üretme masrafından dolayı zaten rahatsız olan tarayıcı sağlayıcıları için muazzam bir iş yaratacaktı.
  • Kötü aktörlerin saldırılarına direnen güvenli bir JS uygulaması oluşturmak yeterince zordur; saldırabilecek yüzey alanını iki katına çıkarmalı mıyız? Muhtemelen değil.
  • Standartlar inovasyon için bir engeldir. Bayt kodu dilimizde küçük bir değişiklik yapılmasının, daha önce öngörülemeyen veya daha önce önemsiz bazı kullanıcı senaryosunda büyük bir fark yaratacağını keşfettiysek, özgürdük bu değişikliği yapmak için. Standart olsaydı, bu kullanıcı avantajını oluşturmakta özgür olmazdık.

Ancak bu analiz, özelliği yapmanın nedeninin performans olduğunu varsayar. İlginçtir ki, 1990'larda bu özelliği dikkate alarak motive eden müşteri talepleri öncelikle performansla ilgili değildi.

Neden olmasın? 1990'lar JS için bugünden çok farklı bir zamandı; senaryolar çoğunlukla küçüktü. Bir gün yüz binlerce hatlı çerçeveler olacağı düşüncesi, radarımızda olmaya bile yakın değildi. JS'yi indirmek ve ayrıştırmak, HTML'yi indirmek ve ayrıştırmak için harcanan zamanın küçük bir kısmıydı.

Diğer dillere yönelik uzantı da motivasyon değildi, ancak tarayıcıda da VBScript çalıştığından Microsoft'a ilgi duyuyordu, bu da çok benzer bir bayt kodu dili kullandı. (Aynı ekip tarafından geliştirildi ve aynı kaynaklardan ve her şeyden derlendi.)

Aksine, tarayıcıdaki bayt kodunu motive etmek için birincil müşteri senaryosu, kodun okunmasını, anlaşılmasını, kaynak kodunun çözülmesini, tersine mühendislik yapılmasını ve kurcalanmasını zorlaştırmaktı. Bir bayt kodu dilinin, makul kaynaklara sahip herhangi bir saldırgan için anlaşılması gereken ek bir iş olmaması, bu işi yapmanın ana noktalarıydı; yanlış bir güvenlik duygusu oluşturmak istemedik.

Temelde çok fazla masraf ve değerli birkaç fayda vardı, bu yüzden yapılmadı. 1998 ile 2015 arasında, WebAssembly'nin makul bir fayda-fiyat fiyatına sahip olmasını sağlayan bir şey değişmiş olmalıdır; bu faktörlerin ne olduğunu bilmiyorum. WebAssembly hakkında bir uzmana sormanız gerekir.

381
Eric Lippert

Kaynağı Görüntüle

"Kaynağı Görüntüle" başlangıçta idi ve hala bir dereceye kadar web'in önemli bir özelliği olarak görülüyor. Web geliştiricilerinin nesillerinin web geliştirmeyi nasıl öğrendiği ve ilgili standart kurumları (ECMA TC39, W3C, WHATWG) hala çok ciddiye almaktadır.

Minification

ECMAScript dosyaları konuşlandırılmadan önce genellikle "simge durumuna küçültülür". Bu, tüm yorumların kaldırılmasını, tüm boşlukların ve tüm tanımlayıcıların mümkün olduğunca kısa olacak şekilde yeniden adlandırılmasını ve ayrıca ölü kodun kaldırılması gibi bazı üst düzey optimizasyonları içerir.

Sıkıştırma

HTTP/1.0'dan beri (1996 başı) HTTP'de sıkıştırma desteği bulunmaktadır. ECMAScript metindir ve metin gerçekten iyi sıkıştırır. Aslında, ECMAScript çok fazla yedekli (;, {, }, (, ), ,, ., function, var, if, for vb.) Ve sıkıştırma algoritmaları işten çıkarılmak. Dolayısıyla, aktarılan veri miktarı, olduğundan daha küçüktür. Bir deneme olarak, bir ECMAScript kaynak dosyasını web'de kullanılan tipik sıkıştırma algoritmalarından biriyle (örn. Gzip veya deflate) sıkıştırmayı deneyin ve bunu aynı dosyanın derlenmiş bayt kodunun boyutuyla karşılaştırın.

Bayt kodu biçimi

Bu da bizi bir sonraki soruna getiriyor: ECMAscript için standart bir bayt kodu formatı yok. Aslında, bazı uygulamalar bayt kodunu bile kullanamayabilir! Örneğin, ilk birkaç yıl içinde V8, ECMAScript'i doğrudan yerel makine koduna derledi ve aralarında bayt kodu yok. Chakra, SquirrelFish Extreme ve SpiderMonkey bayt kodu kullanır, ancak farklı bayt kodu kullanırlar. dyn.js, TruffleJS, Nashorn ve Rhine ECMAScript'e özel bayt kodu kullanmaz, JVML bayt kodunu derler. Benzer şekilde, IronJS CLI CIL bayt kodunu derler.

Şimdi şöyle diyebilirsiniz: Neden ECMAScript için standartlaştırılmış bir bayt kodu biçimi tanımlamıyor ? Bununla ilgili sorunlar iki katlıdır:

  1. Bayt kodu biçimi, yürütme motorunun tasarımını kısıtlar. Örneğin, JVM'lere bakın: JVM'ler ECMAScript motorlarından çok daha benzerdir. Şahsen, 2000'lerin sonları/2010'ların başlarındaki "performans yarışının" standart bir bayt kodu formatının eksikliğinin sağladığı geniş bir deney yelpazesi olmadan mümkün olmayacağına inanıyorum.

  2. Tüm ECMAScript motor satıcılarının ortak bir standart bayt kodu formatı üzerinde anlaşmasını sağlamak zor değil, aynı zamanda şunu da düşünün: sadece için bir bayt kodu formatı eklemek mantıklı değil Tarayıcıya ECMAScript. ortak bir bayt kodu formatı kullanırsanız, ActionScript, VBScript, Python, Ruby, Perl, Lua, PHP vb. iyi. Ancak şimdi, katlanarak artması dışında # 1'deki ile aynı soruna sahipsiniz: sadece tüm ECMAScript motor satıcılarının ortak bir bayt kodu formatı üzerinde anlaşması gerekmiyor, ayrıca PHP, Perl, Ruby, Python, Lua, vb. Topluluklar da aynı fikirde!

Önbelleğe almak

İyi bilinen yaygın olarak kullanılan kütüphaneler, birden fazla siteden başvurulabilecekleri kanonik URI'lerde barındırılmaktadır. Bu nedenle, yalnızca bir kez indirilmeleri gerekir ve istemci tarafında önbelleğe alınabilir.

CDN

Birçok kütüphane CDN kullanır, bu nedenle aslında kullanıcıya yakın bir yerden sunulur.

Wasm/asm.js

WebAssembly (Wasm) , şu anda W3C tarafından standartlaştırılan ve zaten Firefox, Chrome, Safari ve Edge'de gönderilen kompakt bir ikili talimat biçimidir. Bununla birlikte, ECMAScript için bayt kodu formatı olarak tasarlanmamıştır, bunun yerine C, C++ ve Rust gibi diller için düşük seviyeli bir taşınabilir makine kodu ve derleme hedefi olarak tasarlanmıştır.

Wasm'dan önce, benzer hedefleri olan asm.js vardı, ancak ECMAScript'in sözdizimsel ve anlamsal bir alt kümesi olarak tasarlandı, bu yüzden onu asm.js uyumlu olmayan bir motorda değiştirilmemiş olarak çalıştırabilirsiniz ve işe yarayabilir, çok daha yavaş.

114
Jörg W Mittag

JavaScript Netscape tarafından icat edildi. Tasarım amacı, web sayfalarını gömülü bir komut dosyası dili aracılığıyla etkileşimli hale getirmekti. Başlangıçta karmaşık uygulama için tasarlanmamıştı - karmaşık öğelerin Java küçük uygulamalar veya eklentiler) olarak yazılması gerekiyordu ve JavaScript, HTML öğelerini = Java küçük uygulamalar ve diğer kodlanabilir eklentiler.

JavaScript <input type="button" onclick="alert('hello world')"> gibi doğrudan HTML'ye gömülmek üzere tasarlanmıştır. Bu günlerde JavaScript'i HTML'ye gömmek kaşlarını çattı, ancak o günlerde bu, olay işleyicilerini bağlamanın standart yoluydu. Bu kullanım durumu göz önüne alındığında, JavaScript'in temel olarak metin tabanlı olması gerekiyordu.

Ayrıca JavaScript'te HTML oluşturmak için olanaklar vardı, örneğin:

<script>
  document.write("<input type=\"button\" onclick=\"alert('hello world')\">"
</script>

Yine, bu temelde JavaScript'in yararlı olması için metin formatı olmasını gerektirir.

Ayrıca, metinsel biçim sıradan geliştiriciler için çok daha kolaydır, çünkü bayt koduna derlemek için bir geliştirme ortamına ihtiyacınız yoktur. Sadece metni yazın ve çalıştığını görmek için tarayıcıyı yeniden yükleyin. JavaScript'in kullanıma sunulduğu sırada, özel HTML editörleri neredeyse hiç yoktu. İnsanlar web sayfalarını not defterine yazdı. Web sayfaları için boru hatları oluşturmak diye bir şey yoktu.

Bahsettiğiniz dezavantajlar, o zamanlar gerçekten dikkate alınmadı. Küçük komut dosyaları için tasarlandığından, metin biçiminin ek yükü tamamen önemsizdi.

18
JacquesB

Veri kullanımı aslında bir sorun değildir.

Vücuttaki varsayımlara cevap vermek için (harika Eric Lippert'in yanıtı asıl soruların oldukça iyi ele alındığı görülüyor):

İster veri büyüklüklerinden isterse bant genişliğinden bahsediyor olun, Google-Fu'm, Javascript'in aslında "terabaytlarca veri israf ettiğini" (ne anlama gelirse) öneren herhangi bir araştırmayı ortaya çıkaramadı.

Sorularınızın geri kalanına gelince, birçok şeyde, "bu hangi sorunlara neden olacak?" Diye sormak daha az yararlıdır. "bunun ne faydalar yaratacağını?".

1
sp88