Reputation: 1088
I try to let use ajax upload file over 2mb with nodejs app,
client side I use FileReader
api to save base64 then pass through FormData
.
My problem is server side code like below so slow, I put console.log
try to find which part, when upload bigger size file, seems stuck at regex match
..
any suggestion how to improve this?
https://regex101.com/r/qS2lB2/1
...
console.log(image.data_base64);
// 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvd ...
var matches = image.data_base64.match(/^data:.+\/(.+);base64,(.*)$/);
console.log('done'); // slow
var fileExtension = matches[1];
var base64 = matches[2];
var buffer = new Buffer(base64, 'base64');
...
yield Promise.resolve( filesystem().writeFile(temporaryFilePath, buffer) );
Upvotes: 2
Views: 1637
Reputation: 6173
Additional length means there's more string that the regex must travel through.
Testing your regex (using regex101.com, PHP mode) on strings starting with data:image/jpeg;base64,/9
:
0 | 63
1 | 68
2 | 73
10 | 113
100 | 563
Each additional character is 5 steps.
(based on characters added=100
taking 563 steps)
Your biggest problems are the .+
s
.+?
takes it from 248 to 34 stepsCatastrophic backtracking. .+
will eat up the entire string, and if it still needs to find more characters, it has to go back, releasing characters one by one. The .+?
is lazy, meaning it will try to move on in the regex ASAP, consuming as few characters as possible.
Upvotes: 1
Reputation: 626926
Just in case you still want to use a regex for some reason, the performance can be improved by replacing non-trailing .+
subpatterns with appropriate negated character classes that involve much less backtracking.
Use
/^data:[^\/]+\/([^;]+);base64,(.*)$/
See regex demo.
Explanation:
^
- start of stringdata:
- literal char sequence data:
[^\/]+
- 1+ characters other than /
\/
- a literal slash([^;]+)
- Group 1: 1+ characters other than ;
;base64,
- a literal char sequence ;base,
(.*)
- Group 2: 0+ any characters but a newline$
- end of string.Upvotes: 2
Reputation: 106696
Sending a file base64-encoded in a multipart/form-data
request is unnecessary. FileReader
has a .readAsArrayBuffer()
method that will give you the raw data (as an ArrayBuffer) that you can pass directly to formData.append()
.
Upvotes: 0