ably / ably-js

Javascript, Node, Typescript, React, React Native client library SDK for Ably realtime messaging service
https://ably.com/download
Apache License 2.0
316 stars 55 forks source link

Stripped-down version #309

Open SimonWoolf opened 8 years ago

SimonWoolf commented 8 years ago

We've had a couple requests for a stripped-down/miniature version of the lib. We already have ably.noencryption.js, which saves about 10%. Perhaps we should that into an official miniature version. What else can be easily stripped out? One obvious one is msgpack, any others?

Lib sizes (minified but not gzipped):

┆Issue is synchronized with this Jira Task by Unito

mattheworiordan commented 8 years ago

@SimonWoolf I think we should consider a hugely stripped down version as well for another use case which I am seeing quite often. Customers often want to integrate Ably into their products so that they can stream data to their browsers. Typically it's one way so publish is not necessary.

For this use case, we could have a lib that only does the following:

I appreciate there may be customers who need other features, but I think in those scenarios they'd just use the full lib. For customers wanting to embed our lib in their libs, this is probably all that is needed for now.

mattheworiordan commented 6 years ago

@SimonWoolf @paddybyers a customer has asked about this again. The lib is currently 152kb with encryption and minified (but not Gzipped), and 141kb without encryption, although it's 41kb when Gzipped.

Any ideas how we can analyse how can we analyse what's contributing to the large lib size? I realise we can and will offer a subscribe only version soon which will be tiny, but that doesn't help customers who need the full power of the Ably feature set.

SimonWoolf commented 6 years ago

Any ideas how we can analyse how can we analyse what's contributing to the large lib size?

Quick hack to grunt:concat to print the length of everything concatenated, sorted descending:

69761 common/lib/transport/connectionmanager.js
29676 common/lib/client/auth.js
21315 node_modules/crypto-js/src/core.js
19479 common/lib/client/realtimechannel.js
18698 browser/lib/util/msgpack.js
18030 common/lib/client/realtimepresence.js
11486 common/lib/transport/comettransport.js
9670 browser/lib/transport/xhrrequest.js
9621 common/lib/util/utils.js
7614 browser/lib/transport/jsonptransport.js
7304 common/lib/transport/transport.js
7108 common/lib/types/message.js
6876 common/lib/transport/websockettransport.js
6796 common/lib/util/eventemitter.js
5123 browser/lib/util/base64.js
5095 common/lib/client/rest.js
5027 node_modules/crypto-js/src/sha256.js
4943 common/lib/client/resource.js
4758 common/lib/client/realtime.js
4685 browser/lib/util/bufferutils.js
4573 common/lib/types/presencemessage.js
4432 common/lib/util/defaults.js
4258 common/lib/types/protocolmessage.js
4017 browser/lib/util/http.js
3967 common/lib/client/paginatedresource.js
3541 node_modules/crypto-js/src/hmac.js
3321 common/lib/client/channel.js
3198 node_modules/crypto-js/src/enc-base64.js
2473 common/lib/types/stats.js
2432 common/lib/util/logger.js
2371 common/lib/transport/protocol.js
2228 common/lib/client/presence.js
2084 browser/lib/util/webstorage.js
1914 common/lib/transport/messagequeue.js
1627 common/lib/client/connection.js
1446 browser/lib/transport/xhrstreamingtransport.js
1386 browser/lib/transport/xhrpollingtransport.js
1205 browser/lib/util/defaults.js
1036 browser/fragments/platform-browser.js
937 browser/lib/util/domevent.js
857 common/lib/transport/connectionerror.js
842 common/lib/types/errorinfo.js
777 browser/fragments/ably-commonjs-epilogue.js
576 common/lib/util/multicaster.js
313 common/lib/client/channelstatechange.js
307 common/lib/client/connectionstatechange.js
212 browser/fragments/license.js
15 browser/fragments/ably-commonjs-prologue.js

obviously unminified.

One possibility: we could do a 'modern-only browsers' version that assumes webcrypto and good buffer support, which would let us get rid of all the cryptojs modules (collectively 33k), bufferutils, the xhr/jsonp transports, and all the connection upgrading logic. But even doing all that would still only cut the lib size down by maybe 30% (back-of-the-envelope, assuming upgrading logic is a third of connectionmanager). Or 35% if we also get rid of msgpack. Which is still not all that much. There's a lot of code in there..

mattheworiordan commented 6 years ago

