Node-vibrant: Reduce library size

Created on 21 Jun 2019  ·  9Comments  ·  Source: Vibrant-Colors/node-vibrant

I see this library declares jimp as a dependency for doing some transformations.

I'm analyzing my projects dependencies (I have node-vibrant in my package.json and looks like jimp need a lot of spaces:

ncdu 1.14 ~ Use the arrow keys to navigate, press ? for help
--- /deploy/out/node_modules ---------------
  185.0 MiB [##########] /@jimp
   38.4 MiB [##        ] /chrome-aws-lambda
   34.2 MiB [#         ] /sharp
   11.0 MiB [          ] /@browserless
   11.0 MiB [          ] /@babel
    9.2 MiB [          ] /jimp
    6.3 MiB [          ] /core-js
    4.8 MiB [          ] /lodash
    3.2 MiB [          ] /jsdom
    3.1 MiB [          ] /moment
    3.0 MiB [          ] /iltorb
    2.4 MiB [          ] /colorable
    2.1 MiB [          ] /cssstats
    1.9 MiB [          ] /@cliqz
    1.7 MiB [          ] /@microlink
    1.7 MiB [          ] /graphql
    1.7 MiB [          ] /port-numbers
    1.7 MiB [          ] /node-vibrant

The point is, jimp includes some plugin by default:

--- /deploy/out/node_modules/@jimp ---------
                         /..
    7.6 MiB [##########] /plugin-print
    7.0 MiB [######### ] /core
    6.9 MiB [######### ] /plugin-resize
    6.9 MiB [######### ] /plugin-color
    6.8 MiB [########  ] /plugin-crop
    6.8 MiB [########  ] /plugin-blur
    6.8 MiB [########  ] /plugin-rotate
    6.8 MiB [########  ] /png
    6.8 MiB [########  ] /custom
    6.8 MiB [########  ] /plugin-blit
    6.8 MiB [########  ] /plugin-contain
    6.8 MiB [########  ] /plugin-normalize
    6.8 MiB [########  ] /plugins
    6.8 MiB [########  ] /plugin-cover
    6.8 MiB [########  ] /plugin-gaussian
    6.8 MiB [########  ] /plugin-scale
    6.8 MiB [########  ] /bmp
    6.8 MiB [########  ] /plugin-mask
    6.8 MiB [########  ] /plugin-displace
    6.8 MiB [########  ] /jpeg

but not sure if all the plugins are relevant for node-vibrant.

I want to suggest two approaches:

Consider use sharp

(my favorite solution)

As you can see in my bundle, I have also sharp as a dependency.

The main difference between both is jimp is 100% javascript code, while sharp delegate into son binaries.

At the first time I thought jimp could be better since it doesn't have dependencies, but the reality is so different: sharp ship pre-installed binaries and the package size is actually tooo much smaller than jimp.

In fact, sharp perf is superior, see
http://sharp.pixelplumbing.com/en/stable/performance/

Just exclude non necessary jimp

I suppose that inside 185MB that jimp is adding there, just a few things are actually used.

Not sure how to do that from a node-vibrant, but for example adding a tiny section on README.md explicitly listed the necessary jimp plugins should be enough for anyone exclude the rest of non necessary things into a pre-build step

enhancement

Most helpful comment

Here's some additional research on how jimp could be configured to reduce the size:

The @jimp/custom package acts as a base to add plugins onto from scratch. Its default export is a configure function that takes arrays of types (supported image types) and plugins (plugins to use).

@jimp/types exports all the types included in the main jimp package, making it easy to have support for the same images node-vibrant supports now.

The only special plugin that node-vibrant seems to use is the resize function. The corresponding plugin is @jimp/plugin-resize.


The @vibrant/image-node package could be updated with the following near the top of the script:

import configure from '@jimp/custom';
import types from '@jimp/types'; // all of jimp's default types
import resize from '@jimp/plugin-resize'; // resize function

const Jimp = configure({
  types: [types],
  plugins: [resize]
});

All 9 comments

Love the work you've done to look into this, a sincere thank you.

sharp is unlikely to be a solution we're able to take on, as (despite the name) we support the browser to run node-vibrant on it's own.

However, you're absolutely correct that jimp is not required for much of the usage in node-vibrant. We're currently restricting development for the current "stable" codebase, we're working on a rewrite of the codebase to a monorepo (which means you can pick what you want to use from node-vibrant in the future as well!) and I've confirmed that's a size optimization we can make there as well.

I've got an extremely busy week ahead of me, but will do my best to loop back next weekend to make this change

Otherwise, we always love and accept pull requests 👀

I noted another thing behind @jimp: they have core-js as a dependency, and this dependency is installed per every plugin!

That's why @jimp sizes is 185MB: core-js takes 7.4MiB x 27 modules = TOO MUCH SPACE.

Probably core-js could be declared in a way they can share between the plugins

Here's some additional research on how jimp could be configured to reduce the size:

The @jimp/custom package acts as a base to add plugins onto from scratch. Its default export is a configure function that takes arrays of types (supported image types) and plugins (plugins to use).

@jimp/types exports all the types included in the main jimp package, making it easy to have support for the same images node-vibrant supports now.

The only special plugin that node-vibrant seems to use is the resize function. The corresponding plugin is @jimp/plugin-resize.


The @vibrant/image-node package could be updated with the following near the top of the script:

import configure from '@jimp/custom';
import types from '@jimp/types'; // all of jimp's default types
import resize from '@jimp/plugin-resize'; // resize function

const Jimp = configure({
  types: [types],
  plugins: [resize]
});

Seems like I might need to write some typings, but massive thank you @NotWoods. I'll try to finish this this week

Typings are taking longer than I thought originally. I know I'm going the long way around, but I want to make sure I'm fixing up the ecosystem as well as our own needs

The typings for jimp ended up taking a bit, but it's a good contribution upstream:

https://github.com/oliver-moran/jimp/pull/770

After this is merged in, I'll make the optimization to node-vibrant

With the release of Jimp 0.8.4, this can now be done! I'll have a PR open tonight with it! :D

Waiting on https://github.com/oliver-moran/jimp/pull/815 in order to fix some issues after jimp 0.8.4 with the import

This has been solved as-of the 3.1.5 release

Was this page helpful?
0 / 5 - 0 ratings

Related issues

asela-wijesinghe picture asela-wijesinghe  ·  4Comments

lucafaggianelli picture lucafaggianelli  ·  9Comments

nitriques picture nitriques  ·  12Comments

orgilor picture orgilor  ·  5Comments

daviestar picture daviestar  ·  9Comments