demo · v149

Module vs Classic Script Cache

Chrome 149 extends V8's bytecode cache to inline scripts. The caching model differs for <script type="module"> vs classic <script>: classic scripts cache the compiled bytecode as a whole; modules cache each module instance separately and can benefit from the module cache on repeated instantiation. Adjust size and content to see how eligibility changes.

Drag the size slider to simulate scripts of different lengths. Check the eligibility rules column — a module script has slightly different eligibility criteria than a classic script. The bar chart compares cold (first parse) and warm (from cache) compile times for each type.
Script size: 2 KB

Classic script (<script>)

<script>
// 2000 bytes of business logic
function processData(d) { … }
function renderChart(c) { … }
processData(window.__data);
</script>
Checking…

    Timing (simulated)

    Cache keySHA-256 of full body
    Cache scopewhole script body
    Module graphN/A — single unit
    Re-eval on changeFull recompile

    Module script (<script type="module">)

    <script type="module">
    import { process } from './data.js';
    import { render } from './chart.js';
    const data = await fetch('/api/data');
    render(await process(data));
    </script>
    Checking…

      Timing (simulated)

      Cache keyPer-module URL or hash
      Cache scopeModule instance graph
      Module graphShared across documents
      Re-eval on changeOnly changed modules recompile
      <!-- Classic inline script: V8 bytecode cache in Chrome 149 -->
      <script>
        // Cached as a single bytecode unit after first visit.
        // Key: SHA-256(script_body)
        // Eligible when: size > ~1KB, no eval()/with/new Function(),
        //                no document.write(), stable content across visits.
        function init() { /* … */ }
        init();
      </script>
      
      <!-- Module inline script: also cached, but module-graph-aware -->
      <script type="module">
        // Each imported module is cached separately in the module map.
        // The inline module itself benefits from V8's code cache.
        // Changes to imported modules do NOT invalidate the inline cache.
        import { setup } from '/lib/setup.js';  // cached in module map
        await setup();
      </script>
      
      // Key difference: classic scripts cache as one monolithic unit;
      // module scripts participate in the module cache and each imported
      // file is cached independently — partial invalidation is possible.

      see also

      implementation reference

      Need the exact API surface, compatibility boundaries, errors, lifecycle, and source links? Read the matching gendn reference ↗