Typewriter animation, implemented using recursive asynchronous function [closed]

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
0
down vote

favorite












In this animation, I am wondering if it's a good idea using async/await with recursive calls and the effect may be caused to the javascript event loop.



Core function:






const wait = (ms) => new Promise(r => setTimeout(r, ms));

async function typeWriter(text, n, elementId, waitAfter)
const el = document.getElementById(elementId);
if (n < text.length)
requestAnimationFrame(() =>
el.innerHTML = (text.substring(0, n + 1));

n++;
await wait(waitAfter) //wait after letter stroke
await typeWriter(text, n, elementId, waitAfter) //recursion till text finish






Full code



https://github.com/Microsmsm/microsmsm.github.io/blob/master/js/typewriter.js



Result:



https://microsmsm.com/







share|improve this question













closed as off-topic by t3chb0t, Toby Speight, Graipher, Sam Onela, Snowbody Jan 17 at 14:39


This question appears to be off-topic. The users who voted to close gave this specific reason:


  • "Questions must involve real code that you own or maintain. Pseudocode, hypothetical code, or stub code should be replaced by a concrete implementation. Questions seeking an explanation of someone else's code are also off-topic." – Toby Speight, Graipher, Sam Onela
If this question can be reworded to fit the rules in the help center, please edit the question.












  • Please add an explanation of what the code is supposed to do. What is it trying to accomplish?
    – Snowbody
    Jan 17 at 14:39










  • @snowbody I attached the typewriter result link above
    – Microsmsm
    Jan 17 at 16:47










  • Yes, I can see that there is a web link, but in order for this qquestion to be considered you need to explain in the question itself what the code is supposed to do. e.g. "It's supposed to animate the characters appearing one at a time with a random delay".
    – Snowbody
    Jan 18 at 5:47
















up vote
0
down vote

favorite












In this animation, I am wondering if it's a good idea using async/await with recursive calls and the effect may be caused to the javascript event loop.



Core function:






const wait = (ms) => new Promise(r => setTimeout(r, ms));

async function typeWriter(text, n, elementId, waitAfter)
const el = document.getElementById(elementId);
if (n < text.length)
requestAnimationFrame(() =>
el.innerHTML = (text.substring(0, n + 1));

n++;
await wait(waitAfter) //wait after letter stroke
await typeWriter(text, n, elementId, waitAfter) //recursion till text finish






Full code



https://github.com/Microsmsm/microsmsm.github.io/blob/master/js/typewriter.js



Result:



https://microsmsm.com/







share|improve this question













closed as off-topic by t3chb0t, Toby Speight, Graipher, Sam Onela, Snowbody Jan 17 at 14:39


This question appears to be off-topic. The users who voted to close gave this specific reason:


  • "Questions must involve real code that you own or maintain. Pseudocode, hypothetical code, or stub code should be replaced by a concrete implementation. Questions seeking an explanation of someone else's code are also off-topic." – Toby Speight, Graipher, Sam Onela
If this question can be reworded to fit the rules in the help center, please edit the question.












  • Please add an explanation of what the code is supposed to do. What is it trying to accomplish?
    – Snowbody
    Jan 17 at 14:39










  • @snowbody I attached the typewriter result link above
    – Microsmsm
    Jan 17 at 16:47










  • Yes, I can see that there is a web link, but in order for this qquestion to be considered you need to explain in the question itself what the code is supposed to do. e.g. "It's supposed to animate the characters appearing one at a time with a random delay".
    – Snowbody
    Jan 18 at 5:47












up vote
0
down vote

favorite









up vote
0
down vote

favorite











In this animation, I am wondering if it's a good idea using async/await with recursive calls and the effect may be caused to the javascript event loop.



Core function:






const wait = (ms) => new Promise(r => setTimeout(r, ms));

async function typeWriter(text, n, elementId, waitAfter)
const el = document.getElementById(elementId);
if (n < text.length)
requestAnimationFrame(() =>
el.innerHTML = (text.substring(0, n + 1));

n++;
await wait(waitAfter) //wait after letter stroke
await typeWriter(text, n, elementId, waitAfter) //recursion till text finish






Full code



https://github.com/Microsmsm/microsmsm.github.io/blob/master/js/typewriter.js



Result:



https://microsmsm.com/







share|improve this question













In this animation, I am wondering if it's a good idea using async/await with recursive calls and the effect may be caused to the javascript event loop.



Core function:






const wait = (ms) => new Promise(r => setTimeout(r, ms));

async function typeWriter(text, n, elementId, waitAfter)
const el = document.getElementById(elementId);
if (n < text.length)
requestAnimationFrame(() =>
el.innerHTML = (text.substring(0, n + 1));

n++;
await wait(waitAfter) //wait after letter stroke
await typeWriter(text, n, elementId, waitAfter) //recursion till text finish






Full code



https://github.com/Microsmsm/microsmsm.github.io/blob/master/js/typewriter.js



Result:



https://microsmsm.com/






const wait = (ms) => new Promise(r => setTimeout(r, ms));

async function typeWriter(text, n, elementId, waitAfter)
const el = document.getElementById(elementId);
if (n < text.length)
requestAnimationFrame(() =>
el.innerHTML = (text.substring(0, n + 1));

n++;
await wait(waitAfter) //wait after letter stroke
await typeWriter(text, n, elementId, waitAfter) //recursion till text finish






const wait = (ms) => new Promise(r => setTimeout(r, ms));

async function typeWriter(text, n, elementId, waitAfter)
const el = document.getElementById(elementId);
if (n < text.length)
requestAnimationFrame(() =>
el.innerHTML = (text.substring(0, n + 1));

n++;
await wait(waitAfter) //wait after letter stroke
await typeWriter(text, n, elementId, waitAfter) //recursion till text finish









share|improve this question












share|improve this question




share|improve this question








edited Jan 17 at 12:46









200_success

123k14143401




123k14143401









asked Jan 17 at 10:39









Microsmsm

1787




1787




closed as off-topic by t3chb0t, Toby Speight, Graipher, Sam Onela, Snowbody Jan 17 at 14:39


This question appears to be off-topic. The users who voted to close gave this specific reason:


  • "Questions must involve real code that you own or maintain. Pseudocode, hypothetical code, or stub code should be replaced by a concrete implementation. Questions seeking an explanation of someone else's code are also off-topic." – Toby Speight, Graipher, Sam Onela
If this question can be reworded to fit the rules in the help center, please edit the question.




closed as off-topic by t3chb0t, Toby Speight, Graipher, Sam Onela, Snowbody Jan 17 at 14:39


This question appears to be off-topic. The users who voted to close gave this specific reason:


  • "Questions must involve real code that you own or maintain. Pseudocode, hypothetical code, or stub code should be replaced by a concrete implementation. Questions seeking an explanation of someone else's code are also off-topic." – Toby Speight, Graipher, Sam Onela
If this question can be reworded to fit the rules in the help center, please edit the question.











  • Please add an explanation of what the code is supposed to do. What is it trying to accomplish?
    – Snowbody
    Jan 17 at 14:39










  • @snowbody I attached the typewriter result link above
    – Microsmsm
    Jan 17 at 16:47










  • Yes, I can see that there is a web link, but in order for this qquestion to be considered you need to explain in the question itself what the code is supposed to do. e.g. "It's supposed to animate the characters appearing one at a time with a random delay".
    – Snowbody
    Jan 18 at 5:47
















  • Please add an explanation of what the code is supposed to do. What is it trying to accomplish?
    – Snowbody
    Jan 17 at 14:39










  • @snowbody I attached the typewriter result link above
    – Microsmsm
    Jan 17 at 16:47










  • Yes, I can see that there is a web link, but in order for this qquestion to be considered you need to explain in the question itself what the code is supposed to do. e.g. "It's supposed to animate the characters appearing one at a time with a random delay".
    – Snowbody
    Jan 18 at 5:47















Please add an explanation of what the code is supposed to do. What is it trying to accomplish?
– Snowbody
Jan 17 at 14:39




Please add an explanation of what the code is supposed to do. What is it trying to accomplish?
– Snowbody
Jan 17 at 14:39












@snowbody I attached the typewriter result link above
– Microsmsm
Jan 17 at 16:47




@snowbody I attached the typewriter result link above
– Microsmsm
Jan 17 at 16:47












Yes, I can see that there is a web link, but in order for this qquestion to be considered you need to explain in the question itself what the code is supposed to do. e.g. "It's supposed to animate the characters appearing one at a time with a random delay".
– Snowbody
Jan 18 at 5:47




Yes, I can see that there is a web link, but in order for this qquestion to be considered you need to explain in the question itself what the code is supposed to do. e.g. "It's supposed to animate the characters appearing one at a time with a random delay".
– Snowbody
Jan 18 at 5:47










1 Answer
1






active

oldest

votes

















up vote
2
down vote



accepted










Recursion is a state stack.



Function context



Every time a function is called JS creates a new context (function state), even if the function does nothing, creates no variables, has no arguments, only calls another function, it still requires its own context. The process of creating and pushing to the heap costs memory and processing time.



The minimum memory cost varies between JS engines, but 1K is a reasonable estimate for an empty context.



Note The exception is Proper tail call Functions that by nature of the return, may not require their own context, they use the calling functions context. (No browser current lets you use this ES6 required standard feature)



Recursive state stack



In general recursion is used as a way create a state stack. Each iteration (recursive) call creates a new function context, with closure that is pushed to the heap.



When the a function exits its state is deleted popped from the heap and the calling function's state is reinstated from the heap.



Example showing states pushed and popped



The following illustrates the state stack. The state includes a random value. Each iteration waits 200ms before creating the next. When the recursion exits each state is popped from the heap, the functions complete execution until the stack is clear.






 function resolveAfter200ms(x) 
return new Promise(resolve =>
setTimeout(() => resolve() , 200);
);
;
async function test(count)
const rand = Math.random() * 100
function log(data)
document.body.innerHTML += `<span>$data</span>`;

test(0);





Why this makes your function bad.



Saving state to a stack is great when you have complex or branching data structures that you need to iterate.



Saving an irreverent state on the other hand is not so great. In fact I would say using an aysnc function to step over animation frames via recursion is about the worst way to create an animation.



If you have 200 characters to animate by the time they have all completed (the last recursive call) you have 200 function states on the heap.



I would estimate that the memory usage of a 200 character animation to be about 200K +, though that is nothing, I have seen people chew 1Meg just to add two integers in JavaScript (crazy eh!).



Luckily JavaScript makes such wasteful resource usage transparent, by providing ample memory and a gaggle of resource management threads to contain and clean up so from your point of view everything is running slick..



Another way.



I am a little long in the tooth and come from a time where 1K was all we had. I can not write code without a device angel whispering thoughts of "conserve, speed and memory"



So I would have written your code as follows if the requirement was to use async functions, and assuming that the waitAfter value is many times greater than 60fps.



// Note dont need text position (n)
async function typeWriter(text, elementId, waitAfter)
var n = 0;
// Following DOM query only done once saving lots of time
const el = document.getElementById(elementId);

const wait = () => new Promise(r => setTimeout(r, waitAfter));

// Preventing re flow overhead by using textContent rather than innerHTML
const render = () => el.textContent = (text.substring(0, n + 1));

while (n < text.length)
requestAnimationFrame(render); // Calls existing function
// thus avoid unneeded function state capture
// via closure

await wait();

n++; // add after await so render gets
// the correct value




From an external view its behaviour is identical, from a resource point of view its is remarkably different, will much lower memory use and associated GC overhead upon exit. It can also handle any size text, unlike the recursive method was limited to the available call stack size.






share|improve this answer





















  • That was super helpful to me, thanks too much... unfortunately we as well as many -JavaScript developers- have too many resources to waste... 1KB should have landed a rocket the moon while now 1GB couldn't literally launch an Angular app smoothly!
    – Microsmsm
    Jan 17 at 19:35

















1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
2
down vote



accepted










Recursion is a state stack.



Function context



Every time a function is called JS creates a new context (function state), even if the function does nothing, creates no variables, has no arguments, only calls another function, it still requires its own context. The process of creating and pushing to the heap costs memory and processing time.



The minimum memory cost varies between JS engines, but 1K is a reasonable estimate for an empty context.



Note The exception is Proper tail call Functions that by nature of the return, may not require their own context, they use the calling functions context. (No browser current lets you use this ES6 required standard feature)



Recursive state stack



In general recursion is used as a way create a state stack. Each iteration (recursive) call creates a new function context, with closure that is pushed to the heap.



When the a function exits its state is deleted popped from the heap and the calling function's state is reinstated from the heap.



Example showing states pushed and popped



The following illustrates the state stack. The state includes a random value. Each iteration waits 200ms before creating the next. When the recursion exits each state is popped from the heap, the functions complete execution until the stack is clear.






 function resolveAfter200ms(x) 
return new Promise(resolve =>
setTimeout(() => resolve() , 200);
);
;
async function test(count)
const rand = Math.random() * 100
function log(data)
document.body.innerHTML += `<span>$data</span>`;

test(0);





Why this makes your function bad.



Saving state to a stack is great when you have complex or branching data structures that you need to iterate.



Saving an irreverent state on the other hand is not so great. In fact I would say using an aysnc function to step over animation frames via recursion is about the worst way to create an animation.



If you have 200 characters to animate by the time they have all completed (the last recursive call) you have 200 function states on the heap.



I would estimate that the memory usage of a 200 character animation to be about 200K +, though that is nothing, I have seen people chew 1Meg just to add two integers in JavaScript (crazy eh!).



Luckily JavaScript makes such wasteful resource usage transparent, by providing ample memory and a gaggle of resource management threads to contain and clean up so from your point of view everything is running slick..



Another way.



I am a little long in the tooth and come from a time where 1K was all we had. I can not write code without a device angel whispering thoughts of "conserve, speed and memory"



So I would have written your code as follows if the requirement was to use async functions, and assuming that the waitAfter value is many times greater than 60fps.



// Note dont need text position (n)
async function typeWriter(text, elementId, waitAfter)
var n = 0;
// Following DOM query only done once saving lots of time
const el = document.getElementById(elementId);

const wait = () => new Promise(r => setTimeout(r, waitAfter));

// Preventing re flow overhead by using textContent rather than innerHTML
const render = () => el.textContent = (text.substring(0, n + 1));

while (n < text.length)
requestAnimationFrame(render); // Calls existing function
// thus avoid unneeded function state capture
// via closure

await wait();

n++; // add after await so render gets
// the correct value




From an external view its behaviour is identical, from a resource point of view its is remarkably different, will much lower memory use and associated GC overhead upon exit. It can also handle any size text, unlike the recursive method was limited to the available call stack size.






share|improve this answer





















  • That was super helpful to me, thanks too much... unfortunately we as well as many -JavaScript developers- have too many resources to waste... 1KB should have landed a rocket the moon while now 1GB couldn't literally launch an Angular app smoothly!
    – Microsmsm
    Jan 17 at 19:35














up vote
2
down vote



accepted










Recursion is a state stack.



Function context



Every time a function is called JS creates a new context (function state), even if the function does nothing, creates no variables, has no arguments, only calls another function, it still requires its own context. The process of creating and pushing to the heap costs memory and processing time.



The minimum memory cost varies between JS engines, but 1K is a reasonable estimate for an empty context.



Note The exception is Proper tail call Functions that by nature of the return, may not require their own context, they use the calling functions context. (No browser current lets you use this ES6 required standard feature)



Recursive state stack



In general recursion is used as a way create a state stack. Each iteration (recursive) call creates a new function context, with closure that is pushed to the heap.



When the a function exits its state is deleted popped from the heap and the calling function's state is reinstated from the heap.



Example showing states pushed and popped



The following illustrates the state stack. The state includes a random value. Each iteration waits 200ms before creating the next. When the recursion exits each state is popped from the heap, the functions complete execution until the stack is clear.






 function resolveAfter200ms(x) 
return new Promise(resolve =>
setTimeout(() => resolve() , 200);
);
;
async function test(count)
const rand = Math.random() * 100
function log(data)
document.body.innerHTML += `<span>$data</span>`;

test(0);





Why this makes your function bad.



Saving state to a stack is great when you have complex or branching data structures that you need to iterate.



Saving an irreverent state on the other hand is not so great. In fact I would say using an aysnc function to step over animation frames via recursion is about the worst way to create an animation.



If you have 200 characters to animate by the time they have all completed (the last recursive call) you have 200 function states on the heap.



I would estimate that the memory usage of a 200 character animation to be about 200K +, though that is nothing, I have seen people chew 1Meg just to add two integers in JavaScript (crazy eh!).



Luckily JavaScript makes such wasteful resource usage transparent, by providing ample memory and a gaggle of resource management threads to contain and clean up so from your point of view everything is running slick..



Another way.



I am a little long in the tooth and come from a time where 1K was all we had. I can not write code without a device angel whispering thoughts of "conserve, speed and memory"



So I would have written your code as follows if the requirement was to use async functions, and assuming that the waitAfter value is many times greater than 60fps.



// Note dont need text position (n)
async function typeWriter(text, elementId, waitAfter)
var n = 0;
// Following DOM query only done once saving lots of time
const el = document.getElementById(elementId);

const wait = () => new Promise(r => setTimeout(r, waitAfter));

// Preventing re flow overhead by using textContent rather than innerHTML
const render = () => el.textContent = (text.substring(0, n + 1));

while (n < text.length)
requestAnimationFrame(render); // Calls existing function
// thus avoid unneeded function state capture
// via closure

await wait();

n++; // add after await so render gets
// the correct value




From an external view its behaviour is identical, from a resource point of view its is remarkably different, will much lower memory use and associated GC overhead upon exit. It can also handle any size text, unlike the recursive method was limited to the available call stack size.






share|improve this answer





















  • That was super helpful to me, thanks too much... unfortunately we as well as many -JavaScript developers- have too many resources to waste... 1KB should have landed a rocket the moon while now 1GB couldn't literally launch an Angular app smoothly!
    – Microsmsm
    Jan 17 at 19:35












up vote
2
down vote



accepted







up vote
2
down vote



accepted






Recursion is a state stack.



Function context



Every time a function is called JS creates a new context (function state), even if the function does nothing, creates no variables, has no arguments, only calls another function, it still requires its own context. The process of creating and pushing to the heap costs memory and processing time.



The minimum memory cost varies between JS engines, but 1K is a reasonable estimate for an empty context.



Note The exception is Proper tail call Functions that by nature of the return, may not require their own context, they use the calling functions context. (No browser current lets you use this ES6 required standard feature)



Recursive state stack



In general recursion is used as a way create a state stack. Each iteration (recursive) call creates a new function context, with closure that is pushed to the heap.



When the a function exits its state is deleted popped from the heap and the calling function's state is reinstated from the heap.



Example showing states pushed and popped



The following illustrates the state stack. The state includes a random value. Each iteration waits 200ms before creating the next. When the recursion exits each state is popped from the heap, the functions complete execution until the stack is clear.






 function resolveAfter200ms(x) 
return new Promise(resolve =>
setTimeout(() => resolve() , 200);
);
;
async function test(count)
const rand = Math.random() * 100
function log(data)
document.body.innerHTML += `<span>$data</span>`;

test(0);





Why this makes your function bad.



Saving state to a stack is great when you have complex or branching data structures that you need to iterate.



Saving an irreverent state on the other hand is not so great. In fact I would say using an aysnc function to step over animation frames via recursion is about the worst way to create an animation.



If you have 200 characters to animate by the time they have all completed (the last recursive call) you have 200 function states on the heap.



I would estimate that the memory usage of a 200 character animation to be about 200K +, though that is nothing, I have seen people chew 1Meg just to add two integers in JavaScript (crazy eh!).



Luckily JavaScript makes such wasteful resource usage transparent, by providing ample memory and a gaggle of resource management threads to contain and clean up so from your point of view everything is running slick..



Another way.



I am a little long in the tooth and come from a time where 1K was all we had. I can not write code without a device angel whispering thoughts of "conserve, speed and memory"



So I would have written your code as follows if the requirement was to use async functions, and assuming that the waitAfter value is many times greater than 60fps.



// Note dont need text position (n)
async function typeWriter(text, elementId, waitAfter)
var n = 0;
// Following DOM query only done once saving lots of time
const el = document.getElementById(elementId);

const wait = () => new Promise(r => setTimeout(r, waitAfter));

// Preventing re flow overhead by using textContent rather than innerHTML
const render = () => el.textContent = (text.substring(0, n + 1));

while (n < text.length)
requestAnimationFrame(render); // Calls existing function
// thus avoid unneeded function state capture
// via closure

await wait();

n++; // add after await so render gets
// the correct value




From an external view its behaviour is identical, from a resource point of view its is remarkably different, will much lower memory use and associated GC overhead upon exit. It can also handle any size text, unlike the recursive method was limited to the available call stack size.






share|improve this answer













Recursion is a state stack.



Function context



Every time a function is called JS creates a new context (function state), even if the function does nothing, creates no variables, has no arguments, only calls another function, it still requires its own context. The process of creating and pushing to the heap costs memory and processing time.



The minimum memory cost varies between JS engines, but 1K is a reasonable estimate for an empty context.



Note The exception is Proper tail call Functions that by nature of the return, may not require their own context, they use the calling functions context. (No browser current lets you use this ES6 required standard feature)



Recursive state stack



In general recursion is used as a way create a state stack. Each iteration (recursive) call creates a new function context, with closure that is pushed to the heap.



When the a function exits its state is deleted popped from the heap and the calling function's state is reinstated from the heap.



Example showing states pushed and popped



The following illustrates the state stack. The state includes a random value. Each iteration waits 200ms before creating the next. When the recursion exits each state is popped from the heap, the functions complete execution until the stack is clear.






 function resolveAfter200ms(x) 
return new Promise(resolve =>
setTimeout(() => resolve() , 200);
);
;
async function test(count)
const rand = Math.random() * 100
function log(data)
document.body.innerHTML += `<span>$data</span>`;

test(0);





Why this makes your function bad.



Saving state to a stack is great when you have complex or branching data structures that you need to iterate.



Saving an irreverent state on the other hand is not so great. In fact I would say using an aysnc function to step over animation frames via recursion is about the worst way to create an animation.



If you have 200 characters to animate by the time they have all completed (the last recursive call) you have 200 function states on the heap.



I would estimate that the memory usage of a 200 character animation to be about 200K +, though that is nothing, I have seen people chew 1Meg just to add two integers in JavaScript (crazy eh!).



Luckily JavaScript makes such wasteful resource usage transparent, by providing ample memory and a gaggle of resource management threads to contain and clean up so from your point of view everything is running slick..



Another way.



I am a little long in the tooth and come from a time where 1K was all we had. I can not write code without a device angel whispering thoughts of "conserve, speed and memory"



So I would have written your code as follows if the requirement was to use async functions, and assuming that the waitAfter value is many times greater than 60fps.



// Note dont need text position (n)
async function typeWriter(text, elementId, waitAfter)
var n = 0;
// Following DOM query only done once saving lots of time
const el = document.getElementById(elementId);

const wait = () => new Promise(r => setTimeout(r, waitAfter));

// Preventing re flow overhead by using textContent rather than innerHTML
const render = () => el.textContent = (text.substring(0, n + 1));

while (n < text.length)
requestAnimationFrame(render); // Calls existing function
// thus avoid unneeded function state capture
// via closure

await wait();

n++; // add after await so render gets
// the correct value




From an external view its behaviour is identical, from a resource point of view its is remarkably different, will much lower memory use and associated GC overhead upon exit. It can also handle any size text, unlike the recursive method was limited to the available call stack size.






 function resolveAfter200ms(x) 
return new Promise(resolve =>
setTimeout(() => resolve() , 200);
);
;
async function test(count)
const rand = Math.random() * 100
function log(data)
document.body.innerHTML += `<span>$data</span>`;

test(0);





 function resolveAfter200ms(x) 
return new Promise(resolve =>
setTimeout(() => resolve() , 200);
);
;
async function test(count)
const rand = Math.random() * 100
function log(data)
document.body.innerHTML += `<span>$data</span>`;

test(0);






share|improve this answer













share|improve this answer



share|improve this answer











answered Jan 17 at 16:04









Blindman67

5,4001320




5,4001320











  • That was super helpful to me, thanks too much... unfortunately we as well as many -JavaScript developers- have too many resources to waste... 1KB should have landed a rocket the moon while now 1GB couldn't literally launch an Angular app smoothly!
    – Microsmsm
    Jan 17 at 19:35
















  • That was super helpful to me, thanks too much... unfortunately we as well as many -JavaScript developers- have too many resources to waste... 1KB should have landed a rocket the moon while now 1GB couldn't literally launch an Angular app smoothly!
    – Microsmsm
    Jan 17 at 19:35















That was super helpful to me, thanks too much... unfortunately we as well as many -JavaScript developers- have too many resources to waste... 1KB should have landed a rocket the moon while now 1GB couldn't literally launch an Angular app smoothly!
– Microsmsm
Jan 17 at 19:35




That was super helpful to me, thanks too much... unfortunately we as well as many -JavaScript developers- have too many resources to waste... 1KB should have landed a rocket the moon while now 1GB couldn't literally launch an Angular app smoothly!
– Microsmsm
Jan 17 at 19:35


Popular posts from this blog

Chat program with C++ and SFML

Function to Return a JSON Like Objects Using VBA Collections and Arrays

Will my employers contract hold up in court?