P.S. Another customer has asked about this, so something we should still consider. I can't help feeling though that we should probably instead focus on:

SimonWoolf commented 6 years ago

As a stopgap until the streaming api is available, if needed we can pretty easily add support for mqtt over websockets, allowing people to use a js mqtt library (of which there are some pretty small ones). See https://github.com/ably/translator/issues/118

Edit: and now SSE https://www.ably.io/documentation/sse

SimonSchick commented 2 years ago

Bumping this as the bundle size is reaching questionable levels, in our prod build able takes up a LOT of size, this library should really aim to be more tree-shakable.

image
owenpearson commented 2 years ago

Hey @SimonSchick, thanks for raising this with us. We are definitely planning on making the library tree-shakeable in the near future, I'll make sure to let you know in this thread when it's available.

Just in case you weren't already aware - there's a bundle without encryption available at node_modules/ably/build/ably.noencryption.min.js, this bundle is about 20kb smaller than the full version.

SimonSchick commented 2 years ago

I am aware but we are not directly in control of this dependency as it is introduced through a dependency on the magicbell sdk, I will see if I can re-target webpack to use this file but it still seems unreasonably large.

jokull commented 1 year ago

Just chiming in - noticed that ably is a huge part of our bundle. We only use it to stream events to the browser. Please consider slimming it down, making it shakable etc.

mikelee638 commented 1 year ago

Hey @jokull, thanks for the feedback! This is on our roadmap and, while it’s not a simple fix, we do plan to make the library tree shakable. We’ll post an update on this issue when we have something available, thanks!

yairhaimo commented 1 year ago

I just found out about Ably and wanted to replace Pusher which I use as part of a library I supply to my customers. I cant bloat their bundle by so much so I'll have to look for an alternative. Ably looks amazing and when the library is a bit thinner I would love to use it!

Edit:

image image

Not much difference unfortunately :(

mikelee638 commented 1 year ago

Hey @yairhaimo thanks for the feedback! At what size would you start using ably-js in your projects?

Similarly, @jokull & @SimonSchick, curious to hear your thoughts on what a reasonable size for this package would be. Thanks!

yairhaimo commented 1 year ago

I would say under 80k minified ~20k gzipped.

Appreciate the effort!

jokull commented 1 year ago

I only use it to receive events. Seems like it should be extremely small - just auth and a connection. Tree shakability would help?

yairhaimo commented 1 year ago

That's my usecase as well. Im not familiar with the internal architecture but the library being tree-shakeable is always good.

jnpwebdeveloper commented 1 year ago

Just wanna bump this. We would really appreciate a stripped down version or the ability to reduce the size ourselves based on the functionality we actually use. This lib is bigger than any of the others we have - including the app itself. I obviously appreciate the reliability that comes with this library and amount of features that are provided out of the box. But it comes at a cost that to us at least seems fairly unreasonable as it stands.

itsderek23 commented 1 year ago

Bumping this as well - we're getting pushback from customers installing a JS library that includes Ably. We're close to needing to investigate alternatives.

   ├ node_modules/ably/browser/static/ably-commonjs.js                                         200.5kb   46.6%

For comparison:

   ├ node_modules/pusher-js/dist/web/pusher.js                                                  73.6kb   14.6%
yairhaimo commented 1 year ago

For simple scenarios (subscribe-only for channels) you can use SSE without using any library:


var apiKey ='mykey';
var url ='https://realtime.ably.io/event-stream?channels=myChannel&v=1.2&key=' + apiKey;
var eventSource = new EventSource(url);

eventSource.onmessage = function(event) {
  var message = JSON.parse(event.data);
  console.log('Message: ' + message.name + ' - ' + message.data);
};

https://ably.com/docs/sse

mikelee638 commented 1 year ago

Thanks all for this feedback! We’ll make sure to incorporate it into our existing conversations surrounding reducing the size of ably-js.

And thanks @yairhaimo for pointing out SSE as an option for subscribe-only use cases.

yairhaimo commented 1 year ago

Btw, a few years ago I created a VSCode extension that measures the weight of an import/require and shows it inline in your editor: https://marketplace.visualstudio.com/items?itemName=wix.vscode-import-cost

It doesnt always work (I dont work at Wix anymore so I cant maintain it) but it can help with the tree-shaking endeavor. Import Cost tree shakes the specific import that you write so it will tell you the exact amount that is imported.

Hopefully it will help, thanks for your efforts!