You are browsing as a guest. Sign up (or log in) to start making projects!

gabriel_ferreira

@gabriel_ferreira

Joined June 16th, 2026

  • 29Devlogs
  • 3Projects
  • 0Ships
  • 0Votes
Just a guy addicted to programming.
(Im from Brasil btw, 16y)
Open comments for this post

7h 41m 13s logged

Improving the LCP (Largest content paint) performance

I am improving the way that the website create and downloads the images, the main reason is to make the user see something faster. Before the system were doing 2 main things:

  • Go trough the entire list of images, creating the elements and placing them into the page.
  • Position them.
    But the position of the items were being done after the creation of the images, in another function. Now they are in the same function: it create the element, position it and add it to the page.
    That does not seem like much, but the code got way faster with that, probably because it dont need to go item by item in an list twice just to create an element. I tested the time to load the first element and it went from 8.63s to 6.43s, the test was made with 2200 elements (Yeah ik, it is a lot and normally it isnt that much, but i had to see how they were holding with more than 22 items).

Also i fixed a bug that passed unnoticed while improving the responsiveness: At some point of images the visibility of the elements broke, that was because the perspective (what makes the 3D perspective of the component, and makes it visible with 3D effects) was based on the screen size, not the elements itself. What was the problem in that: Each element takes a size in the screen ‘makes the circle that shows the element be more and more near of our point of view’ (i cant explain it any better, search what is ‘perspective in an 3d element at HTML’ ). While it was approaching our point of view (POV), our POV were exactly at the same position (based on the screen size), so at some point the circle perspective would pass the POV and we would be unable of seeing it well. Now it is based on the elements: The 3d elements were basically a circle, i just used the diameter to change the perspective based on it.
TODO: Maybe i lowered the image quality too much… I will fix it in the next updates.
Also i were trying to improve the font settings to improve the performance, but that wast working so i decided to move on to this because it was more critical (took a while for me to jump to this, maybe like 2 hours trying and trying values in the font settings).
i am also working in a way to load the images in parallel, with that it will take way less time
(I didnt known about LCP before so i spent a while figuring out the way it works).

0
0
4
Open comments for this post

2h 39m 48s logged

Improving the performance

After finishing the improvements in the responsiveness, now i decided to improve the performance. I used lighthouse to get insights (i learned about it in an tiktok video) and figured out that the images size were too high (were an png of 1280x1280px), so i saw more about that in the page: https://developer.chrome.com/docs/performance/insights/image-delivery (an link that google lighthouse gave).
With that i saw how to decrease the size while staying with quality, i reached up to the sharp-cli tool, that makes the work of resize, convert and compress the image for me. The command used was that:

npx sharp-cli -i *.png -o ./output resize 320 -f avif -q 50 --effort 6 --smartDeblock --preset photo

The 320 is the size that i want it to be at the end, i got that value by seeing what was the computed value (the value that is being used in the website) in an high resolution pc (not the most higher one, the high but normal pc) with the resolution of 2500x1714px.
With this simple changing the image went from 2mb to 40Kb! Nearly 100% decrease, and take in mind that there is more than one img, so the change were even higher.
Also i created 5 different images: 320px, 480px, 640px, 960px e 1280px. With them the browser can choose which one is better for each device. With these changes i went from 35 points of performance to 59.

0
0
5
Open comments for this post

52m 18s logged

The home is now fully responsive

Ah that took a while, but finally it is fully responsive. Now the description at the player UI resizes based on the screen size and active a scroll behaviour when need, also i did some minor change at the emotionDrum perspective to make it show more emotions at the same time, removed the padding in the arrows at the emotionDrum so they will have more space and fixed an error in the genre drum that was making it perspective broke.
After all these devlogs i improved how i make a code responsive.

0
0
8
Open comments for this post

2h 32m 16s logged

The emotionDrum is now responsive!

Now the buttons that you use to select the emotion are in the same side as the div that displays the emotion, so they dont fight for space anymore. This change is meant to fix the low size of the items in screens that are too small, in the new way we have more free space to display the emotions, there is not much to say.

What else

I did some minor changes in the size of some items at the player area, now they are easier to read! (I increased the size of some items)

0
0
21
Open comments for this post

6h 36m 45s logged

