Skip to content

I2I: Standalone Bento Runtime #36421

Open
@alanorozco

Description

Bento extensions are "standalone", included like:

<script async src="https://cdn.ampproject.org/v0/bento-timeago-1.0.js"></script>

Optionally, we include custom-elements-polyfill.js once for compatibility.

<script src="https://cdn.ampproject.org/v0/custom-elements-polyfill.js"></script>
<script async src="https://cdn.ampproject.org/v0/bento-timeago-1.0.js"></script>

A minimal bento-*-1.0.js file is very large. This is caused by including preact and PreactBaseElement, which are identical on all Bento extensions.

amp make-extension --name=amp-example --bento
amp dist --core_runtime_only --extensions=amp-example
cat dist/v0/bento-example-1.0.js | brotli -c | wc -c
   16127

Goal

Share preact/PreactBaseElement as a "Bento runtime" so that extension files are each 15-16K smaller compressed.

Non-goals

  • Updating AMP versions of the extension files (like amp-timeago-1.0.js) _ Updating npm releases of Web Components, since they should share preact as a peer dependency. _ Reducing the size of the shared runtime.

Overview

  1. Rename custom-elements-polyfill.js to bento.js. It is no longer optional.
  2. Wrap extension code so that it does not execute until a global BENTO is available. Provide BENTO from bento.js.

Details

bento.js is asynchronous

Unlike custom-elements-polyfill.js; bento.js can be asynchronous because extensions are runtime-blocked.

<script async src="https://cdn.ampproject.org/v0/bento.js"></script>

We wrap extension code:

- defineElement();
+ (self.BENTO = self.BENTO || []).push(defineElement);

Note that we don't call defineElement in the extension bundle, but only provide it so that bento.js calls it instead. This is similar to the AMP runtime's async loading mechanism, but simpler since we do not version-lock.

Preact is defined by BENTO

On compiled code, global preact functions are not bundled, but instead provided by BENTO. This is fine since extension code should not execute until BENTO is available.

- const C = fR(
+ const C = BENTO['#preact'].forwardRef,
    ({children}, r) =>
-     h(
+     BENTO['#preact'].h(
-       Fragment,
+       BENTO['#preact'].Fragment,
        null,
        children
      )
  );

Likewise, we provide PreactBaseElement as BENTO.BaseElement:

- class B extends P {
+ const {PreactBaseElement} = BENTO['#preact/base-element'];
+ class B extends PreactBaseElement {

Differences in filesize

before after Δ
bento.js n/a 18.01 kB 18.01 kB
custom-elements-polyfill.js 2.21 kB n/a n/a
bento-accordion-1.0.js 18.61 kB 7.90 kB -10.71 kB
bento-base-carousel-1.0.js 23.29 kB 9.11 kB -14.18 kB
bento-brightcove-1.0.js 20.10 kB 6.21 kB -13.88 kB
bento-date-countdown-1.0.js 17.70 kB 3.29 kB -14.41 kB
bento-date-display-1.0.js 17.34 kB 3.14 kB -14.21 kB
bento-embedly-card-1.0.js 18.66 kB 4.57 kB -14.09 kB
bento-facebook-1.0.js 19.11 kB 5.11 kB -14.00 kB
bento-fit-text-1.0.js 16.72 kB 1.63 kB -15.10 kB
bento-iframe-1.0.js 17.33 kB 3.04 kB -14.29 kB
bento-inline-gallery-1.0.js 16.35 kB 3.83 kB -12.52 kB
bento-instagram-1.0.js 16.98 kB 2.67 kB -14.31 kB
bento-jwplayer-1.0.js 21.15 kB 7.25 kB -13.90 kB
bento-lightbox-1.0.js 17.32 kB 3.10 kB -14.23 kB
bento-lightbox-gallery-1.0.js 25.15 kB 11.12 kB -14.02 kB
bento-mathml-1.0.js 18.94 kB 5.04 kB -13.90 kB
bento-render-1.0.js 16.53 kB 1.87 kB -14.66 kB
bento-selector-1.0.js 17.98 kB 3.62 kB -14.36 kB
bento-sidebar-1.0.js 18.27 kB 4.27 kB -14.00 kB
bento-social-share-1.0.js 21.18 kB 6.30 kB -14.88 kB
bento-soundcloud-1.0.js 17.05 kB 2.79 kB -14.26 kB
bento-stream-gallery-1.0.js 23.79 kB 9.61 kB -14.18 kB
bento-timeago-1.0.js 24.13 kB 9.76 kB -14.37 kB
bento-twitter-1.0.js 18.69 kB 4.69 kB -14.00 kB
bento-video-1.0.js 18.41 kB 4.31 kB -14.10 kB
bento-video-iframe-1.0.js 19.21 kB 5.19 kB -14.03 kB
bento-vimeo-1.0.js 19.89 kB 5.92 kB -13.97 kB
bento-wordpress-embed-1.0.js 17.19 kB 2.88 kB -14.31 kB
bento-youtube-1.0.js 20.10 kB 6.17 kB -13.93 kB

Metadata

Assignees

Labels

INTENT TO IMPLEMENTProposes implementation of a significant new feature. https://bit.ly/amp-contribute-codeStaleInactive for one year or more

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions