Slimming Down Steal

Matthew Phillips by Matthew Phillips

Slimming Down Steal

Matthew Phillips StealJS has always had a focus on performance. With "slim", we are building a new loader for production with a focus on providing only the features you use in your app. This roadmap explains how we plan to build it.

posted in StealJS on June 30, 2017 by Matthew Phillips

The slim loader is a new minimal production loader for StealJS apps. You can think of slim as taking all of the useful features that StealJS provides and stripping them away to only what you actually use in your application. This means that your users don't download any code that you're not using, which improves the speed of your application.

Currently for an application that has only a single bundle (one that doesn't use progressive loading) the cost of the loader (minified & gzipped) is only 323 bytes. If you do use progressive loading it is 1.07kb. Compare this to the steal.production.js build, which is 22kb. Size is only one aspect of slim's impact on production performance; additionally it does far less work than the steal loader to resolve and load modules.

There are some types of features that are difficult to "compile away" during the build, and will need some type of runtime support. These include:

  • Plugins that have their own logic for handling importing, such as CSS.
  • Extensions that handle splitting bundles in unusual ways (such as steal-conditional).
  • Run-time configuration that might be used in the application.

The DoneJS core team believe in "release early and often" so we're going to make slim available as quickly as possible to get your feedback. As such, the initial version of slim will not support every feature of steal that exists today, but it will work for a good percentage of applications.

Phase 1

The first phase of the slim loader will be released in steal-tools 1.4.0 (coming very soon), the next release. This will work with an application that:

  • Progressively loads different pages of their application.
  • Uses steal-css or steal-less to import styles.
  • Runs in the browser, but doesn't in Node (including server-side rendering).

This covers a good percentage of our users. Additionally, if you know what you are doing, you can load all of your progressively-loaded bundles with asynchronous script tags like so:

<script src="/bundles/main.js" async></script>
<script src="/bundles/cart.js" async></script>
<script src="/bundles/cart-product.js" async></script>

Knowing which scripts should be loaded will require a little bit of manual labor. To aid with that steal-tools will updated so that it can export a bundle manifest. This is a JSON file that lists the entry points of your application, along with which bundles are needed for those. It looks something like:

{
  "place-my-order/home.component": {
    "dist/bundles/place-my-order/home.css": {
      "type": "style",
      "weight": 1
    },
    "dist/bundles/place-my-order/home.js": {
      "type": "script",
      "weight": 2
    }
  },
  "place-my-order/index.stache": {
    "dist/bundles/place-my-order/index.css": {
      "type": "style",
      "weight": 1
    },
    "dist/bundles/place-my-order/index.js": {
      "type": "script",
      "weight": 2
    }
  },
  "place-my-order/order/history.component": {
    "dist/bundles/history-componen-51b0674a.js": {
      "type": "script",
      "weight": 3
    },
    "dist/bundles/history-component-new.js": {
      "type": "script",
      "weight": 3
    },
    "dist/bundles/place-my-order/order/history.js": {
      "type": "script",
      "weight": 2
    }
  }
}

You can then use this bundle graph to know which asynchronous scripts to add to your page, which you can either do manually or by using the file within your server templating logic.

As part of this phase we'll create a getting started guide for using slim that explains all of the above.

Phase 2

The second phase of the project will seek to fill in some of the holes, to allow more advanced applications to utilize the slim loader. This will mean providing an API that extensions can hook into at build-time to add any capabilities that they need. A few scenarios come to mind:

  • Apps that need to be able to run in Node.js.
  • Apps that use steal-conditional to implement internationalization.
  • Apps that use envs configuration to import a different module in production.
  • Apps that use any type of configuration that is useful at runtime, such as DoneJS' use of @loader to configure its serviceBaseURL option.

After phase 2 the essential hooks will be in place to allow any new dynamic features we implement into steal will always work within slim.

Phase 3 - Integration with DoneJS

For many DoneJS users, the benefits of slim will be available in the first phase, in steal-tools 1.4.0. To fully integrate with DoneJS we need to make sure that:

  • done-ssr is able to load and use slim bundles.
  • done-ssr is able to use the bundle graph to automatically attach the correct asynchronous script tags for pages that are rendered.
  • Make any changes necessary so that done-component and other similar DoneJS plugins work.
  • Update steal-cordova, steal-nw, and steal-electron so that they can use either loader.
  • Create a donejs add slim generator that updates your build scripts to use slim.

We hope to have all of this ready for the DoneJS.NEXT release. By StealJS 2.0 slim will become the default, and steal-tools will be able to intelligently pick the loader that you need, based on the features that you use in your application.

Yes, your applications will slim down, thanks to StealJS!

 

1302282209_dog-on-treadmill.gif

 

Create better web applications. We’ll help. Let’s work together.