Im nearly finishing the workings on the responsiveness. Now the entire player screen is responsive and do not breaks the texts anymore (except for the description area), also the buttons that show you the next screen (the ones that displays ‘player’ and ‘generos’) are responsive too, the music queue is working perfectly fine, and the area that is used to select an emotion is nearly responsive too, it just needs some adjusts in the two buttons that change the current emotion because they become too small and uses a lot of space when the screen is too small, after that this screen will be finished.
It is taking a really long time, the fact of how many different screen sizes exists makes it harder to finish, but now there is times that i even cannot see if i changed the resolution in some areas, because the system looks the same. I spent quite a while testing different resolutions and combinations of size, i didnt even noticed that i where 6 hours here, but now ik more about css (things like container-type + container based sizes and more ways to set the size of an text)
The video shows how it is now, if u want to see the before just checks the past devlog.

0
0
22
Open comments for this post

42m 34s logged

Finished the correction of the errors at the perspective and click in the cover-flow component. Now the perspective stays the same 150vw value (that is based on the screen width) and stays normal, with everything working. Oh man, that needed a lot of logic and out of box thinking finding another ways to check where the user clicked without using an normal click event listener (for those who lost the past devlog or didnt understood, i cannot use a normal eventListener in that because the clicks is detected in another element or in nothing, even with z-index or more in css, so the solution should be done entirely on javascript logic).
The first video is the new way, the second is how it was before all changes in it

0
0
7
Open comments for this post

5h 31m 10s logged

i finished the workings on the section of the home page that i where doing before, now has a good responsiveness for pc and a decent one for mobile.
Now im working on the main area of the home page, the one where the user selects the desired genre for the music (second img). It may looks completely fine, but that same element already was a headache before and is here again. The given area is the cover-flow component, before i already fixed it (or so i thought), but it was looking bad (the 3d perspective where a bit strange) and would probably broken if i added new genres.
I were trying to figure out a way to listen to the clicks in the card without any problems, that seems easy at first glance, but the 3d perspective in the element make other elements eat the click from one another, make the clicks dont be listened and so many problems that i nearly decided to erase it and write from scratch. I already found a way to do it by using the mouse position, the center of the screen and the card width (the genre img) to transform it in an value that can be used to select the exact card without any dependencies on the doom selector. It basically uses just some values, put in some calcs and get the difference between the current card (genre) index and the clicked.
Im nearly finishing it, but i still need to figure out some values and more.

0
0
3
Open comments for this post

1h 10m 38s logged

Im improving the responsiveness at the home page (before was the player page), but for some reason that idk the emotion selection div is having a strange behavior, i will update what it is after i fix it. Take a look: (the item in the center should be centered)

0
0
18
Open comments for this post

43m 30s logged

Hi again! Like said in the past devlog, im improving the responsiveness of the website, specifically in the player part. But it had some problems and where distorting when playing an video, now it resizes based on the screen size in a way that it stays ¨normal¨.
The first video is the new way, the second is the old way.
It still needs a lot of improvements, but it is going!

0
0
8
Open comments for this post

1h 27m 47s logged

Making the website responsive

Hi again! Like i said in some devlog, the website dont have support for mobile, that was because it was designed to be at kiosk mode and work just in desktops. but i decided to change that.

First of all: the site where using a lot of absolute values of dimensions, so it where braking even in the desktops (it wasnt responsive at all). But i spent a while changing it, it is isnt ready and has some problems, but is better than before.
(The mobile is still strange, i did not started fixing it yet).

Credits:
https://css-tricks.com/snippets/css/fluid-typography/ - This website shows about a way to make the texts become responsive for the screen using some calcs, it is worth seeing.

The first video is how it was before, the second is how it is now

0
0
20
Open comments for this post

47m 40s logged

Creating a new helper

Context: There was an class called youtubeFrameControls, this class basically where designed as an structure to help using the youtube iframe API, but with the time this class where becoming basically to hold just an function (and in a very inefficient way), because the methods that it had before (like the one that runs when the iframe is loaded) had to have more and more specific logic in the codes that used it, so they where useless (because the codes that where using it where rewriting it).

What i did: I picked the only function that where being used and transformed it in an helpers (that can easily be customized). This function was the one that creates the player of the musics, and the function where called createPlayer. Also i removed the old class (youtubeFrameControls) and replaced it for this helper in every place that used it.

It now is way more simple than before and can me more customized.

0
0
39
Open comments for this post

2h 9m 37s logged

Refactoring the copa script

