-
Notifications
You must be signed in to change notification settings - Fork 0
JavaScript code and TypeScript definitions generation
Basically, we can follow two possible routes, given that there are two JS runtime Protocol Buffers implementations.
-
On release 3.0.0, starting 2016, Google added node/JS support to its official
google-protobuf
library. TypeScript support is something that was discussed at some degree in the repo issues, and even the team use TS code generation internally, but it's not yet open to the public. For this purpose then,ts-protoc-gen
is our very best alternative. -
Protobuf.js
is a previous third-party attempt, its origin can be traced up to even March 2013, and included TypeScript support with its full rewritten 6.0.0 release back in November 2016.
Protobufjs |
google-protobuf + ts-protoc-gen |
---|---|
Much much better performance, although running the benchmark locally did throw a bit less of a difference on the results, they were still massive. |
Performance is somehow constrained by google-protobuf runtime JS implementation, which in the end for encoding/decoding is more or less aligned with that of JSON.An approach with some improvements can be consulted here. |
Preserves precision, through the use of a dedicated library, long.js, which addresses this issue by representing a Long as two internal parts of 32 bits each. Only problem being that its use along TypeScript definitions might be a bit convoluted. |
Precision could be lost when using [s/u]int64 value types on a proto descriptor, due to the discrepancy between the number type on JavaScript, which is based on the IEEE 754 binary64 format (Double-precision floating-point), hence only values between -(253-1) and 253-1 will be safe. Out of that range (namely values until -(263-1) and 263-1, valid for a int64/long datatype) will be rounded to a near value. Some workaround can be found here, and a discussion and a PR for google-protobuf trying to address this issue is here.Also a solution has been provided in the release 3.4, but this one implies changes to our proto files adding a [jstype = JS_STRING] option to our int64 definitions. |
Support for services do exist, though the library make no assumptions on the actual transport channel used, so the user must provide an RPC implementation. |
Services have first-class citizen support. The use of gRPC could be easily achieved, thanks to the grpc-web spec and grpc-web-client library, which provides different transport channels depending on the execution context. |
For time when not full functionality is needed (statically generated code, JSON reflection) final bundle size can be reduced thanks to some stripped down versions offered. | Final bundle size can take a hit, due to this library most apparently being designed to be used on server side through node.js (browser use was somehow in the team aspirations nevertheless). |
Browser compatibility is pretty good, even with the possibility to reach non-ES5 environments using a polyfill. | Again, as it doesn't look like the primary goal of this library is to be used client-side, wide browser compatibility (while maybe not problematic) can't be something taken for granted. |
Even encoding small payloads will cast messages with an underlying buffer length of 8192 bytes. This is expected behaviour, due to the library internally using a buffer pool of 8kb of allocated space for performance reasons. The generated views out of this then point to the respective relevant part of that buffer pool through the byteOffset and byteLength properties. |
There's no buffer pool in use, so serialized data will have a fitted buffer byteLength for each instance. |
Due to our current target of integrating freestyle-opscenter through RPC, the combination of Google's implementation google-protobuf
+ ts-protoc-gen
will be used.
Should any of the advantages offered by the Protobuf.js
library become needed to our project, a branch with the needed changes to be able to use Protobuf.js
is gonna be set.
A more detailed comparison between Protobuf.js
and JSON performance can be found here and here, and more tidbits here.