weixin_39688378
weixin_39688378
2020-11-27 22:41

Use Size Limit to calculate size

I read 7.0 changelog and was very happy reducing project file size. Great work, .

And I bring a good thing for you — Size Limit. It is a special tool to calculate project cost of users. It is highly accurate and gives you important feedback for optimization.

  1. It doesn’t just take file size. JS file in npm package could have one size, but bloat few times when webpack or Rollup will add a file to bundle. For instance, JS file could have a big dependency. Or it could use process in the wrong way and bundler will add process polyfill. This is why Size Limit emulate the real case. It creates the empty project in the memory, adds your library as dependency and then checks project bundle size.
  2. Size Limit has awesome npx size-limit --why tool which shows you the reason for this size. Here is current results:

vxh0sam

(Note, that PropTypes still in the bundle, this is why Size Limit’s size is bigger)

Of course, Size Limit is not just a rando tool from the Internet. It is used by PostCSS, Autoprefixer, Material UI. And Size Limit’s feedback really improved the size of this projects (you can find examples in Size Limie readme).

If you like the idea to use this special tool for checking the size, please check my PR. update-size must be called only after building step. Did I make PR right?

该提问来源于开源项目:Andarist/react-textarea-autosize

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

11条回答

  • weixin_39949607 weixin_39949607 5月前

    Thanks for the PR! I was considering using some dedicated tool for this (i've looked briefly into size-limit too). I'm not opposed to using one - especially I'd like to chose 1 tool and configure more packages with it.

    The problem I have is that it's IMHO those measurements are often hard to get right (each situation is different) and often they might misinform the people looking at them. I.e. I don't believe we should count webpack's runtime wrapper - this is not the cost of a module. Also I don't quite think prop-types package should be counted here either - most people have it in their bundles anyway, so it wouldn't be an added cost. While I remove propTypes now in production mode, it's not possible (at least I don't know how) to remove the import 'prop-types' declaration because of ESM static nature.

    I agree that one thing is what's the size of the module itself, one thing is what's the size of the module and its dependencies and I think both are valuable metrics.

    Open question - I'm wondering how we should measure tree-shakeable libraries. Let's take polished lib as an example - it's totally tree-shakeable so it's actual cost may vary A LOT, because it depends on the actual usage and not on what a library in question provides.

    Don't take me wrong - I would very much like to chose some tool for the job. This answer is more of a discussion starter right now than a direct response to this PR.

    点赞 评论 复制链接分享
  • weixin_39688378 weixin_39688378 5月前

    Also I don't quite think prop-types package should be counted here either - most people have it in their bundles anyway, so it wouldn't be an added cost.

    I removed prop-types from size calculation

    I.e. I don't believe we should count webpack's runtime wrapper - this is not the cost of a module.

    We didn’t have a perfect way to calculate the real cost since all projects (which will use your module) are different. The only thing we can try to select a better way from available.

    Open question - I'm wondering how we should measure tree-shakeable libraries. Let's take polished lib as an example - it's totally tree-shakeable so it's actual cost may vary A LOT, because it depends on the actual usage and not on what a library in question provides.

    The bundler way to calculate size is perfect for this case. We can emulate project which uses only some of the functions and sees project size after tree-shaking (since there is a limits in tree-shaking this bundler-way will show mistakes in using tree-shaking).

    it's not possible (at least I don't know how) to remove the import 'prop-types' declaration because of ESM static nature.

    I think there is a Bable plugin for it. If I understood you correctly.

    点赞 评论 复制链接分享
  • weixin_39949607 weixin_39949607 5月前

    We didn’t have a perfect way to calculate the real cost since all projects (which will use your module) are different. The only thing we can try to select a better way from available.

    I agree, but I'm also wondering if rollup shouldnt be used instead as baseline because it bundles only what's really provided by the lib. As to i.e. process misusage & such - we could just lint it, make an audit instead of measurement for such things. Not sure if it's better - just thinking out loud.

    The bundler way to calculate size is perfect for this case. We can emulate project which uses only some of the functions and sees project size after tree-shaking (since there is a limits in tree-shaking this bundler-way will show mistakes in using tree-shaking).

    Maybe it would be good to incorporate some ideas from https://github.com/TrySound/rollup-plugin-size-snapshot

    I think there is a Bable plugin for it. If I understood you correctly.

    I'm using it here, but what I meant is that it can remove Comp.propTypes = {}, but it cannot remove import PropTypes from 'prop-types' for prod builds (unless package consumers use it).

    Could u rebase against master?

    Question - does size-limit stores last value somewhere (like if I would setup CI integration)? What's important to me is to track size changes, but not necessarily to setup a threshold.

    点赞 评论 复制链接分享
  • weixin_39688378 weixin_39688378 5月前

    if rollup shouldnt be used

    We can use Rollup project as well. The reason for using webpack in Size Limit is that webpack is the most popular bundler. So in some way, it is the most popular use case. In my opinion benchmarks (we could call it benchmark) should test the most popular use case.

    but it cannot remove import PropTypes from 'prop-types' for prod builds (unless package consumers use it).

    It can (at least it removed imports from our project).

    If plugin removed only require() (I tested only them) but not import, you can always remove any import by browsers in package.json. And it is the good reason to create an issue, removing import is easy.

    Question - does size-limit stores last value somewhere (like if I would setup CI integration)?

    Yeap. If you want to add it to CI I can add .size-limit config with the limit.

    Maybe it would be good to incorporate some ideas from https://github.com/TrySound/rollup-plugin-size-snapshot

    Nice to see this link here :D. This project was inspired by Size Limit :).

    But this project was created for a little different purpose. It contains raw data for many scenarios.

    For this project we need:

    1. One number to write in the docs (users will not be happy if we give them a lot of numbers, which they will not understand).
    2. We need to have feedback about why we got this number to optimize the size. size-limit --why is important here.
    3. In another hand, this is one component library. Most of users will not have three-shaking end will use the whole library.
    4. Optionally we should run it in Travis CI and block PR which bloat the project. In this case, one number is always better idea (PR authors will not be happy with many numbers).
    点赞 评论 复制链接分享
  • weixin_39688378 weixin_39688378 5月前

    Question - does size-limit stores last value somewhere (like if I would setup CI integration)?

    Yeap, you can have .size-limit.js config with the limit. But I didn’t add the limit since I didn’t found .travis.yml or test script in package.json.

    I added the config. Just add size-limit script to your test suit.

    点赞 评论 复制链接分享
  • weixin_39688378 weixin_39688378 5月前

    Could u rebase against master?

    Done

    点赞 评论 复制链接分享
  • weixin_39949607 weixin_39949607 5月前

    If plugin removed only require() (I tested only them) but not import, you can always remove any import by browsers in package.json. And it is the good reason to create an issue, removing import is easy.

    That's the problem - plugin can remove require because it's dynamic, so it can just wrap call to it in NODE_ENV check, but imports cannot be wrapped because they are static. Not sure how to work around this issue on library's side (in application it's easy - u have to just remove it, but in lib u want to keep import for dev builds but remove for prod).

    I'll respond to the rest some time later.

    点赞 评论 复制链接分享
  • weixin_39688378 weixin_39688378 5月前

    Here is a article with a reasons behind Size Limit metrics

    https://evilmartians.com/chronicles/size-limit-make-the-web-lighter

    点赞 评论 复制链接分享
  • weixin_39688378 weixin_39688378 5月前

    Ping :). The project anyway uses library size metric, Size Limit just make it more accurate. Small PR to improve existent tooling.

    点赞 评论 复制链接分享
  • weixin_39688378 weixin_39688378 5月前

    done :+1:

    点赞 评论 复制链接分享
  • weixin_39949607 weixin_39949607 5月前

    Thanks for keeping up with me 👍

    点赞 评论 复制链接分享

相关推荐