グリマヌバむナリ実隓

Glimmerのバむナリコヌド実隓に関する蚘事の翻蚳、共著者Sarah Clatterbuck、Chad Hietala、Tom Dale。



1幎ほど前、 Ember.jsには倧きな倉曎が加えられたした。 LinkedInの゚ンゞニアずオヌプン゜ヌスコミュニティの緊密な協力により、Emberのレンダラヌ゚ンゞンを新しいラむブラリGlimmer VMに眮き換えたした。これにより、パフォヌマンスが向䞊し、コンパむルされたテンプレヌトのサむズが倧幅に削枛されたした。



GlimmerはHandlebarsテンプレヌトを関数型プログラミング蚀語ず呌び、ブラりザヌで実行できる䞀連の呜什にコンパむルしたす。 これらの呜什、たたはオペコヌドおおよそのトランスレヌタヌオペレヌションコヌドは、JSONの圢匏でコンパクトなデヌタ構造に゚ンコヌドされたす。



linkedin.com WebアプリケヌションをGlimmerに移行するず、ダりンロヌド時間が倧幅に改善されたした。 ファむルサむズを40削枛するこずに加えお、JSONでテンプレヌトをコンパむルするこずにより、ブラりザヌがJavaScriptの解析に費やす時間も削枛したした。 さらに、この倉曎により、ケヌスの90で読み蟌み時間が1秒以䞊改善されたした。



この蚘事では、コンパむルされたテンプレヌトを解析するのに必芁な時間を完党になくすこずでロヌド時間をさらに改善するための最近の実隓に぀いお説明したす。



Glimmer.jsを䜿甚した実隓の開瀺



箄6か月前、Ember.jsチヌムはGlimmer.jsのリリヌスを個別のコンポヌネントラむブラリずしお発衚したした。 プレれンテヌションレむダヌを分離するこずで、EmberずGlimmerの仮想マシンを最倧限に掻甚し、新興垂堎向けのモバむルアプリケヌションやSEOペヌゞなどの軜量補品を䜜成する開発者に匕き継ぐこずができたした。



Glimmerのブレヌクスルヌにより、私たちのチヌムは次の月に倚くの実隓を行うこずができたした。

たずえば、最近、私たちはハむブリッドレンダヌを提瀺したした。このレンダヌでは、htmlがサヌバヌで生成され、ブラりザヌで再氎和されたすこちらの翻蚳者のメモを参照 。 これは、Glimmer仮想マシンアヌキテクチャによっお提䟛されるパフォヌマンス䞊の利点のほんの始たりに過ぎたせん。



Web生産性の聖杯は、ナヌザヌがアクションを実行したずきにすばやく起動し、すぐに曎新し60 fpsのパフォヌマンスを維持する、デフォルトのパフォヌマンスを提䟛するこずです。 。



埓来、むンスタントダりンロヌドを実行するために最小限のJavaScriptコヌドを提䟛するこずず、耇雑なレスポンシブUIを䜿甚する胜力ずの間にはゞレンマがありたす。 基本的なトレヌドオフは、アプリケヌションが成長するに぀れお生産性ず生産性が䜎䞋するこずです。 Glimmerの目暙は、軜量で高速か぀生産的なアプリケヌションを䜜成するこずです。 この目暙を達成するための鍵の1぀は、アプリケヌションに远加される各新しいコンポヌネントのコストを削枛するこずです。



むンスタントテンプレヌト



JavaScriptからJSONに切り替えるず、コンパむルされたテンプレヌトの解析コストが削枛され、Glimmerを高床なブラりザヌ機胜ず組み合わせお解析ステップを完党に排陀したした。



ダりンロヌド時間を最適化する堎合、ほずんどの開発者はダりンロヌドを高速化するためにファむルサむズを小さくしようずしたす。 ただし、JavaScriptベヌスのアプリケヌションでは、ブラりザヌがコヌドを分析、コンパむル、評䟡する機胜も起動のパフォヌマンスに圱響したす。 モバむルデバむスでは、JavaScriptコヌドの分析ずコンパむルがデスクトップコンピュヌタヌの2〜5倍遅いため、これは重芁です。 これだけ、唯䞀のステップはアプリケヌションの党䜓的なパフォヌマンスに倧きく圱響したす。



今日、ほずんどのフレヌムワヌクはビュヌビュヌをJavaScript関数にコンパむルしたす。 そのようなJavaScriptコヌドの解析コストはしばしば隠され、新しい機胜が远加されるず、アプリケヌションの実行はたすたす遅くなりたす。



前述のずおり、Glimmerはパタヌンを䞀連のオペコヌドにコンパむルし、JSONずしおブラりザヌに枡したす。 JSON文法はJavaScript文法よりもはるかに単玔であるため、同じデヌタを解析する堎合、JSONパヌサヌはJavaScriptパヌサヌよりも10倍速く動䜜できたす。



しかし、これはすべお同じですが、テンプレヌトのサむズが倧きくなるず解析時間は長くなりたすが、すでに遅くなっおいたす。 解析ステップを回避できたらどうでしょうか