I where placing some scripts in a class. These scripts are related with the player functions of the copa script, so i pick all of them and placed in the same class. I did it to follow best practices, but i confess that i still got some doubts about when to create an class and when the variable or method should be static or private (#property), i will search and learn more about because maybe i will have to refactor some parts of the code following these rules of best practices. That was all for now, see ya!

0
0
57
Open comments for this post

2h 28m 28s logged

Adding more bug checks

I added some checks in the player class at the startExplication function that checks if the src (the url for the audio) is valid or not by doing an fetch with the HEAD method and checking if the return is an valid audio before trying anything in this function. Also i solved this error in the same function:

Uncaught (in promise) AbortError: The play() request was interrupted because the media was removed from the document. https://goo.gl/LdLk22

This error was because the startExplication function where trying to play the audio before it was loaded, i solved it by making it play the audio just after it was load with the event listener canplaythrough.

There was another error at the playMusic function where the code where trying to play the youtube video before it was loaded, i solved it by making it wait until it was CUED (Where the video isnt playing, but is loaded and showed).

(The website was not created to be in mobile and dont has a lot of support, the video where recorded in my smartphone because i had to record the audio and the audio on my pc dont work. In the Future i Will add mobile suport, but right now im finishing the bugs and etc)

0
0
20
Open comments for this post

2h 47m 41s logged

Adding a new description feature

So basically there was an place where was designed to have the description about an music, but that was empty and where only finished today

What it do

It is petty simple, it just show an text about the music that is currently playing, also there is an audio that plays before the music starts playing, but this audios is played just one time before the music so if someone loses it or didnt listen well there was not a second chance to listen for that audio. Now there is this place that holds the same content, but in the format of an text that can be read whenever they want while the music is being played, that was what i added.
Also that text can be hidden, so it will not stay using half of the screen every time (in the screenshot it is active)

What this audios do

This audio / text is part of the main purpose of the website, they give some fun facts about the music that may be useful someday in some kind of quiz or essay.
Also the audio is played before the music and the music plays just after the audio finishes. That is to make whoever is listening listen to the entire audio before having what he (or she) wants, so they will not listen to the music and skip the audio.

0
0
21
Open comments for this post

1h 23m 28s logged

Studing about cache

So basically i where studing about cache, the main ideia was to implement it in the sistem, but then i realized something:

  • Theres is nearly no difference between cache and a normal request in an localhost project, adding the cache would not improve anything, sometimes it maybe even slow the website, because the page would need load more code.

I realized it afther a while studing about it, but anyway lets focus on another thing.
Also i where studing with google for devs: https://developer.chrome.com/docs/workbox/caching-strategies-overview

0
0
12
Open comments for this post

1h 1m 1s logged

Toast applied and tested

The toast notification component is now being used at the player class, i did some tests and it is working very nice, hopefully the user will not see it very often (because that would be a problem, the user must not see it unless there is an error playing the music).

But why did i make it?

It is used to show more about what is going on for the user, so they will not become anxious if it something is working or not.

Why not use another notification system?

Each notification system has its own use cases, the others would be very painful for the user. Imagine every time a simple error (that is simple for me) like the music fail to play there was an error that interrupt the use of the app with an popup or alert, that would be painful, dont it?
That is why i used an toast notification, because it is temporary (disappears after some seconds) and dont stop the use of the website.

Also there is a feature that i implemented for the same reason a few devlogs ago that add a fallback in the music search, so it wont show a message at every single combination.
Lets calculate how many combinations we have: there is around 50 musics in the database, 22 genres and around 40 emotions, multiplying the genres and the music 880 combinations that the user can make. Now lets see how many musics we can get: each music have around 1.2 emotions and 1.2 genres, so we get 72 combinations that lead to an music. With that in mind, we can see that from 880 combinations, just 72 of them are useful combinations, so we get a 8.18% for getting a music, and 91,12% of not getting one. Consider that each failed attempt shows an error that stop the use flow of the website, but that was before the past devlog, now it tries again and again and only afther failing everything it shows an error, at that point it must really show an error.

Thats all, sorry for the long boring text and thanks everyone that read, see yall later

0
0
12
Open comments for this post

3h 8m 1s logged

The toast notification is finished

So i finished it, it is a component that u adds in the code that u wants to use. I added 2 icons, 1 for infos and another for warnings.

What i used and did

The element that holds it all is an dialog, the icons are svg, the text is a span and the element that shows the time left is an progress.
To update the time left i used an setInterval that runs at a 10ms delay and deduce 0.01 of the dialog value, so it will be smooth to see. Also there is an if inside that destroy the element and clear the interval when the value of the dialog reaches zero or less (In the past devlog i said about not using an if, but considering how low the cost for an if in that time is i decided to use it anyway).
The function that creates the toast receives some params that will let it be customized by whoever is calling it:

const icons = Object.freeze({ 
INFO: infoIcon(), 
WARNING: warningIcon()
});

function createToast({ message, time = 5, styles, icon = icons.INFO })
// the `message` is the displayed message
// the `time` is the time until close
// the `styles` is custom css styles for the element, it uses the dictionary format {}
// the `icon` is the svg icon

What else?

I will apply it in some elements and post about. See you later!

0
0
15
Open comments for this post

1h 35m 44s logged

Creating a toast notification system

So rn im creating what i said in the past devlog about a toast navigation. This isnt finished yet, im still figuring out an way to check the end of the timer, i found some ways to do it, like using an simple if inside the countdown. I didnt comment but i am using an setInterval to decrease the time and an <progress> tag to show the value

but that is a bad ideia, imagine doing 1 if every 50 ms? that dont cost a lot of processing power, but i still will search for other ways to do it just to check, if yall got any hints or ideas leave a comment.
Also i will improve the design, the design is petty poor.

0
0
5
Open comments for this post

4h 14m 18s logged

Fixing errors and adding bug checks

Hi everyone, so i were fixing some bugs that i saw that may broke the app, i fixed all of them (for now), here they are:

  • There was a logic bug that a class (the one that controls the youtube iframe) where doing stuff that it wasnt supposed to do (not an unexpected behavior, but a logic that should be outside of it), it was an easy fix.
  • There was a bug at the player class that when the provided sourceId (for the youtube iframe) where wrong or unable to use it crash and stopped doing anything else (like playing another musics). I tryied solving it in various ways, one was beffore the changes that i did in my last devlog, but i failed because the class that holds the player where hard to fix, this devlog fix it. I fixed it by adding some bug checks and, when some error ocurred, it play the next music.
  • There was also a bug at the player class and youtube-iframe-controls class, that for a couple seconds in the start of the website it would broke if u tried to play a music. It was because in the start of the program the youtube API where unable to be used. To fix it i just made it wait until the API where ready using an ASYNC function.
  • There was also a bug that, afther the past devlog, it was doing and request at the /api/songs with params at the wrong format. Afther the past devlog the API started using the params genre_id and emotion_id, but the frontend where passing with the incorrect name (genre, emotion).

Something that i implemented

  • I upgraded the mysql query that where being used to get more infos about the music, before it where just returning infos like name, author, sourceId, etc, but now it also returns the genre and emotion from that given music.
  • I added a bug check at the player class, now if it fails it pass to the next music.

Something that i want implement

I want to implement a simple toast notification system that will apear when something fails, like the playing of some music.

Others

The youtube docs for the iframe where very helpful for this changes, check it out: https://developers.google.com/youtube/iframe_api_reference?hl=pt-br

0
0
51
Open comments for this post

3h 15m 48s logged

Optimizating some piece of code

So there was a certain part of the code responsible for the songs queue in the main route, that piece is a core function but where running a while true loop for no reason, here is the part:

async start() {
    while (true) { // { emotion, genre, author, name, sourceId }
      const musicData = await this.#musicQueue.get();
      this.createPlayer(musicData['sourceId'], null);
      this.#showMusicInfos(musicData['name'], musicData['author']);

      this.#queueList.removeChild(this.#queueList.children[0]);
      
      await this.#startExplication(`/storage/${musicData['explicationSource']}`);
      this.player.playVideo();

      await this.#musicFinished.when(true);
      this.#musicFinished.set(false);
    }
  }

Basically the code were calling it at the start and running it forever, but that code where a nightmare to maintain / implement, i tried to implement a safe check here for over 2 hours, but wasnt possible.
I replaced it for a more efficient approach that do a loop in a different way, here it is:

  • when adding a music, it checks if it is already playing, if no starts to play.
  • when start to play it checks if there is a music in the queue for it to play, if no it stops playing, if yes it get it and play.
  • When the music that is playing ends, it call the play function (from the above topic).

That is just it, no while or constant loops, no overhead, it works by basically connecting all the codes in a way that they work together to maintain (or stop) the loop (notice how i said loop, it uses a loop but isnt a while or for loop, it connects the end of one code and the start of another, like a chain.
I made it in the pull request #2, check it out: here

0
0
10
Loading more…

Followers

Loading…