Performance Comparison of JSON, Protocol Buffers, and FlatBuffers for H5‑Hybrid and Flutter Data Transmission
This article presents a real‑device performance test of three data serialization structures—JSON, Protocol Buffers, and FlatBuffers—used in H5‑Hybrid and Flutter development, analyzing their size, serialization/deserialization speed, and suitability for Android, Flutter, and H5 communication channels.
The rapid rise of H5‑Hybrid and Flutter development has raised concerns about the transmission efficiency between different virtual machines (VMs). This article evaluates three popular serialization formats—JSON, Protocol Buffers, and FlatBuffers—through real‑device benchmarks to guide format selection.
Test Sample Introduction
Test data: 8‑level deep structure with 150 fields, representing a complex real‑world scenario.
JSON payload size: ~4 KB.
Protocol Buffers payload size: just over 2 KB.
FlatBuffers size: between Protocol Buffers and JSON.
JSON Analysis
JSON is a key‑value storage format. During serialization and deserialization it relies on reflection and object traversal, creating temporary objects and consuming more memory, which reduces overall efficiency. Below is a simple Gson deserialization example:
1 "user":{ "name":"mary"}Key steps in Gson deserialization:
Process the target Java class via reflection to locate fields and create corresponding BoundField objects, selecting appropriate TypeAdapter for each field.
Use JsonReader to perform an initial parse of the raw JSON string.
Iterate with JsonReader.nextName , retrieve the matching TypeAdapter , parse the value, and assign it to the target object field.
Protocol Buffers Analysis
Protocol Buffers (ProtoBuf) use a compact TLV‑like binary representation, achieving small payloads through various encoding optimizations. Serialization and deserialization are fast. Example .proto definition:
1 message User {
2 string name = 1;
3 }Key characteristics:
Tag encoding: field_number << 3 | wire_type stores field number and type.
Value encoding varies (Varint, Length‑delimited, etc.) to suit different data types.
Deserialization is order‑independent, relying on the TV structure to ensure data correctness.
FlatBuffers Analysis
FlatBuffers store data in a stream‑oriented format using offsets. They support structs, tables, and vectors, with tables offering forward/backward compatibility and optional fields—making them suitable for many business scenarios, especially games.
Serialization example in Java:
1 // flat schema, table structure:
2 table User {
3 name: string;
4 user: User;
5 }
6 // data filling
7 FlatBufferBuilder builder = new FlatBufferBuilder(0);
8 int name = builder.createString("mary");
9 User.startUser(builder);
10 User.addName(builder, name);
11 int endUser = User.endUser();
12 builder.finish(endUser);Deserialization involves calculating offsets from the vtable and byte buffer, then extracting fields directly, which yields very high parsing speed.
1 // api
2 public String name() {
3 int o = __offset(4);
4 return o != 0 ? __string(o + bb_pos) : null;
5 }
6 protected int __offset(int vtable_offset) {
7 return vtable_offset < vtable_size ? bb.getShort(vtable_start + vtable_offset) : 0;
8 }
9 protected String __string(int offset) {
10 offset += bb.getInt(offset);
11 int length = bb.getInt(offset);
12 return utf8.decodeUtf8(bb, offset + SIZEOF_INT, length);
13 }Transmission Channel Analysis
Common channels:
Android ↔ Flutter: Flutter’s official MethodChannel (String/Uint8List).
Android ↔ H5: JsBridge using WebView.evaluateJavascript and window.prompt .
Flutter ↔ H5: Flutter calls Android, which then calls H5.
Both serialization and deserialization steps are required when converting Java objects to Flutter‑compatible types and vice‑versa. Smaller payloads generally lead to higher transmission performance.
Test Results
Bar‑chart measurements (Android ↔ Flutter):
FlatBuffers > Protocol Buffers > JSON.
Bar‑chart measurements (Android/Flutter ↔ H5):
JSON > FlatBuffers/Protocol Buffers.
Notes:
Byte array transmission to H5 includes Base64 encoding/decoding overhead.
Flutter’s channel runs on the UI thread, which may affect real‑world performance (not considered in this test).
Intra‑VM tests can vary by thousands of operations; however, throughput consistently reaches tens of thousands of operations per second.
Conclusion
For Android ↔ H5 communication, JSON is preferred due to native JavaScript support.
When communicating with Flutter, choose the format based on scenario: JSON: easy to use, low cost, suitable for rapidly changing data with modest performance needs. Protocol Buffers: high compression, strong serialization/deserialization speed, ideal for stable or less‑frequent data exchange. FlatBuffers: excellent speed for serialization/deserialization, best for game‑related workloads, but larger size and more complex schema management.
Overall, JSON is a solid early‑stage choice, while Protocol Buffers is recommended for long‑term, performance‑critical projects.
References
https://flutter.dev/docs/development/platform-integration/platform-channels
http://google.github.io/flatbuffers/flatbuffers_benchmarks.html
https://code.fb.com/android/improving-facebook-s-performance-on-android-with-flatbuffers/
https://developers.google.com/protocol-buffers/docs/proto3
https://www.ibm.com/developerworks/cn/linux/l-cn-gpb/
360 Tech Engineering
Official tech channel of 360, building the most professional technology aggregation platform for the brand.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.