Опыт написание музыкального сервиса на React и Tone.js
Good afternoon! I would like to share my experience of writing a web [royalty free music](https://taketones.com) service using React, TypeScript, Tone.js and (suddenly) PHP. This article is about performance issues, endless refactoring, and what finally came out.
Sometime before 2016, the activity of a web programmer was rather dull and consisted mostly of developing corporate websites on various CMS-systems. Now, the number of such jobs is still high, because someone has to maintain what has been written for many years🙃. However, in 2020, the web offers many more opportunities than ever before. The advent of handy JavaScript frameworks has made it easier to create complex interfaces and more and more functionality now depends on frontend developers.
I myself have relatively recently started writing web applications and using React and Vue.js. Before that I, like many others, used JQuery, cramming thousands of lines of code into a script.js file and attaching it to the footer tag.
The technology stack was chosen as follows:
React, Redux, TypeScript and Tone.js - client side;
PHP - the server side.
Why React and not Vue.js? To be honest, I don't really see the point in comparing the two frameworks because each of them is good in its own way. Tone.js is a wrapper for Web Audio API. And although the library is not that actively developing (last release was released more than a year ago), at the moment it is the only good tool if you don't want to work with Web Audio API directly.
The backend was written in PHP. It gives the frontend data (in json) about where the different instrument sounds are stored. Probably the best solution would have been to use Node.js and MongoDB on the backend, but this part was written hastily and without much thought, and in the end it got lazy to redo it properly.
Problem #1 Loading almost 100 MB of sound in *.wav format
The main challenge was to ensure that the user could quickly interact with the set of instrument sounds: synths, drums, bass, etc. It would be wrong to load all the necessary samples at once, because they are all stored in *.wav format and weigh almost 100 MB. Therefore, when starting the application, only the minimum set of sounds necessary to get started is downloaded. The rest are requested from the backend as the user needs them. Redux and Redux Saga were used to structure the server request code and component redrawing.
Problem #2 Artifacts in the recording
Initially, the recordings (especially from an old laptop) had excessive noise, it was constantly twitching and interrupted. The reason was that some components were being redrawn while recording from the microphone, affecting performance. Special features are available in the latest reacta updates to help optimize the application. Without going into details, I had to rewrite almost all the code using functional components and constantly use Reac.memo, React.useCallback, React.useMemo to eliminate unnecessary redrawing and re-creation of variables.
Problem #3 Saving songs to *.mp3
There is a project on github called Recorderjs. This library was written almost 5 years ago and can convert output of Web Audio API to *.mp3 format. However, if you are looking for a more professional video editing solution, you might consider using [DaVinci Resolve templates](https://taketones.com/video-templates/applications/davinci-resolve). After many experiments, I found out that it's not the best idea to convert sound from *.wav format to *.mp3 format with the help of browser. Therefore I had to convert the resulting track with the help of the LAME utility.
This is by no means a complete list of pitfalls I encountered when working with Web Audio API along with React. If you're interested in this experience, write in the comments or by mail.