3

I'm trying to create a GIF image from scratch on the browser. It all works, but it get a lot of time to build small image which feels underwhelming. (2.6s for a 300x200 with 100 frames on a high-end proc)

Currently, I'm concatenating all my data into a simple Array and turn everything into a Uint8Array when done. I guess using Uint8Array would be better memory and efficiency wise, but I didn't figured out how to concat my data as I create it.

I tried to recreate the Uint8Array each times, but it obviously reduces performances. I tried to use Stream, but never manage to make it work.

// kinda concat
stream = new Uint8Array([
    ...stream,
    ...graphicControlExtension,
    ...imageDescriptor,
]);

MDN Stream example are just confusing, so if someone could point me to the right direction it would be dope. =D

GMartigny
  • 126
  • 8
  • what are `stream`, `graphicControlExtension` etc? Strings, other arrays? – georg Nov 22 '19 at 14:13
  • That's the point of my question. They're `Array` as of now, but concatenating everything take too long IMO. There should be a better way. – GMartigny Nov 22 '19 at 14:23
  • Does this answer your question? [How do I merge an array of Uint8Arrays?](https://stackoverflow.com/questions/49129643/how-do-i-merge-an-array-of-uint8arrays) – mousetail Sep 13 '22 at 11:41
  • best answer for me: https://stackoverflow.com/a/57946167/470749 – Ryan Feb 08 '23 at 16:12

1 Answers1

1

if all of your variables are uint 8 arrays(stream, graphicControlExtension, imageDescriptor) use the set method.

uint8stream = new Uint8Array(stream.length + graphicsControlExtension.length + imageDescriptor.length);
uint8stream.set(stream);
uint8stream.set(graphicControlExtension, stream.length);
uint8stream.set(imageDescriptor, stream.length + graphicControlExtension.length);

Otherwise you should to convert them first

UPD: to boost it up you can:

  1. try to use push instead of concat
  2. try to use lodash.concat (it is faster than Array.prototype.concat)
  3. write your own concat method like in this article
mousetail
  • 7,009
  • 4
  • 25
  • 45
nickbullock
  • 6,424
  • 9
  • 27
  • This is the same as my example code. You just create a new `Uint8Array` and fill it with the values or I'm missing something. – GMartigny Nov 22 '19 at 14:24
  • I tried `push`, with the same results. I just also tried to make a custom concat method, with the same results. My problem is (I think) that I'm dealing with a lot of values, not that push/concat/spread is not performant. I guess I should be using [`Stream`s](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API), but I don't know how. – GMartigny Nov 22 '19 at 14:45
  • 1
    This example has a mistake: you need to specify the size of the Uint8Array to be at least the total size of the sub arrays, otherwise `set` will not work because it expects the array to have enough elements. Also, are you sure that the copy at the end is the bottleneck? Make sure to profile this. – Octo Poulos Jun 27 '22 at 18:44