Serving

# Preloading

Every pin is preloaded with a modulepreload link by default, so the browser doesn't discover imports one file at a time.

## modulepreload by default

Without preloading, the browser loads one file, parses it, finds its imports, loads those, and so on down to the deepest nested import — a waterfall. importmap-rails avoids it with [modulepreload links](https://developers.google.com/web/updates/2017/12/modulepreload): `javascript_importmap_tags` emits the import map, then one modulepreload link for every pin marked `preload: true` (the default) that applies to the entry point being rendered, then the entry point import — so every preloaded file starts downloading at once.

## preload: false

A dependency you want to load on demand — a chart library used on one page, say — gets `preload: false` on its pin:

```ruby
pin "@github/hotkey", to: "@github--hotkey.js" # file lives in vendor/javascript/@github--hotkey.js
pin "md5", preload: false # file lives in vendor/javascript/md5.js
```

```ruby
<%= javascript_importmap_tags %>

<%# emits, after the import map, a link for hotkey but none for md5: %>
<link rel="modulepreload" href="/assets/@github--hotkey.js">
```

`bin/importmap` keeps `preload:` when it rewrites a pin, so a `preload: false` survives `update`.

## Preloading per entry point

`preload:` also takes a string or an array of strings naming the entry points a dependency should be preloaded for. `javascript_importmap_tags` takes the entry point as its argument (`"application"` by default):

```ruby
pin "@github/hotkey", to: "@github--hotkey.js", preload: "application"
pin "md5", preload: ["application", "alternate"]
```

```ruby
<%= javascript_importmap_tags "alternate" %>

<%# emits, after the import map, a link for md5 but none for hotkey: %>
<link rel="modulepreload" href="/assets/md5.js">
```

A pin with `preload: true` is preloaded for every entry point; one with a name is preloaded only when that entry point is rendered.