npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

babel-plugin-optimize-objstr

v1.0.0

Published

Babel plugin to optimize `obj-str` calls.

Downloads

622

Readme

babel-plugin-optimize-obj-str CI codecov

Babel plugin to optimize obj-str calls by replacing them with an equivalent unrolled expression.

Even though the obj-str function is negligible in size over-the-wire, the motivation for this plugin is that transformed expressions execute almost twice as fast as equivalent calls.

import objstr from 'obj-str';

objstr({
  'my-classname': true,
  'another-one': maybe,
  'third': a && b,
});

// Transformed:
'my-classname' + (maybe ? ' another-one' : '') + (a && b ? ' third' : '');

Install

npm install --save-dev babel-plugin-optimize-obj-str

Usage

Via babel.config.js (recommended):

// babel.config.js
module.exports = {
  plugins: ['optimize-obj-str'],
};

Via CLI:

babel --plugins optimize-obj-str script.js

Options

// babel.config.js
module.exports = {
  plugins: [
    ['optimize-obj-str', {
      strict: false,
    }],
  ],
};

options.strict

Type: boolean Default: false

Allow Babel to throw errors when encountering obj-str calls that cannot be optimized.

We can only optimize function calls whose single argument is an object literal containing only keyed properties.

objstr({
  'optimizable': true,
  [classes.myClass]: maybe,
});

// Transformed:
'optimizable' + (maybe ? ' ' + classes.myClass : '');

By default, calls that cannot be optimized are preserved.

objstr({ optimizable: true });
objstr(cannotOptimizeIdentifierArg);
objstr({ ...cannotOptimizeSpread });

// Transformed:
('optimizable');
objstr(cannotOptimizeIdentifierArg);
objstr({ ...cannotOptimizeSpread });

Preserved calls force the resulting bundle to contain the objstr() function, which could otherwise be dead-code-eliminated.

Instead, when setting the option { strict: true } the plugin errors out to prevent this.

Caveats

Performance

The purpose of this transform is to improve execution performance. This benchmark results in a ~1.8x speedup on desktop Chrome (88) (obj-str calls are about 45% slower).

You should not expect this transform should to reduce bundle size. Depending on the amount of object properties and plugin configuration, it might actually output slightly larger code. A rough estimate is that using less than ~100 different conditional properties should not increase the size of a bundle.

Leading Space

Direct results from objstr() always omit a leading space. This is not the case when using this transform:

objstr({
  a: false,
  foo: true
});

// transformed:
(' foo');

You must ensure that your expression consumers ignore this leading space. A classname should work just fine.

Inconsistent Duplicates

Object literals may contain duplicate property names, in which case the lastly defined value is preserved.

objstr({
  dupe: one,
  dupe: two
});

// Transformed:
'' + (two ? 'dupe' : '');

The example above is transformed properly since the duplicate property names are literal and constant. The plugin does its best to override duplicates by comparing property name expressions, but it's unable to compare equal computed results whose expressions vary:

objstr({
  good: one,
  'good': two,
  ['good']: three,
});
objstr({
  bad: one,
  'bad': two,
  ['ba' + 'd']: three,
});

// Transformed:
'' + (three ? 'good' : '');
'' + (two ? 'bad' : '') + (three ? ' bad' : '');

It's therefore recommended to reserve the use of computed property names for identifiers to unique values, and to avoid complex expressions. This reduces the likelihood of mismatched dupes.

// These computed names are likely ok:
objstr({ [FOO]: true });
objstr({ [myConstants.BAR]: true });

// More complex computed names are at a higher risk of duping:
objstr({
  [FOO + 'bar']: true,
  [FOO + possiblyBar]: false,
});

License

MIT