ブログ

  • CSS Grid Layout入門Part 2は、グリッド線を“座標”として使う記事だった

    CSS Grid Layout入門Part 2は、グリッド線を“座標”として使う記事だった

    Mozilla Hacksの「An Introduction to CSS Grid Layout: Part 2」を読みました。前回紹介したPart 1が「グリッドを作る」記事だったのに対し、Part 2は「作ったグリッド上に要素をどう配置するか」を扱う記事です。

    CSS Gridは、単に列と行を作るだけでなく、要素をどの行・列に置くかをCSSで明示できるところが強みです。この記事では、grid lineの番号、短縮記法、template areas、名前付きラインという複数の配置方法が順番に紹介されています。

    記事の要点

    • Grid itemは通常、自動配置で順番に並びますが、より細かく制御したい場合はgrid lineを使って配置できます。
    • grid lineは、左から右、上から下へ番号が振られます。右から左の言語では向きが変わることにも触れられています。
    • grid-row-startgrid-row-endgrid-column-startgrid-column-end を使うと、要素の開始線と終了線を指定できます。
    • grid-row: 2 / 3;grid-column: 2 / 3; のような短縮記法も使えます。
    • ヘッダー、サイドバー、コンテンツ、フッターのような基本レイアウトを、grid line番号で手動配置する例が紹介されています。
    • grid-template-areas を使うと、レイアウトを文字列の形で視覚的に定義できます。
    • さらにgrid line自体に名前を付けると、番号ではなく main-startcontent-end のような意味のある名前で配置できます。
    • Firefox DevToolsでは、line numbers、area names、grid overlayの色変更など、Gridの構造を見えるようにする支援が紹介されています。

    リンク先も見てわかったこと

    前編のPart 1は、display: gridgrid-template-columnsgrid-template-rowsfrrepeat() を扱っていました。Part 2はその上に、配置のための語彙を積み上げています。この2本を合わせると、CSS Gridの最初の学習単位としてかなりまとまっています。

    MDNのCSS Grid Layoutは、Grid全体の仕様や実用例を確認するための入口です。Part 2で出てくるline番号、template areas、named linesは、MDN側でさらに深く確認できます。

    記事中ではFirefox Developer Editionも案内されています。当時の文脈では、Firefox Quantum / Developer EditionのDevToolsがGridの学習支援としてかなり前面に出ています。CSS Gridはコードだけで理解するより、overlayで線や領域名を見ながら学ぶ方が早い機能だとわかります。

    また、記事中のCodePen例は、grid lineでの配置、基本レイアウト、template areas、named linesを段階的に試すための参照として挙げられています。こちらは今回の取得ではCodePen側が403を返したため本文の埋め込み説明までの確認ですが、記事の構成上は実例を触りながら理解するための補助になっています。

    気づき

    今回の気づきは、CSS Gridの配置指定は「見た目を無理やり動かす」ものではなく、レイアウト上の座標系をCSSに持ち込むものだという点です。grid line番号を使うと、要素を「2行目から3行目、2列目から3列目」のように座標で置けます。template areasを使うと、ヘッダーやフッターといった意味のある領域として置けます。named linesを使うと、線そのものに設計上の名前を付けられます。

    つまりCSS Gridは、レイアウトを目視調整の集まりから、構造として読めるものに変えます。小さなサンプルでは番号指定で十分ですが、実際の画面が大きくなるほど、template areasやnamed linesのような「意味を残す書き方」が効いてきます。これはコンポーネントやデザインシステムを扱う時にも大事な視点だと思いました。

    読むとよさそうな人

    • CSS Gridで要素を任意の位置に置く基本を学びたい人
    • grid-rowgrid-columngrid-template-areas の違いを整理したい人
    • Firefox DevToolsのGrid Inspectorを、学習やデバッグにどう使うか知りたい人

    参照した記事

  • CSS Grid Layout入門Part 1は、二次元レイアウトを“標準のCSS”へ戻した記事だった

    CSS Grid Layout入門Part 1は、二次元レイアウトを“標準のCSS”へ戻した記事だった

    Mozilla Hacksの「An Introduction to CSS Grid Layout: Part 1」を読みました。CSS Grid Layoutを初めて触る人向けに、用語、グリッド作成、行列定義、gap、frrepeat() を順に説明する入門記事です。

    先に紹介したSubgridの記事はCSS Grid Level 2の話でしたが、今回の記事はその土台になるCSS Grid Layoutそのものの入口です。Subgridを理解する前に、grid line、grid cell、grid area、grid trackといった基本語彙を押さえる記事として読めます。

    記事の要点

    • CSS Grid Layoutは、CSS標準として提供される二次元グリッドシステムです。
    • float、table、CSSフレームワーク、各種ハックに頼らず、行と列をCSSで明示できます。
    • 記事では、grid line、grid cell、grid area、grid track、grid row、grid column、gutter、grid container、grid itemといった用語を整理しています。
    • グリッドは、対象要素に display: grid を指定して作ります。
    • grid-template-columnsgrid-template-rows で、明示的な列と行のサイズを定義します。
    • 行と列の間隔は、当時の記事では grid-gap として説明されています。
    • fr は利用可能な空間の割合を表す単位で、固定幅だけではない柔軟なグリッドを作れます。
    • repeat() 記法を使うと、1fr 1fr 1fr のような繰り返しを短く書けます。

    リンク先も見てわかったこと

    記事内で案内されているMDNのCSS Grid Layoutは、Grid全体を体系的に確認する入口です。さらにimplicit gridとexplicit gridの説明を見ると、記事で少し触れられている「定義した外に配置された要素は暗黙的なグリッドを作る」という点が補えます。

    writing-modeのMDNページも参照しました。記事中では、縦書きなどでは行と列の向きの感じ方が変わることに触れられています。Gridは単なる横書き前提のレイアウト機能ではなく、書字方向と組み合わせて考える必要があります。

    続きのPart 2では、grid lineの番号を使って要素を配置する方法、grid-rowgrid-column の短縮記法、名前付きラインを使う方法が扱われています。Part 1が「グリッドを作る」記事なら、Part 2は「グリッド上に意図して置く」記事です。

    気づき

    今回の気づきは、CSS Gridの重要さは「複雑なレイアウトが作れる」ことだけではなく、「レイアウトの意図をCSSの言葉で直接書ける」ことにあるという点です。以前は、列を作るためにfloatを使ったり、表ではないものをtable的に扱ったり、フレームワークのグリッドクラスに依存したりする場面が多くありました。

    CSS Gridでは、列数、行数、隙間、余白の配分、固定幅と可変幅の混在を、レイアウトのためのプロパティとしてそのまま書けます。これは単にコード量を減らすだけでなく、「この画面はどういう二次元構造なのか」をCSS上で読み取れるようにする変化です。

    SubgridやInteropの記事を読んだ後にこの入門記事へ戻ると、CSS GridがWeb標準として定着した意味が見えやすくなります。まず基本のGridが標準機能として使えるようになり、その後にSubgridのような「ネストした部品とページ全体の整列をつなぐ機能」が必要になった、という流れです。

    読むとよさそうな人

    • CSS Gridの用語を最初から整理したい人
    • display: gridgrid-template-columnsfrrepeat() の役割を押さえたい人
    • SubgridやCSS Grid Level 2の前に、CSS Grid Layoutの土台を確認したい人

    参照した記事

  • Subgridは、ネストした部品を親グリッドへ戻すCSS Gridの足りない一手だった

    Subgridは、ネストした部品を親グリッドへ戻すCSS Gridの足りない一手だった

    Mozilla Hacksの「CSS Grid Level 2 – subgrid is coming to Firefox」を読みました。2019年の記事で、公開当時はsubgridがまだどのブラウザにも正式出荷されておらず、Firefox Nightlyでテストできるようになった段階として紹介されています。

    Subgridは、CSS Gridでネストした要素を親グリッドの行や列に参加させるための仕組みです。通常のネストしたグリッドは内側だけで独立してトラックを持ちますが、subgridを使うと親グリッドのトラックサイズやラインを引き継げます。

    記事の要点

    • Subgridは、grid-template-columnsgrid-template-rows に指定する新しいキーワード値として説明されています。
    • 通常は 200px max-content 1fr のようにトラックサイズを列挙しますが、subgridでは grid-template-columns: subgrid; のように親のトラックを使います。
    • 親グリッドの直接の子でない要素も、親グリッドの列や行に沿って配置しやすくなります。
    • カードレイアウトでは、カード内のヘッダーやフッターの高さを行としてそろえる用途が紹介されています。
    • 12カラムレイアウトのような設計でも、深くネストされた部品を親のカラム体系に参加させられます。
    • 繰り返し要素の数が不明な場合にも、親側の明示的なグリッドを保ちながら、内側の繰り返しを扱うパターンが紹介されています。
    • Firefox DevToolsでは、複数グリッドのハイライトやsubgridバッジなど、複雑なグリッド構造を把握するための機能も整備されていました。

    リンク先も見てわかったこと

    記事内から参照されているMDNのCSS Grid LayoutBasic concepts of grid layoutは、Grid全体の前提を確認する入口になります。SubgridはGridを知らない状態で読むより、まずトラック、ライン、明示的グリッド、暗黙的グリッドの考え方を押さえた方が理解しやすい機能です。

    MDNのSubgridページと、Grid by Exampleの例は、記事内の説明を実際のコードパターンとして追うのに向いています。カード内の要素をそろえる例や、親グリッドのラインを利用する例は、文章だけよりも視覚的に見る方が理解しやすいです。

    また、BugzillaのDevTools関連チケットでは、subgridを選択したときに親グリッドも半透明でハイライトする改善が追跡されています。SubgridはCSSの機能そのものだけでなく、DevToolsで構造を見えるようにすることも実用上かなり重要だったことがわかります。

    気づき

    今回の気づきは、subgridは単なる「ネストしたグリッドの便利機能」ではなく、コンポーネント化とページ全体の整列を両立させるための機能だという点です。部品をコンポーネントとして分けるほど、DOM上は親グリッドから遠くなります。しかしデザイン上は、見出し、本文、フッター、ナビゲーション、カード内要素を同じ列や行にそろえたい場面があります。

    Subgridは、そのずれをCSS側で吸収します。内側の部品を完全に独立した小さなレイアウトとして閉じ込めるのではなく、必要なときだけ親のトラック体系へ戻せる。これは、HTML構造を無理にフラットにしたり、寸法を重複定義したりする代わりになる実用的な逃げ道です。

    もう一つ印象的なのは、DevTools対応が記事の中で大きく扱われていることです。レイアウト機能は、仕様として存在するだけでは使いこなしにくい。親と子のグリッドがどう重なっているかを見える化できて初めて、開発者が安心して使える機能になります。

    読むとよさそうな人

    • CSS Gridを使ったカードレイアウトや12カラムレイアウトで、内側の要素がそろわず困ったことがある人
    • Subgridが通常のネストしたGridと何が違うのか知りたい人
    • Firefox DevToolsのGrid Inspectorが、レイアウト理解にどう役立つか知りたい人

    参照した記事

  • Firefox 105の安定性改善は、OOM時に“少し待ってやり直す”判断だった

    Firefox 105の安定性改善は、OOM時に“少し待ってやり直す”判断だった

    Mozilla Hacksの「Improving Firefox stability with this one weird trick」を読みました。タイトルは軽いですが、中身はFirefoxのWindows版で多かったout-of-memoryクラッシュをどう減らしたかという、かなり実務的な安定性改善の話です。

    記事の中心は、Firefox 105で導入された「メモリ確保に失敗したらすぐクラッシュせず、少し待ってから再試行する」という変更です。結果として、WindowsでのOOMブラウザクラッシュが70%超減ったとされています。

    記事の要点

    • Firefoxでは、Windows上のout-of-memoryが大きなクラッシュ要因になっていました。
    • Windowsにはcommit spaceという制約があり、物理メモリが残っていても、コミット可能な容量が尽きるとメモリ確保に失敗します。
    • commit spaceは、物理メモリとswap fileの合計に近い上限として扱われます。
    • グラフィックスドライバなど、Firefoxが直接制御しにくい領域でもcommitが使われるため、Firefox側から原因を完全に取り除くのは難しい状況でした。
    • Windowsはswap fileを自動拡張することがあるため、Firefoxはメモリ確保失敗時にすぐクラッシュせず、少し待ってから再試行するようにしました。
    • この待ち時間は一時的なjankを生む可能性がありますが、ブラウザ全体が落ちるよりは軽い被害で済みます。
    • Firefoxは複数プロセス構成なので、メインプロセスを少し粘らせている間に、別プロセスが落ちてメモリが空き、ブラウザ全体のクラッシュを避けられる場合もあります。

    リンク先も見てわかったこと

    Bugzillaの「Delay crashing the main process when running out of memory」を見ると、この改善は単なる説明記事ではなく、実際のバグ追跡として進められていたことがわかります。メインプロセスを即座に落とさず、短く待ってから再試行するという実装方針が、安定性改善の中心になっています。

    関連する子プロセス側のOOMクラッシュ遅延や、物理メモリ不足とcommit space不足を分けて検出する取り組みも参照されています。記事後半で触れられている通り、ブラウザクラッシュを減らすだけでなく、タブクラッシュや低メモリ時の挙動をさらに改善する方向へ続いています。

    また、本文ではメモリ消費の監視やリーク検出にも触れられています。リンク先のfuite紹介記事はWebアプリ側のメモリリーク検出ツールの話で、ブラウザ本体のメモリ対策とは別の層ですが、低メモリ問題がプラットフォーム側とアプリ側の両方にまたがることを示しています。

    気づき

    今回の気づきは、安定性改善は必ずしも「根本原因をすべて消す」形だけではないという点です。理想はメモリを無駄に使わず、ドライバや外部コンポーネントのcommitも最小化することですが、現実のブラウザはOS、GPU、ドライバ、Webコンテンツの上で動いています。制御できない要因がある中では、「失敗した瞬間に落ちる」のではなく、「OS側の回復余地を少し待つ」だけで大きな効果が出ることがあります。

    これはかなり地味ですが、ユーザー体験としては重要です。一瞬固まることは不快ですが、ブラウザ全体が落ちるよりはずっとよい。しかもFirefoxのマルチプロセス構成では、最悪の場合でもタブやGPUプロセスの再起動で済む可能性があります。高機能化だけでなく、壊れ方を小さくする設計が安定性を支えていることがよくわかる記事でした。

    読むとよさそうな人

    • Firefoxのクラッシュ削減や安定性改善に興味がある人
    • Windowsのcommit spaceとOOMの関係をざっくり理解したい人
    • ブラウザのマルチプロセス設計が、クラッシュ時の被害をどう小さくするか知りたい人

    参照した記事

  • Interop 2022の発表は、互換性改善を“測れる領域”と“調べる領域”に分けた

    Interop 2022の発表は、互換性改善を“測れる領域”と“調べる領域”に分けた

    Mozilla Hacksの「Announcing Interop 2022」を読みました。Interop 2022は、Apple、Bocoup、Google、Igalia、Microsoft、Mozillaが参加して、Webプラットフォームの互換性問題を重点的に改善するために始まった取り組みです。

    前回紹介したInterop 2022の成果記事は「1年後に何が改善されたか」を見る記事でした。今回の発表記事は、その前に「どの問題を、どう選び、どう測ることにしたのか」を説明しています。

    記事の要点

    • Webは単一実装ではなく標準で定義されるため、ブラウザ間の実装差を継続的に減らす必要があります。
    • Interop 2022は、Web開発者のフィードバックと、webcompat.comなどに寄せられる実ユーザーの互換性問題をもとに対象領域を選びました。
    • 問題は大きく2種類に分けられます。仕様や期待動作が比較的明確でテストできる問題と、仕様や実際にサイトが依存している挙動を調査する必要がある問題です。
    • 前者は「focus areas」として、web-platform-testsの通過率で進捗を測ります。
    • 後者は「investigate areas」として、まず何を標準化し、何をテスト可能にするべきかを調べます。
    • 2022年のfocus areasには、Cascade Layers、Color Spaces and Functions、Containment、Dialog Element、Forms、Scrolling、Subgrid、Typography and Encodings、Viewport Units、Web Compatが含まれました。
    • Compat 2021からは、Aspect Ratio、Flexbox、Grid、Sticky Positioning、Transformsも引き継がれました。
    • 調査領域には、Editing/contentEditable/execCommand、Pointer and Mouse Events、Viewport Measurementが選ばれました。

    リンク先も見てわかったこと

    wpt.fyiのInterop 2022ダッシュボードは、ブラウザごとの進捗を公開スコアとして見えるようにする場所です。単なるロードマップではなく、実装差がどれだけ縮まったかを継続的に追える仕組みになっています。

    web-platform-testsのドキュメントを見ると、このテストスイートはブラウザ横断で同じテストを走らせ、Web作者が「この機能はブラウザをまたいで頼れる」と判断できる状態を目指していることがわかります。Interop 2022は、この既存基盤を使って重点領域を測定可能にした取り組みだと見られます。

    記事内のMDN Web DNA Reportwebcompat.comへのリンクも重要です。Interop 2022は、仕様書だけを起点にした計画ではなく、開発者が困っている点と、実際に壊れているサイトの報告を選定材料にしています。

    パートナー発表として、WebKitの記事Igaliaの記事も参照しました。どちらも、Interop 2022が15領域を対象にした複数組織の共同作業であること、そしてダッシュボードで進捗を追う点を強調しています。GoogleのInterop 2022記事やMicrosoft Edge Blogの発表記事も、同じ取り組みを各社側から説明するリンクとして確認しました。

    気づき

    今回の気づきは、Interop 2022の設計でいちばん強いのは「測れる問題」と「まだ測れない問題」を最初から分けたことです。すべてをテスト通過率に押し込もうとすると、仕様が曖昧な領域やモバイル特有の挙動は置き去りになります。一方で、調査ばかりにすると実装改善の進捗が見えません。

    focus areasとinvestigate areasを分けることで、Interop 2022は短期的に直せる互換性問題と、将来テスト可能にするための下準備を同じプロジェクト内に置けました。これはWeb標準の実務にかなり合った設計だと思います。既に測れるものは測って直し、まだ測れないものは調べて測れる形に近づける。この順序があるから、Interopは単年のキャンペーンではなく、2023、2024、2025以降へ続く改善サイクルになったのだと感じました。

    読むとよさそうな人

    • Interopプロジェクトの出発点を知りたい人
    • Web互換性改善がどのように対象選定されるのか知りたい人
    • web-platform-testsやwpt.fyiが、ブラウザ実装の改善にどう使われるのかを把握したい人

    参照した記事

  • Interop 2022の成果は、互換性改善を“測れる共同作業”にしたことだった

    Interop 2022の成果は、互換性改善を“測れる共同作業”にしたことだった

    Mozilla Hacksの「Interop 2022: Outcomes」を読みました。Interop 2022は、Apple、Bocoup、Google、Igalia、Microsoft、Mozillaが参加して、Webプラットフォームの実装差を減らすために進められた共同プロジェクトです。

    すでにこのブログではInterop 2023の記事も紹介していますが、今回の記事はその前提になる「最初の年に何が起きたか」を振り返る内容です。

    記事の要点

    • Interop 2022の重点領域では、各ブラウザがテスト通過率を大きく改善し、全ブラウザが90%を超える状態になりました。
    • Viewport Unitsは、全ブラウザ0%から全ブラウザ100%へ到達した代表例として紹介されています。
    • Firefoxは、Firefox 95時点の約60%から、2022年12月リリースのFirefox 108で90%へ伸びました。
    • CSS Containmentは、Firefox 103での改善を含めて、既存機能の品質改善として取り上げられています。
    • Cascade LayersはFirefox 97、Chrome 99、Safari 15.4で相次いで出荷され、Interopが新機能を実用水準へ押し上げる例になりました。
    • Web Compatibility重点領域では、実際のサイト破損につながっていた既存機能の差分も改善対象になっています。

    リンク先も見てわかったこと

    元になった「Announcing Interop 2022」では、Interop 2022が「focus areas」と「investigate areas」を分けていたことが説明されています。前者はweb-platform-testsで測れる領域、後者は仕様やテスト基盤から整理しなければならない領域です。この分け方が、成果記事を読むうえでかなり重要でした。

    wpt.fyiのInterop 2022ダッシュボードは、単なる発表ではなく、各エンジンの進捗を公開指標として追える場所です。Web互換性の改善を「各社ががんばっています」という話で終わらせず、テスト結果として見える形にした点がInteropの特徴です。

    また、Google側のInterop 2022 end of year updateでは、Cascade Layers、dialog要素、Subgrid、Viewport Units、Color 4など、実際に開発者が使う機能単位で成果が整理されていました。WebKitのSafari 16.2の記事でも、Safari Technology PreviewのInteropスコアや、Font Features、Last Baseline、CSS修正などが触れられています。Mozillaの記事単体よりも、ブラウザ横断の取り組みだったことが見えやすくなります。

    気づき

    今回の気づきは、Interop 2022の価値は「特定の新機能を出したこと」だけではなく、「ブラウザ互換性改善を、共有されたテストと公開ダッシュボードで進める作業にしたこと」だという点です。Web標準は合意されていても、実装差が残れば開発者は回避策を書き続けることになります。Interopは、その差分を抽象的な不満ではなく、合意した重点領域とテスト結果に変換しました。

    特に面白いのは、新機能だけでなくWeb Compatibility領域が含まれているところです。新しいAPIの出荷は目立ちますが、実際のサイトを壊している小さな差分を直すことも、Webを使いやすくするうえでは同じくらい重要です。Interop 2022は、華やかな新機能と地味な互換性修正を同じ指標の中に並べた点で、かなり実務的な取り組みだったと感じました。

    読むとよさそうな人

    • Interop 2023以降の背景を知りたい人
    • Web互換性改善がどのように測定されているかを知りたい人
    • CSSやWeb APIの実装差が、ブラウザ横断でどう縮められているかを知りたい人

    参照した記事

  • llamafileの最初の狙いは、ローカルLLMを“配布できる実行ファイル”にすることだった

    llamafileの最初の狙いは、ローカルLLMを“配布できる実行ファイル”にすることだった

    Mozilla Hacksの「Introducing llamafile」を読みました。2023年11月に公開された、llamafileの最初の発表記事です。すでに後続の進捗記事やv0.8.14の記事もありますが、この初回記事は「何を簡単にしたかったのか」が短くまとまっています。

    llamafileは、LLMの重みを実行ファイルとして配布できるようにするプロジェクトです。記事では、たとえばGGUF形式の数GB級の重みを、複数OSでインストールなしに動くバイナリへ変換できる、と説明されています。

    記事の要点

    • llamafileは、LLMの重みを単一の実行ファイルとして扱えるようにする。
    • これにより、モデル配布と実行の手順を大きく減らせる。
    • モデルや重み形式が変化しても、特定の重みを再現可能な形で残しやすくなる。
    • 中核には、ローカルLLM実行で広く使われるllama.cppと、Cプログラムを複数OS・複数アーキテクチャで動かすCosmopolitan Libcがある。
    • 初回リリースはMozillaのinnovation groupによるもので、Cosmopolitanの作者であるJustine Tunney氏の協力が大きい。

    リンク先も見てわかったこと

    llamafileのGitHubリポジトリを見ると、現在のREADMEでも「LLMを単一ファイルで配布して実行する」という軸は維持されています。さらに現在はMozilla.ai側のプロジェクトとして整備され、whisperfileのような音声認識系の単一ファイル実行ツールにも広がっています。

    llama.cpp側を見ると、狙いはローカルやクラウド上で、少ないセットアップでLLM推論を動かすことにあります。llamafileはそこへ「配布物としての扱いやすさ」を足している、と見ると位置づけがわかりやすいです。

    もう一方のCosmopolitan Libcは、Cを“build-anywhere run-anywhere”に近づけるための技術です。llamafileの記事が面白いのは、AIモデルの話に見えて、実際には「重いAI環境をどう配布可能なソフトウェア成果物にするか」というパッケージングの話でもあるところです。

    気づき

    今回の気づきは、llamafileが解いている問題は「ローカルAIを速くすること」だけではなく、「ローカルAIを渡せる形にすること」だという点です。モデルの実行環境は、依存ライブラリ、OS差、GPU対応、重み形式、コマンドライン手順などが絡みやすく、動かす前の摩擦が大きい。llamafileはその摩擦を、単一ファイルという古典的で強い配布単位に押し込もうとしています。

    この発想は、ローカルAIを開発者向けの実験環境から、チーム内配布やユーザー配布に近づけるものです。WebAssemblyが「どの環境でも動かしやすい中間形式」を目指したのと少し似ていて、llamafileはLLMの世界で「環境ごとの差を配布時にどこまで吸収するか」に取り組んでいるように見えました。

    読むとよさそうな人

    • llamafileの出発点を短く把握したい人
    • ローカルLLMの配布や再現性に関心がある人
    • llama.cpp、GGUF、Cosmopolitan Libcの関係をざっくり整理したい人

    参照した記事

  • assembly記事は、WebAssemblyを“概念機械の命令”として理解する入口になる

    assembly記事は、WebAssemblyを“概念機械の命令”として理解する入口になる

    Mozilla Hacksの「A crash course in assembly」を読みました。Lin Clark氏によるWebAssembly解説シリーズの第3回で、WebAssemblyそのものに入る前に、assemblyとは何か、コンパイラが高水準言語をどのように機械に近い表現へ落としていくのかを整理する記事です。

    前回のJITコンパイラの記事では、JavaScriptエンジンが実行中の情報を使って最適化する仕組みが扱われていました。今回の記事は、その「最終的に機械が理解する形」とは何かに踏み込みます。

    記事の要点

    • CPUの中には、計算を担うALU、短期的な値を置くレジスタ、長期的な値を置くRAMのような役割分担があります。
    • 機械語の命令は、opcodeのような「何をするか」を示す部分と、どのレジスタを使うかを示す部分などに分かれます。
    • assemblyは、機械語を人間が読みやすくするためのsymbolic machine codeです。
    • ただし「機械語」は1種類ではなく、x86やARMなどアーキテクチャごとに異なります。
    • そのため、C、C++、Rustなどの高水準言語から各CPU向けassemblyへ直接すべて変換しようとすると組み合わせが増えすぎます。
    • そこで多くのコンパイラは、中間表現(IR)を挟みます。フロントエンドが高水準言語をIRへ変換し、バックエンドがIRを対象アーキテクチャ向けのassemblyへ変換します。

    リンク先も見てわかったこと

    シリーズ冒頭の「A cartoon intro to WebAssembly」では、WebAssemblyはJavaScriptの置き換えではなく、JavaScriptと併用される実行形式として説明されていました。今回のassembly記事を挟むと、その説明がより具体的になります。WebAssemblyは「別の言語をブラウザで動かす」だけでなく、「CPUごとの違いを直接ユーザーへ配布しないための中間的な実行形式」として見えてきます。

    さらに次の「Creating and working with WebAssembly modules」を読むと、WebAssemblyはx86やARMのような特定の物理CPU向けassemblyではなく、概念上の機械に向けた形式として説明されています。assembly記事でIRとバックエンドの役割を理解しておくと、WebAssemblyがどの位置に差し込まれるのかがかなり見えやすくなります。

    記事中のRustWebAssemblyへのMozilla Researchリンクは、現在のページ取得では内容を確認しきれませんでしたが、文脈としてはC/C++/Rustのような言語を対象アーキテクチャへ翻訳する話に接続されています。

    気づき

    今回の気づきは、WebAssemblyを理解するには「JavaScriptより速い形式」と見るだけでは足りず、「配布時点では特定CPUに固定しない命令形式」と見る必要があるという点です。assemblyは物理的な機械の都合に近い表現ですが、Webでは実行先のCPUを事前に決められません。だからこそ、WebAssemblyは特定CPUのassemblyではなく、ブラウザが各環境の機械語へ短く橋渡しできる形式として設計されている。

    この見方をすると、IRの話も単なるコンパイラ内部の実装詳細ではなくなります。高水準言語、IR、WebAssembly、実機の機械語という段階を分けることで、開発者、配布形式、ブラウザ、CPUそれぞれの責務が分離されます。WebAssemblyの実用性は、この責務分離のうまさにも支えられているのだと思いました。

    読むとよさそうな人

    • WebAssemblyの前提としてassemblyや機械語の位置づけをつかみたい人
    • opcode、レジスタ、ALU、IRといった用語をざっくり整理したい人
    • なぜWebAssemblyが特定CPU向けのバイナリではないのかを理解したい人

    参照した記事

  • JITコンパイラは、JavaScriptを「通訳」から「観察して最適化する実行系」へ変えた

    JITコンパイラは、JavaScriptを「通訳」から「観察して最適化する実行系」へ変えた

    Mozilla Hacksの「A crash course in just-in-time (JIT) compilers」を読みました。2017年の記事ですが、JavaScriptエンジンがどのように実行中のコードを観察し、必要な部分だけをコンパイルしていくのかを、WebAssembly理解の前提として整理してくれる内容です。

    この記事は、Lin Clark氏によるWebAssembly解説シリーズの第2回です。前回の「A cartoon intro to WebAssembly」では、WebAssemblyがJavaScriptを置き換えるものではなく、同じWebアプリの中で併用される低レベル実行形式として説明されていました。今回のJIT記事は、その比較対象であるJavaScript実行系の複雑さを見せてくれます。

    記事の要点

    • インタプリタはすぐに実行を始められる一方、ループなどでは同じ翻訳作業を繰り返すため効率が落ちます。
    • コンパイラは先に機械が理解しやすい形へ変換するため、実行時は速くなりますが、開始前の準備時間が必要です。
    • JITはその中間にあり、実行しながらコードの利用状況を監視し、よく使われる箇所をコンパイル対象にします。
    • 「warm」な関数にはbaseline compilerが比較的軽いコンパイルを行い、「hot」な関数にはoptimizing compilerがより強い最適化をかけます。
    • ただしJavaScriptは動的型付けなので、最適化は実行時に観察した型やオブジェクト形状への仮定に依存します。仮定が崩れるとdeoptimizationが起き、最適化済みコードを捨てて戻ることがあります。

    リンク先も見てわかったこと

    記事内から参照されている次の記事「A crash course in assembly」では、ALU、レジスタ、RAM、命令、opcode、そして中間表現(IR)という流れで、コンパイラが最終的にどのような機械寄りの表現へ落としていくのかが説明されています。JIT記事だけを読むと「実行中に速くする仕組み」という印象で終わりがちですが、assembly側まで見ると、JITが単なる魔法ではなく、限られた時間の中でどこまで機械向けに近づけるかを判断している仕組みだとわかります。

    また、記事中では翻訳の比喩として映画Arrivalも参照されています。この比喩はかなり効いていて、人間向けに書かれた高水準コードを、機械が扱いやすい形へどう翻訳するかという問題の難しさを直感的に捉えやすくしています。

    気づき

    今回の気づきは、JITコンパイラは「全部をコンパイルして速くする装置」ではなく、「どこにコンパイル時間とメモリを使うべきかを実行中に判断する予算配分の仕組み」だという点です。速くするためには監視も必要ですし、型の仮定も必要ですし、仮定が外れた時に戻る道も必要です。つまりJavaScriptの高速化は、単純な変換ではなく、観察、推測、最適化、撤回の連続として成り立っています。

    この観点で読むと、WebAssemblyが目指した「より予測しやすい性能」の意味も見えやすくなります。JavaScript JITが実行時の推測に多くを背負うのに対し、WebAssemblyはあらかじめ型や構造が整理された形で渡せるため、エンジン側の迷いを減らせる。JITの記事は、WebAssemblyの利点を理解するための背景説明として今読んでも価値があります。

    読むとよさそうな人

    • JavaScriptがなぜ昔より速くなったのかを知りたい人
    • JIT、baseline compiler、optimizing compiler、deoptimizationの関係をつかみたい人
    • WebAssemblyの速さを、単なる「ネイティブに近いから」ではなくJavaScript実行系との比較で理解したい人

    参照した記事

  • WebAssembly入門記事が示したのは、JavaScriptの置き換えではなく“併用する低レベル実行形式”だった

    WebAssembly入門記事が示したのは、JavaScriptの置き換えではなく“併用する低レベル実行形式”だった

    Mozilla HacksのA cartoon intro to WebAssemblyを読みました。Lin Clark氏によるWebAssembly解説シリーズの入口にあたる記事で、「WebAssemblyは速い」と言われる理由を、JavaScriptの性能史から順に説明していく導入編です。

    この記事の良いところは、WebAssemblyをいきなり低レベル仕様として説明しない点です。まずJavaScriptが1995年に生まれ、2008年ごろの“performance wars”でJITにより大きく高速化し、Node.jsのような新しい用途へ広がった流れを振り返ります。そのうえで、WebAssemblyがもう一つの性能上の転換点になり得る、という見立てを置いています。

    記事の要点

    • WebAssemblyは、JavaScript以外の言語で書かれたコードをブラウザで実行するための仕組みです。
    • 記事は、WebAssemblyとJavaScriptを二者択一として扱っていません。実際には、同じアプリケーション内で両方を使う前提で説明されています。
    • JavaScriptは、JITコンパイラの導入によって大きく高速化し、利用範囲を広げました。
    • WebAssemblyは、その次の性能上の転換点になる可能性があるものとして紹介されています。
    • 記事単体で完結するというより、JIT、assembly、WebAssembly modules、WebAssemblyの速さ、MVPと将来機能へ進むシリーズの目次になっています。

    参照リンクから見えたこと

    記事中のリンク先も確認しました。JITコンパイラの解説では、JavaScriptエンジンが実行中にコードを観察し、warm/hotな部分を最適化していく流れが説明されています。WebAssemblyの速さを理解するには、まずJITがどのようにJavaScriptを速くしてきたかを見る必要があります。

    assemblyの解説では、コンパイラが高水準言語を中間表現へ落とし、さらにターゲットCPU向けの機械語へ変換する流れが示されます。続くWebAssembly moduleの記事では、WebAssemblyが物理CPUではなく“概念機械”向けの低レベル形式として位置づけられます。

    さらに、WebAssemblyの速さの記事MVPと将来機能の記事までつながることで、WebAssemblyは単なる高速化テクニックではなく、標準化された実行形式として段階的に作られていることが見えてきます。

    気づき

    今回の気づきは、この導入記事がWebAssemblyを“JavaScriptキラー”として煽っていないことです。むしろ、JavaScriptの柔軟さとWebAssemblyの低レベル性を同じアプリ内で使い分ける前提にしています。WebAssemblyを正しく理解するには、置き換えではなく、役割分担の技術として見るほうが実態に近いと感じました。

    あわせて読みたいリンク