amphtml icon indicating copy to clipboard operation
amphtml copied to clipboard

I2I: Standalone Bento Runtime

Open alanorozco opened this issue 2 years ago • 1 comments

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

alanorozco avatar Oct 20 '21 02:10 alanorozco

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Oct 16 '22 07:10 stale[bot]