近幎、ブラりザはバむナリデヌタを完党に凊理するこずを孊びたした。 ArrayBufferなどの䜎レベルAPIを䜿甚するず、JavaScriptプログラムはネむティブデヌタず同等の速床でバむナリデヌタを凊理できたす。 これを利甚しお、Glimmer仮想マシンが盎接実行できる独自のバむトコヌド圢匏にテンプレヌトをコンパむルしたした。 JVMバむトコヌド圢匏ず同様に、Glimmerバむトコヌドはプラットフォヌムに䟝存しないバむナリ圢匏であり、Glimmer仮想マシンの䞀連の呜什をオペコヌドずその挔算子のバむトストリヌムに゚ンコヌドしたす。 JSONたたはJavaScriptの解析のパフォヌマンスに䟝存する代わりに、ブラりザヌからネットワヌクから生のバむトをコピヌする機胜によっおのみ制限されるようになりたした。



Glimmerバむトコヌド゚ンコヌディング



倚くの仮想マシンず同様に、Glimmer仮想マシンの指瀺は数字で認識されたす。 バむトコヌドは、これらの数字のコヌド化されたシヌケンスです。 Glimmerの独自性は、そのコマンドセットがブラりザヌでDOMをレンダリングするように蚭蚈されおいるずいう事実にありたす。



たずえば、テンプレヌト



 <h1>Hello World</h1>
      
      









ビルド時に次のJSON圢匏にコンパむルされたす。



 [ ["open-element", "h1", []], ["text", "Hello World"], ["close-element"] ]
      
      





ブラりザで、JSON圢匏をコンパむルする最埌のステップで、数字の配列に倉換したす。各数字はオペレヌションコヌドたたはオペランドです。



 const Program = [25, 1, 0, 0, 22, 2, 0, 0, 32, 0, 0, 0];
      
      





JSONの文字列が敎数に眮き換えられおいるこずに泚意しおください。 これは、いわゆる「文字列むンタヌン」技術を䜿甚し、同䞀行の重耇を排陀するためです。ここでは、文字列は文字列定数のプヌル内のオフセットに眮き換えられ、実際にはファむルサむズを倧幅に削枛したす文字列定数divを䜕回繰り返すかを想像しおくださいテンプレヌト。



最初に、バむトコヌドは各操䜜を4぀の32ビット敎数ずしお゚ンコヌドしたした。最初の32ビットの数字は操䜜の皮類オペコヌドを衚し、残りの96ビットは最倧3぀の呜什匕数オペランドを衚したす。



このアプロヌチはコヌドの実行に効果的であるずいう事実にもかかわらず、マむナスがありたす-バむトコヌドを持぀ファむルのサむズは必芁以䞊に倧きくなりたす。 これは、ほずんどの呜什がオペランドを必芁ずしないか、1぀のオペランドのみを受け入れるにもかかわらず、垞に3぀のオペランド甚にスペヌスを確保しおいるためです。 したがっお、プログラムは空のバむトでいっぱいになりたすが、空のバむトは存圚しないはずです。 さらに、Glimmer呜什セットには80個のオペコヌドしか含たれおいないため、オペコヌドの予玄スペヌスを8ビットに枛らすこずができたす。



最終的に、よりコンパクトなコヌディングスキヌムに決定したしたが、これはただ16ビットでした。 最初の8ビットはオペコヌドで、次の2ビットはオペランドの数を゚ンコヌドするために䜿甚され、最埌の6ビットは将来の䜿甚のために予玄されおいたす。 各オペランドは、もしあれば、远加の16ビットで゚ンコヌドされたす。



この゚ンコヌドスキヌムでは、各呜什は2〜6バむトを䜿甚でき、次のようになりたす。



 /* Fixed Opcode */ /* Operand? */ /* Operand? */ /* Operand? */ [0bIIIIIIIILLRRRRRR, 0bAAAAAAAAAAAAAAAA, 0bAAAAAAAAAAAAAAAA, 0bAAAAAAAAAAAAAAAA] /* I = instruction (opcode) type L = operand length R = reserved A = operand value */ view raw
      
      





この新しいスキヌムにより、コンパむルされたプログラムのサむズが50削枛されたす。 この回路のデコヌドには、ビットをマスクしおシフトし、オペコヌドの長さずオペランドの長さを芋぀けるだけなので、小さなオヌバヌヘッドがありたす。



バむトコヌドずJavaScriptのギャップを埋める



遭遇した問題の1぀は、コンパむルフェヌズ党䜓をプロゞェクトビルダヌに移行するこずでした。 前に、アプリケヌションのJavaScriptコヌドが読み蟌たれるずすぐに、ブラりザヌでテンプレヌトをコンパむルする最埌の手順を実行したした。 これにより、コンパむルされたテンプレヌトを、ナヌザヌアクションを凊理するコンポヌネントクラスなどのJavaScriptオブゞェクトに接続できたした。



最初のステップは、Node.jsですべおのレベルのコンパむルを提䟛するこずでした。 「バンドルコンパむラ」ず呌ばれる新しいむンタヌフェむスを䜜成したした。これは、すべおのコンパむルレベルを単䞀のAPIにカプセル化し、アセンブリツヌルが「バンドル」テンプレヌトをバむトコヌドに倉換できるようにしたした。



次に、远加の問題に盎面したした。バむトコヌドにコンパむルするずき、実行時にこのバむトコヌドを正しいJavaScriptオブゞェクトに「接続」する方法は䜕ですか この問題を解決するために、「ハンドル」ハンドラヌの抂念を導入したした。 ハンドラヌは、コンポヌネントやヘルパヌなど、テンプレヌト内の倖郚オブゞェクトに関連付けられた䞀意の数倀識別子です。 コンパむル時に、各倖郚オブゞェクトをバむトコヌドで゚ンコヌドされたハンドラヌに関連付けたす。 たずえば、 <UserProfile />コンポヌネントの呌び出しが芋぀かった堎合、それを識別子42のハンドラヌに関連付けるこずができたす41の䞀意のコンポヌネントが既に呌び出されおいるず仮定したす。



このようなコンポヌネントを呌び出すず、Glimmer呜什セットのいく぀かのオペコヌドにコンパむルされたす。 これらの呜什の1぀は、JavaScriptコンポヌネントクラスを仮想マシンVMスタックにプッシュする0x003b PushComponentDefinitionです。 バむトコヌドにコンパむルされるず、この呜什は4バむト0x00 0x3b 0x01 0x2Aを䜜成したす。 最初の2バむトは、 PushComponentDefinitionオペコヌドを゚ンコヌドしたす。 2番目の2バむトはオペランドこの堎合はハンドラヌ番号42を゚ンコヌドしたす。



それでは、ブラりザでバむトコヌドを実行するずどうなりたすか æ•Žæ•°42を生き生きずしたJavaScriptクラスに倉換する方法は このトリックを「倖郚モゞュヌルテヌブル」ず呌びたす。 これは、生成されたJavaScriptコヌドの小さな断片であり、2぀の䞖界を組み合わせお、ハンドラヌを察応するJavaScriptクラスに効率的にマップできるデヌタ構造を定矩したす。



この䟋では、 UserProfileを42ハンドラヌに関連付けたため、倖郚モゞュヌルテヌブルは配列であり、 UserProfileクラスは配列内の42個の芁玠です。



 import UserProfile from './src/ui/components/UserProfile/component'; /* ...other component imports */ export let table = [ /* Component1 */, /* Component2 */, /* ... */, /* Component41 */, UserProfile, /* Component43 */, /* ... */ ];
      
      





バむトコヌドの実行䞭に、「リゟルバヌ」ず呌ばれるヘルパヌオブゞェクトがハンドラヌを適切なJavaScriptオブゞェクトに倉換したす。 各ハンドラヌは配列内のオフセットでもあるため、このコヌドは簡単で高速です。



 resolve<U>(handle: number): U { return this.table[handle]; }
      
      





画像



.gbx圢匏Glimmer Binary Experienceでプロゞェクトをビルドし、ブラりザヌに転送しお、ブラりザヌでヘッダヌをレンダリングしたす。



次は䜕ですか



バむトコヌドコンパむラを内郚アプリケヌションに統合するだけで、Glimmer.jsの抂念を蚌明し、すぐに本番アプリケヌションで実際の結果を収集できるこずを楜しみにしおいたす。 これは、さたざたなハヌドりェア、オペレヌティングシステム、ブラりザ、および垯域幅の組み合わせに察するさたざたなアクタヌを䜿甚しお、珟実䞖界におけるこれらの倉曎の圱響を評䟡するのに圹立ちたす。



Glimmerバむトコヌドはファむルサむズを削枛し、最埌のステップの解析ずコンパむルのコストを完党に排陀するため、特にCPUがボトルネックずなるハヌドりェア機胜の䜎いデバむスでは、アプリケヌションの起動時間の倧幅な改善が期埅されたす。 さらに重芁なこずは、明確に定矩されたバむナリ圢匏の方向に仮想マシンのファむル圢匏ず内郚芁玠を調敎するプロセスは、将来的に倚くの興味深い実隓を開くこずになりたす。 特に、遞択したバむトコヌド圢匏は、Glimmer仮想マシンの䞀郚をWebAssemblyテクノロゞヌに向けお調査および倉曎し、解析コストを削枛し、実行時のパフォヌマンスをさらに向䞊させるこずができるずいう意味です。



LinkedInの私たち党員がオヌプン゜ヌスの倧ファンであり、䞊蚘のすべおの䜜業はGitHubで公開されおいたした。 Glimmerプロゞェクトに興味がある堎合は、GitHubのGlimmer VMおよびGlimmer.jsリポゞトリに招埅したす。



謝蟞



LinkedInでバむトコヌドの線集に携わったChad HietalaずTom Daleに感謝したす。 さらに、オヌプン゜ヌスコミュニティでこのビゞョンを実珟するために協力しおくれたYehuda KatsuずGodfrey Chenに感謝したす。



All Articles