 an API request, and got something back. That object isn't type checked. But this project will help you with that. It's called typescript is. And here it is on npm. And yeah, it takes some setting up. So that's the difficult bit. But if you can get it set up, then I think it's not. So it's quite friendly to use at runtime. So this is how you would check if this object is this type. OK, so there you go. Typescript is. There's another thing about typescript, which is if you really want to use typescript, you have to change your JavaScript file into a typescript file and add all these things which are not real JavaScript. But Facebook's flow does it so that you can just add all these extra things in comments, which is kind of nice because then your file is still a JavaScript file. And people who don't use typescript can just use your file as normal. They don't need a compiler or anything. And there's been a long discussion on GitHub. People ask me for this. But anyway, somebody has come up with a hack that does it. And he's called it plus typescript. So if you're interested, you can go check out plus typescript. And that will compile a file that has all the typing in comments rather than the JavaScript file with just the types in the comments. OK, that's my JavaScript news for you. Hope you enjoyed. Now we want to give a shout out to engineers, SG, who are very helpful hosting us on Zoom and recording the talks for us and uploading them. So go over to their website. Go visit their website. You could also find out upcoming meetups on their website. And if you love them, you can volunteer with them and give them a hand. OK, this meetup, Singapore, talk.js, we have a couple of telegram channels. I mean, good luck typing that in. But there it is. If you want to join the channel, maybe I can put that in the chat later. Yeah, OK, and we have a bunch of links. Actually, it's probably easier. Go to linktree, Singapore.js. And we have a bunch of links there. If you're interested in presenting in one of our future events, it won't be next month. December, we're having off. We're having a break. But in January, if you're interested in speaking, if you have something on to share, then just come over to our GitHub page. And you should see an issue for January. And you can post your talk proposal on there. Also, if you would like to volunteer to help us out, if you think you can host better than me, go ahead, please. We have some things we're trying to improve with the repositories and the website. So if you want to help with that, you can. Yeah, yeah. Right, I usually give a shout out to some other meetups. But this page, I have not updated. So I don't know what's actually going on this month. But this meetup exists, Junia Dev SG. This meetup does not exist anymore, although it kind of does. This one, I went to once, that's Google Meetup. You could go to that one. Check it on meetup.com. Talk CSS finished last month. But their meeting is still on YouTube, if you want to go and watch it, or on Engineers SG. And I'm imagining this is still going, React.js. So you might want to check out what they're doing. OK, we're going to start the talks very soon. So get your notebook ready. Because when the talk is happening, you might think of the question. But the talk is so interesting that at the end of the talk, you might have forgotten what your question is. So write it down. I'm not saying you're forgetful, but I'm forgetful. During the Q&A, if you want to ask a question, don't forget to unmute yourself in Zoom. Or if you're feeling shy, you can just type your question into the Zoom chat. We can all see it. As I say, we're going to have short Q&A, two or three questions after each talk. And then we will have a free for all at the end. OK, so let's go into the talks. Guna, are you ready to go? Yeah. Fantastic. OK, so Guna's going to talk to us about quad trees in maps using D3. Over to you, Guna. Thank you. So let me share my screen. So I'm going to talk about quad tree and its implementation on maps using D3. So let's get on with the topic. So before going into the talk, let me ask a question. So this is a map. I've searched for some cafe, and I've found a lot of results. Can anyone guess the number? I'll give you some time if you can try to come. Guess the number of cafes. I think there's 15. 15? OK, that's a nice guess. 16 from the channel. Is this a trick question? Is it we didn't disbounce? OK, 13. We didn't disbounce. I'm guessing 265. Oh, that's a huge number. OK. So yeah, my name is Gunaseel Narayanan. I'm a front-end developer. I work at JFrog. I go by the name Guna. You can call me Guna. That's my nickname. And these are my Twitter and GitHub IDs. You can connect with me. So before going to the talk, there is one more thing I need to tell you. So that is a page, jfrog.com, slash show notes, where you can see the slides. The slides what I'm doing today will be uploaded there. You want to see, you can go ahead and see there. And you can rate my talk. And the video of the talk will be uploaded there. And also, there is a raffle. So you can fill the form. And if you win the raffle, maybe you will get a JFrog t-shirt. You'll be contacted by you. There's a QR code here. You can just scan it. And it will directly lead you to the site. Even if it's not up now, you'll get to see in a bit of time. So maybe you can take a picture if you want. I'll give you a few seconds. So let's get on with the topics then. So today, we are going to see about what is clustering. So let me explain what is clustering. And then we'll go into what is a quadtree. And then we'll see how we are going to implement clustering using quadtree on maps. And then we'll get on with the demo. And last, I'll tell you why I didn't use other libraries. There are many API libraries which provides the API for clustering. But why didn't I go with it and choose to do it on my own? So first clustering of markers. So here's the answer. There were 22 markers. So I hope the 18 was the closest one we got as an answer. But yeah, that's the whole topic. There were seven markers in a small place. And it's not easy to see because everything was placed upon each other. So that's why you were not able to see. That's totally fine. So let's see why we are going to implement clustering and what's the advantage of doing clustering in a map. The first one is visual help. Obviously, when you have a lot of markers in a single place, it's going to take up or hide the whole space. And doing clustering, what you're going to do is you're going to just group every one of them to do together and place a number or something determining these are the number of markers that are in the place. That is one thing that's going to improve. And the next one is heat maps. So you would have seen weather forecasting in news and maybe a tornado is happening. You can see the center spot highlighted in red color. So heat maps are shown by the amount of attention each area is getting. So by clustering, you'll know how many markers are things that should be placed on a particular place. And using that, you can maybe color the particular place. So clustering helps in heat maps as well. So the last but not the least, the performance improvement. Think of some 100 to 200 markers in a particular point. And if you're going to show everything, that's going to occupy a lot of browser memory, right? Because markers are nothing but a SVG node. Each marker will have two to three nodes of SVG, whatever depends on the graphics that you're using for your icons. And that's going to occupy a lot of space. Suppose you're going to have some 1000, 2000 markers, then it's going to impact your performance. So by clustering, you're going to avoid that protein. So this is a Google map. I took a GIF from a Google map where you can see in Australia map, you can see that at first, you saw only some 15 markers, right? But when you zoom in, it's going to its perspective place, perspective place, and you can see how it is displacing. So while clustering, you'll also have to consider how to displace it when you're zooming it because simply clustering, it won't offer you a lot because it's just going to show the amount of attention or markers in a particular place. And if you're zooming in, it has to go to its respective place because by clustering, what you're going to do, there are two markers in a small place. You're going to put it down in a single marker in the middle point actually. So when you're zooming in, it's going to displace to its own place. And there you have to consider, again, you have to use a box to determine if two markers are again falling into the same place. So this is how we are going to do clustering. Next, let me tell you how or why QuadTree is used. So QuadTree would have studied in your academics. It's nothing but the tree data structure algorithm. So what is a tree data structure, right? So each parent node will have multiple children nodes. That's how a tree data structure is. And QuadTree is exactly four child nodes. So each parent node will be divided into four child nodes. So then each other node will be divided into four. That's how a QuadTree data structure representation is. So consider this square as a whole parent node that you can see four equal child nodes. And again, what happens is this node can be differentiated into another four child nodes. So that's how QuadTree works. So to show QuadTree how it works and how the objects are formed using QuadTree, let me show you a quote pen example. You can visit this to play with it later. So here there is a plane. This is nothing but an SVG. And here I'm going to show how QuadTree nodes are formed. So let me keep a point here or maybe I'll put it on the corner. Let's explain it easier. Okay, so there is one node now. So now I'm going to put points in each of the four boxes that we saw here, right? So each box has one point now. As you can see here, when I hover over it, you can see the highlighted point there. So each one has its own node now. A parent node is divided into four. So now what I'm going to do, we have each four points on each of the boxes here. Now I'm going to divide this box into another four points. So what I'm going to do, I'm going to place another three. As you can see here, this box is again divided into another set of child nodes. See here, these four come under this, oh sorry, I clicked on somewhere, my bad. So yeah, this is how tree structure for QuadTree works. I hope this little bit explains how the nodes are formed. So that's what I wanted to show about QuadTree and what is clustering. Then now let's see how we are going to implement clustering using QuadTree on maps. So why I used QuadTree? First of all, is D3 offers API for QuadTree. D3 is a library that, it's a very vast library. You can use it for almost many things, mainly for visualizations. So here for map visualizations, they offer API called QuadTree. So using that API, I'm going to use them. I'm not going to devise my own thing because again, it's going to take a lot of time. The main thing is we want to cluster them. So yeah, so what I'm going to do, the SVG points in a map is nothing but X and Y coordinates. There will be X point and Y point. It starts from zero comma zero and we'll have an array of points with the coordinates. And what I'm going to do is I'm going to send it to the D3 API where it is going to form an array based on this structure by what point I'm sending it to. So next, what I'm going to do is you have to separate each your map into a square, based on the zoom level. So here, you can see the image here. The map of USA has been divided into multiple squares. So the size of the square, you can determine them based on the zoom level. I'll tell you why that is important. Because now, as you can see, the points that are falling under one square, you are going to group them together. But when you're zooming in, you have to, the sides of the square should be a little more smaller because when you're zooming in, I'm going to zoom into this particular spot. I don't want to see again the group one. So I'm going to divide the whole map into smaller squares. Based on that, the clustering will be formed. So that you will, when you move in, that will be less number of clusters forming based on the size of the square. Okay, so once that is done, what we are going to do, we are going to traverse through each of the squares. And we are going to see if there are points inside the square using D3. Sorry, using the quadtree object that we have made. And once that is done, you will have an array with a group set of nodes. For that, you can add a single marker for the group elements, maybe with a number or a color, how much, however you prefer. So this is a small code snippet. Here you can see D3's quadtree API where we are sending the data points. And what you're going to get is a quadtree object. The quadtree object has its own attributes and it's also going to have the data points as well in the structure of the stream at the three wave. And here what I'm going to see is the cluster range. The cluster range is nothing, but the size of the square. So at each zoom level, you're going to calculate the size of the square and that is the cluster range. And based on that, it's going to see what you're going to do is quadtree.visit attribute method. So using this, what you're going to do, you're going to send the node, the edges of the square. And based on that, you can be able to determine whether a node falls on with another node. So all these things will be grouped together. Again, you can group it together and you can calculate the center point because when you're going to group these four together, you don't want to have the point, any of the one markers place, right? You want to put it on the center of all the points. So you can calculate that as well. And using that you can create, you can add a marker for that place. So yeah, so let's get on with the demo. This is a JFrog platform deployment. Here you can see we have a dashboard and we have a topology screen where we show the map and whenever a user adds another deployment to this one, they can connect two or three more deployments together. When they connect it, you will be able to see the deployments here. As you can see here, I have added one in Mountain View, one in Buenos Aires, and I have added two in Israel and I have added three in India. So here as you can see, you can select the deployments and it's going to show you information like the link to the deployment and the status, the storage capacity and all that information will be there. And what else we are doing is, as I said, we are grouping the markers together using clustering. So here you can see three in India. So I'm going to zoom in, as you can see. Now they are, you know, in New Delhi might be here and Ahmedabad, Mumbai might be here, but it's all shown together because the map is zoomed out and the place are pretty close back. So if it is shown at their own places, it will be overlapping. So that's why they're clustered. So when I zoom in, as you can see, it's getting displaced. The New Delhi icon went to its own and Ahmedabad, Mumbai are still close together. So they are still grouped together. And when you zoom in again, it's going to again displace. So as you can see, based on the zoom level, the clustering will change. So here the zoom level of these two places, sorry, the distance between these two places are minimal. So it was not displaced even after some zoom in, but it got displaced at the end. So that's how clustering, you have to implement clustering. And when you zoom out again, when it's the distance between them is reducing, you can again cluster them together. So one more example I can give you is of Netany and Tel Aviv. These two cities are separated just for 31 kilometers. So it's going to be very close to each other. And when you're going to add zoom, it probably will set a zoom limit as well. So since the zoom limit is still making the markers still close to each other, it's not getting separated. So you can consider that as well when you're setting a zoom limit if you want to see. So that's about the demo. So let's see why not use map EPS and like this. There are numerous map EPS libraries available. Those are very good actually. Not taking anything away from it, but why I didn't use it? Let's go with that first. So these are the map APIs I considered before moving on to design it on my own. Leaflet, Mapbox, Google Maps API, these are really good. I guess there's a team working behind it and obviously it's going to be maintained better than myself. So it's going to be a better option. So first thing I considered was framework granularity. So here, these again, Leaflet and Mapbox, it's going to come up with its own set of libraries that it's going to use. And since our application is very big and we already use a lot of libraries, we have to consider that as well. So even if you are doing, you have to consider framework granularity as a thing to pick up libraries, that is one thing. And you're restricted to the APIs available. So here, all these libraries comes up with their own APIs. You're going to use them whichever way you want. Maybe you're fine with it, but you will be obviously restricted, maybe not now, but in the future, you might be restricted to use those only. You will not be able to do something on your own. Your team might come up with a different scenario where it has to work like this or work like that. You won't have the freedom to do that when you're using a library. So that is one thing. And integration with other visualization. So that is the advantage of using D3. D3 as a library can be integrated with almost any visualization library. So you're going to have a lot of benefits using D3 alone because it has to have the total control of it. So however you want, you can redesign it. It's not going to stop you from anything. So that's the main advantage you should consider as well. So yeah, so that's it for my presentation. I can ask your questions. Okay, so the first question, is there any particular advantages? Okay, you are not limited to it. As I said, Quadree is just a algorithm that is beneficial for clustering. So that is one thing. If you think Hicksagree is even more beneficial, obviously you can try it. There is no stopping you from doing that. Maybe even if node or single link list or double link list, that's it, we can do with it as well. It's, you know, you can choose your thing. But D3 offers Quadree, so that's why I chose Quadree. That's one reason. I hope that answered your question. I was also thinking about the partitioning because with a Quadree, where you first define the position of the grid, that defines where all the lines are going to be. And it may be that a line cuts through the middle of a city and splits the things in that city into two. I was wondering if, yeah, and it might make sense to group all the things in that city in one place. It might make more sense to a human to see them all grouped together. I was wondering if binary partition tree might work better, but I don't really know. Because I think that could sort of draw the line anywhere, but it would put half the things on one side and half on the other. So keep close things always together. I'm not really sure about that though. Yeah, that's a, maybe, yeah. But the thing why Quadree, I guess was more helpful here, probably is the way it searches everything. So maybe, yeah, binary search offers a better way, but maybe I can take a look at it. Quadree is more suitable for, you know, a plane. Quadree, you know, offers better search algorithm when it comes to partitioning of space and time. So that's an open question, I guess. Yeah. Do we have any other questions? Anyone want to ask? Anyone, oh, there's the t-shirts. There's the t-shirts. If you want a t-shirt, is that a superhero frog? Yeah, so we have a superhero frog for each year. So this year it is Iron Frog. So the year of Iron Man. Okay, and what did Jay Frog do? Okay, so Jay Frog offers the product called Artifactory for DevOps end-to-end. We have a lot of other products as well. We used to have Artifactory as a separate product and offer other products for customers, but now we have a platform called a Jay Frog platform where we have all the products together. So Artifactory is one among it. We have distribution, we have pipelines, CI, CD pipelines offered through Jay Frog itself, and we have dashboard, which is called Mission Control, which offers the view of all the topologies and you can even have, look at the trends, the usage of whatever is used and all that, a lot of apps available. Okay, interesting. Okay, if anyone has any more questions, maybe they can save them till the end when we have the open mic. Thank you very much for your talk, Guna. Let's go on to 10's talk, a note on the browser. 10, are you ready to go? Yep. Let me share my screen. Okay. Thank you very much. Yeah, sorry for my messy desktop, if that triggers anyone. Okay, how do I, where is the present button? Okay. So, yeah, hi, I'm 10Z. So my name is 10Z Yang and ZY is kind of my initials. So that's why people call me 10Z. And today, I did change the name of my talk last minute. So sorry about that. It's the sounds of JS and instead of a note on the browser because I wanted to use this graphic. So a sound of music, sound of JS. So, in our science class, we learned that music is kind of like vibrations that are sent through some medium. And in this case, when we hear it, it's usually the air to our ear drums, right? And this vibrations in our ear drums are then converted into electrical pulses and sent through our nerves. So this is like the visualization of how the vibration looks like when it hits the air particles, air molecules. And this, but this is not particularly useful for analysis. So usually we represent them in the form of a wave like this, right? So the musical note is just the same as any other sound but vibrating consistently if at certain frequencies. So the Web Audio API can make use of certain mathematical functions or it just takes in audio source and whatever to play anything related to sound. But I also found out that it's not very easy to use without some kind of background in signal processing. And yeah, so when you wanna work with the Web Audio Playground, you usually work with this context, our operations will revolve around the audio context. And so this Web Audio Playground isn't built by me, so just to put it out there. It allows you to kind of visualize what it does to your sound. You can add the analyzer, you can build it in a graph like this. And you can see that Web Audio API can have multiple input sources. It's represented by a graph. It can have multiple notes that it connects to. In this particular example or in this particular program it only outputs to one output but you can actually output it to multiple sounds to do things like surround sound, 6.1 or four channel, two channel and mono. So here are four ways to play sounds and I've built it in a very small compact, or the simplest like vanilla JS implementation of playing sounds on the browser. So here I will start playing some audio sounds for my example. So if it's a bit loud, please, you might want to turn down your volume. So this first one is playing audio using audio elements. So I chose a file upload because it's just easier to practice with. So let me see. I should have just things in the way. Okay, nevermind, I can't find the file that I was looking for. Is it in the desktop? Yeah, yeah. That was really, really loud. But so basically as I said, you create some, you get some audio elements. You change the source, you load it and then you play it, but you need to connect. Where was the, let's see. Yeah, so I'm connecting the audio source to the analyzer and then the analyzer to the destination, which is our speaker. And so the analyzer is the thing that shows the bars moving up and down. So that's one way of playing. And the next way of playing, we have this one I believe is audio buffer. So previously the audio element is one of the easier ways to handle audio because it just gives us a nice HTML element that we can call, add a source and then just play from there. But if we want to be a bit more fancy, we can do things like adding audio buffer. So audio buffer is really, really good to play short clips of music because it's stored directly on memory and playing the short clips of music multiple times or in a loop. This is particularly useful for that. I'm not going to do that example because it's too loud and there's no volume control on this example, but you can kind of see, you would actually need to start, choose to start at a particular time value and there are some finicking to do to get this audio buffer things to work. So the next way, which is, this is using the microphone. So I do believe this example should be, yeah, yeah. So now there's a double, there will be a double voice. Double voice, yeah. Okay, so this one is pretty, also pretty simple. I think the Get Musor media has changed a few times over the past couple, the past year or so. So this might be a bit different by the time you might want to play around with this, but this basically takes in the audio input because I've run this example on my computer before I've already given permission. So anytime a website requires your voice or your speaker, it will usually ask for permission in the, your browser will ask for permission. So this doesn't happen in this example because I've tested it before. And finally, the last one, which is a huge part of my talk is the oscillator. So the thing about the oscillator is you pass the mathematical function in, in this way, yeah, you pass the mathematical function in and that will affect the kind of sound that you're playing. And also the other thing is you can change the frequency and things like that. So this is also really, really loud, so I won't play it, but yeah, this is the basic example. So with the oscillator, right, I wanted to create my own synthesizer so how do I get to play musical notes from numbers? So after some research, I found that generally the musical notes are usually represented by hertz, right? And that's how, that's basically for each of a wave, a type of wave, how many times does this wave appear? Let me check if I'm saying nonsense here. No, I didn't write it down. Basically it kind of represents how many times this wave happens in a short span of time. So A4, which is the most, A4 is generally a kind of useful root note that a lot of people use to base their apps or whatever when they want to do, to represent when they want to have some mathematical function involving music. It will start from A4, which is 440 hertz. And one thing about the music notes in general is that there are actually 12 notes, one, two, three, four, five, six, seven, eight, nine, 10, 11, 12 notes in Western music. Interestingly, this is actually mostly cultural. So there could be some other cultures in different music that have different gaps between the notes and what sounds in tune and what sounds out of tune. But Western music is generally accepted the 12 equal 10 per minute. But one thing that is not cultural is that two notes of double, one that is double or half the frequency will sound the same. So this is what we call, consider the same note in a different octave. But this is because the wavelength happens to be in sync with each other at every alternate phase. So one way that we can use to calculate this is we're given some root note value. And then we get, so we get a predefined root note and then N is the Nth note from the root note. And then to figure out the constant A, we will just use this formula basically to calculate. So there's some math behind when you want to do some musical notes. So I believe, I believe, yeah. So you should be able to extract out the, simplify it and get some constant. And this is how I got this thing. And this gives me a way to separate the oscillator into different notes. And yeah, and then I will set the note at a certain time when it's playing. So it will change, it will change the note halfway through. If let's say you change, you call this function halfway, it will change the frequency of the wave and then play a different note. So this gives me this, which is actually built by me. So this is going to be a bit loud. So the automaphone is based off this musical instrument synthesizer called automaton. And it looks like this. You might have seen it before, it makes this really, really with kind of saxophony kind of sound. And the thing about the automaton that is so interesting to me is that with ukulele or guitar, you kind of have frets that determine like you can play this note and you can play this note. There is no kind of microtonal in between kind of things. With a violin, you can actually achieve microtonal. So you can do like vibrato, right? But in a violin, you can do vibrato just by sliding up and down. So that's a different technique. And so the automaton can do that. So I tried to emulate that. So this is the, I think this is a, I think A4 is somewhere. And you can do the vibrato kind of deal. So you can change the different sound waves. And I've added another thing here for constant. So this is like kind of like auto tune, I guess. So to make sure that you start to break note. Right? And then this is to consistently keep it in tune. Yeah, so there's no microtonal anymore when you flick that. So that's all that math goes into this example. But one thing that I realized was the sound that we heard was actually the sign wave, which is that basic mathematical wave that we play around a lot. So I was trying to get a, how to sound more like the actual musical instrument, right? Not just a sine wave. And one thing I found out was that you can actually kind of build any wave that you want out of multiple sine waves. And so all waves are sinusodial, or at least it should be sinusodial. That's what we are assuming. And you can approximate it with some kind of a combination of waves. And you can do anything you want like the picture of Bart Simpson over here. So MP3 file format actually does exactly this. It chops a song into millions of sections and determine important frequency components. Jung those are unimportant until it's done. What's left is our most important frequencies and then it plays into our ears to represent the original track. Yeah, so to achieve this is called a Fourier. We use something to do a Fourier transform to get the, from a given wave we will convert it into some sine waves. But now I want to do it the other way around. I want to do reverse Fourier, if you will. So there's this function that is provided by the Web Audio API. You can set the periodic wave. And this gives us two inputs, real and image. This actually is the Fourier, I don't think it's mentioned here. Yeah, I don't think it's mentioned here. But basically these values are called Fourier coefficients when you want to construct a wave. And yeah, so how do we get the Fourier coefficients? So using this particular thing, this huge chunk of math where we can get some kind of a, given a Fourier series, I can visualize the wave and then I can try and emulate the kind of sound it comes with. So this gives me this kind of deal. So I can add the coefficients, right? And then I can play the waves a bit and it will kind of affect the thing. So the sound is quite different from the sine wave that we heard just now. And this gives us the ability. So one thing that I can do as an instrument. So this tool gives me something that I can save the Fourier coefficient and then going back to the automaphone, we can actually load the Fourier coefficients that we saved should be loads, right? Yeah, it's over here. So it's just in a JSON file and then now you can, oops, that's a bit loud. Turn down the octave. So just by playing around with these numbers, I can actually get a automaton kind of sound and then now that particular Fourier coefficient is safe in this preset over here, this automaton preset. So this is kind of close to the actual automaphone. Now, so that's about the playing sounds. So now that we managed to get the notes from numbers, maybe we want to analyze the numbers from notes, right? So just now in the example, when I was playing the video, you saw that there was the waves. So that's as simple as just connecting the analyzer. Analyzer gives us a series of, gives us a array of numbers. You can choose your size to fast Fourier transform. So this is back to the same thing we're using Fourier transform. And then it gives you kind of like the peak of the sound. So you can use this to build up, when you have an equalizer with the sounds coming with the bars and all that. There is another function. Let's see, in this analyzer, analyzer, there is another, let me see, analyzer. Yeah, so this one, I'm getting the byte frequency data. There's a get byte time frequency data, if I'm not wrong. That one allows you to build the sound waves that you can see different kinds of visualizations, right? Yeah, so this is another thing that I built. Well, this was built using my code and some other code that I found online. So this initially started as a tuner and uses some mathematics to kind of identify. Let me mute that first. So this kind of identifies the note that you're playing by taking the raw audio input and then converting it into a wave to do some mathematics on it and it finds what's the notes that have been played. So this, when I was learning the guitar, I was practicing scales and I don't have a guitar on me now, but so I'll just show an example. And then let's save the C major scale. Scale. Okay. So that was a bit too, I played the D note a bit too fast, but basically when I will note that you're playing, it turns green just by detecting which note was being played. So, and then the last thing that I found was this code that actually detects chords, which is very, very interesting. So it is another very interesting thing about this library that I was using is that it is in C++ and it's actually using the fancy-smancy web assembly to expose its API to JS. So I think it's, if you want to find it, it's just as simple as just Googling a call or detect a JS. Yeah. Let's say I Googled it before and it's this particular one. So it's just JavaScript bindings for code detection. This builds a chroma gram, a chroma gram which is a representation of each note. And then it gives it a certain value. So you can start. I don't think this, yeah, okay. So this one doesn't, another thing that I did was I added a web speech API so you can see that my speech is being transcripted, although not very correctly. And then you can detect the chords. This is supposed to be a F major. It doesn't work, of course it doesn't work when I'm giving an example. Okay, let's try a C major. Of course it doesn't work now. Okay, never mind then. So I guess I can try to sing. A long, long time ago, there was a volcano all alone in the middle of the sea. But yeah, so basically, you know, you can play around with that just based on the code, the notes as being detected and then of course with that speech API, you can do transcription. This doesn't work as well as I hope because playing the song while singing, it's a bit, it will disrupt the algorithm a bit. So it doesn't really give you back the same chord even though my demonstration was bad. But we can do things like split up, can play the chord now and then say the lyrics, play the chord now, say the lyrics and you can create a tablature of music very easily. So that's my last example for today. And so now to plug my things, everything that I've spoken here, I've gone more in-depth in three blog posts over a period of time. So I started in last year, November, which is the synthesizer thing. And then the slides here are on my, everything you can just go to TZYNC. So that's my initials, TZYNC and then just INC. Yeah, so slides and examples are there. Follow my Twitter if you find this kind of things interesting because I think I'll be doing music and JS kind of things for a while. And that's all for my talk. Thank you. Thank you, TZYNC, very interesting. Does anybody have any questions? Yeah, I don't know a lot about music. So like, what is an oscillator? Oscillator is basically a thing that goes up and down, like oscillate, so you know, so it vibrates at a certain thing. So when you create oscillator, it's basically creating something that creates that wave thing. And then you pass the wave into the audio context and that's how you make the sound. So this is not really a music, I don't think it's a music term, I think it's just a mathematical term. I see, okay. I guess, no more questions. Thank you for sharing all the links as well. That gives us lots of reading and stuff we can play around with. Well, if you have any more questions, if you think of any questions later on, you can keep them for the end or even take them on to Twitter for the coming days. Okay, thanks very much, TZYNC. I think we will move on then. Murray is going to talk to us about, oh, hold on a sec. Ah, performance, achieving page speed with a data heavy data visualization. Okay, Murray, are you ready to go? Yes, I'm ready to go. Okay, over to you. Can you hear me okay? Can hear you fine, yes or good? Okay, you should be able to see me. Yeah, we can see your slide. Okay, hi everybody. Thank you so much for the first two talks. I very much enjoyed both of them a lot. Okay, so what I'm going to talk about tonight is an experience I had and what I did to try and actually fix it. And it's all about page speed and about Tableau. So some background. I, Tableau Public actually sends out data visualizations every day and I look at most of them and I come across some really good ones but I don't dare share any of them because the output is really pretty awful. And so I'm going to demonstrate now what that actually is, what that actually looks like. Can everybody see me? I can see Joey on the video. Can everyone see me? Yes, I can see you in the corner of the screen and your slides are fitting the screen. So are you good? Oh good, just I don't want to look at you. See anything? I don't know why I can't see myself, never mind. I'm not saying anything about you Joey, I'm just, anyway. So okay, I'm going to give a commentary as this loads. So it's trying to load. We see a little bit of text, it disappears. It's still trying to load. We see a whiteout. I try and actually scroll a bit. I can't do any kind of input. Nothing is happening as I'm trying to scroll. Ah, finally I can scroll. So this is a Tableau public kind of output and it's got lots of problems. Apart from the fact that it took forever to load. I'll try and do this. I'll just click on a slide because I think something's going to happen and we get another whiteout and we get a spinner going and nothing seems to be happening and I give up and then I do a bit of mouse over and sometimes those pop-ups appear and oftentimes they do not. So now I can't send this to my friend who I know is going to be looking at it on their phone because it's just a disaster on a phone and a couple of other things that's actually going on. Clearly I'm not getting all of this particular country because there's some stuff missing out at the end and I'm missing stuff here. I don't know what's going on. So to explain, this part here is an iFrame. So we've got an iFrame which does not take up the entire screen and I can't see the whole thing. The only way I can scroll to the right is I have to go right down the bottom, find the scroll bar, scroll to the right, go all the way back up again so I can actually do something and see what's going on. So what you can do with this is you can click on any of these things and it will actually sort it by that particular fuel. And let's try that. So let's do coal. Once again, it takes forever, spinners appear. We get a white out on the screen. I can't scroll, I can't do anything. After a long, long time, finally, we get some action. Now I forget what these country names are over here so I've got to go right down the bottom again and I have got to scroll left using the horizontal scroll thing. By the way, this is the text that we saw at the beginning which jumped down and then we couldn't see where it actually went and then here are the countries and showing whatever I sorted on coal. So it's a bit of a disaster. So let's go back and see why. It's slow, it's bloated, it's clunky as you saw. It uses an iFrame and my question is why? I mean, there's only a very few applications that should use iFrames, I think. And this is not one of them. So I don't know why they're using iFrame. It uses one huge background image and the whole thing is 1500 pixels wide which is not mobile friendly and as you saw, it's not even desktop friendly. It's just pretty awful. So now if you haven't heard of Tableau before, just very quickly, it's a very popular data visualization tool. It's very versatile. There's many different chart types like pyramids and scatter plots and maps and whole pile of different things. So I understand why it's popular. You can do a lot with it. It allows filtering, it allows sliders and all sorts of things and it does handle huge data sets. But the output is just so awful. Why is such a popular tool got such awful output? So I ran it through Google Page Speed to see what it actually said. Its score was a measly 11. If any of your sites are getting 11 on Google Page Speed, please throw the whole lot out and start again because Google's gonna reject it very much. Even on a desktop, it gets a score of 43. So it's actually quite slow. It's bloated. The bandwidth is actually more than that. It's actually 7.7 something. I'll explain why I've got 5.6 in a minute. There's at least a megabyte of unused JavaScript that comes down the pipe, which is part of the time that it needs to load. It's clunky as we saw. It has whiteouts like I showed you. It ignores user interaction. So sometimes you're trying to do something and you click or do something and it just, it doesn't seem to do anything. So pretty awful. I did an analysis in a web page test which I think is this one. Just open it again. Okay. So, ugly. These are actually surprisingly not too bad, but this is starting to show something pretty serious. It's 21 seconds to fully loaded, 15 seconds to document complete, 108 requests to that point, 116 requests to this point. And the waterfall, my God, the waterfall. So it loads, it loads a whole bunch of JavaScript. It loads a bunch of fonts. Then it loads a whole bunch more JavaScript and some SVGs and then a bunch more JavaScript and a bunch more JavaScript than a bunch more JavaScript. By the way, what you're looking at is the analysis of the iframe parent. That is the outer border. We haven't even got to the actual visualization yet. Something I don't know what takes seven seconds to actually come in, whole lot more stuff. Finally, at this point, this is where the images start coming in for the actual visualization. So this is the 22 second, 15 second in this case, but I've seen it out at 22, 24 seconds to actually come to here. So all of this stuff was all of when I was talking and pointing out whiteouts and spinners and all sorts of things. So all these images come in and then guess what? A bunch more fonts and a bit more JavaScript and some more JavaScript. So after 116 calls to the server, finally the whole thing's actually in. There are actually 36 different domains that are actually called during the load of that page. So no wonder it is slow, no wonder it is clunky and no wonder from a user point of view, it's pretty awful. So I just said all that stuff, 116 requests, 36 different domains, and I just showed you those. Okay, so I couldn't stand it and I thought, well, I better go build my own and see if I can do something a little faster. Excuse me. So what you're about to see is the same data, the same amount of data. I just got, I used the same data source as that one did. We used similar outputs, not exactly the same thing, so I didn't want to do actually the same thing, but it's fairly similar as you'll see. So I will not have time to actually give a commentary while it loads because it's loaded. So 22 seconds down to less than one seconds, what you just saw. This is all the same kind of information, but as I said, I didn't want to load it the same way. And when I mouse over, I've got the data that's coming up, which is typical of these sorts of visualizations. So if I scroll down a bit quicker, you'll see what I'm actually up to here. I'm lazy loading all of these. And so the only thing that actually loads at the beginning is about up to that much, and then all of the rest of it loads later. Now, similar to the Tableau one that you saw, you can sort by various things. You can sort by oil, and it shows up an interesting thing. America uses tons of oil, as you'd expect. China is the second most highest oil consumer, but it's using way more coal. Just the interesting thing is, China is still building coal-fired power plants and has been at least one a year for the last 10 years or so, but as you see, it's actually not using them. So they're like bridges to nowhere. They're building all these power plants, but nothing's happening. Unlike India, which is building power plants and using them and choking all the people of Delhi who can't even see the next block. I know I've been there in the middle of it. And I'm going to... OK, so all of these, we sort and it comes in super quick, we sort and it comes in super quick, and so on. OK, so I'll go to the other one, which I find more interesting. These are total energy consumption. By the way, I just loaded it in less than a second. And these are now totals. And I'll show an interesting one. Well, I think it's interesting. For countries that use a large percentage of their consumption being oil, these ones, Cyprus is the top, 95%. Good old Singapore is 86%. Luxembourg, 77% and so on. What's interesting is that these are all small countries. Cyprus, Singapore, Luxembourg, Hong Kong, Sri Lanka are all small. Iraq, of course, produces tons of it, so of course they're going to use tons of it. Now, some interesting things here. Did you realise that Singapore is actually uses coal? 0.74% of its energy consumption is coal. They actually built that coal-fired power plant in 2013. So the world is moving away from coal and Singapore decides to start building one at that time. You probably didn't know that Singapore actually has geothermal power. I live in Semboang and the Semboang hot spring is just down the road, and yeah, there's heaps of power coming up, heaps of energy coming up from that. Anyway, this is not a talk about energy, but I found this really interesting to do. There's lots of really interesting things to see. I'll just do one or two others. Hydro is really interesting. Norway is great. Huge amount of hydro that they actually do. Iceland's also good. 24% geo, 54% hydro, and only tiny bits of coal and oil. Okay, so I think anything like this should be quick. I should be able to just click and it should be there. I shouldn't have to wait 22 seconds for the whole thing to load and to come in. Okay, so I showed you both of those. So I'm using SVG for the charts, and what I do is I create those on the server and I cache them so that they can come in really quickly. I load just a certain number on page load and the rest are retrieved via Ajax on-scroll. Now, a key thing about quick page loading is to only load what you really need for the user to see at the top of the page. Any stuff underneath the first screen pool is not worth loading. If you can load it later, load it later. I also do the same thing with what I call data blobs. To do those mouseovers and to get the data coming in for individual years, I need to actually import the data for each one. So I create those blobs on the server using PHP and then on page load I bring in five and then the rest are retrieved via Ajax. So each one of those is taking about one second or so as I scroll down the page. So the data blobs are just things like this with a country array for each country that's going to appear and some board properties because things like the Y-max and Y-min are different for each one because they're using different amounts of each fuel for each one. And basically that's that. I'm using Cloudflare CDN, the free version, and I cache everything. So everything is super quick because it's cached, of course, in Singapore and so it comes in really quickly. The only country where Cloudflare is not so successful is actually Australia. For reasons known only to them, they have some sort of dispute with Cloudflare. So if you're in Australia, you actually get the downloads actually come from the Singapore server most of the time. I'm only actually using one domain, which I'll show you in a minute, yet I'm using Google Analytics on the page and I'm using SVG, an SVG library, but it's a PHP library so I don't have to do anything with JavaScript in that case. So let's look at the speed of the improved version. Google page speed tells me 99, it's not perfect but it's close, and for desktop 100. On the web page test, well, there's not much to show but I'll just go to it. All As, which is what I was looking for, the whole thing complete, document complete in one second, fully loaded 1.69, that's after my first few things come in. The waterfall, your waterfall should be really, really not high. If you've got a whole lot of things in your waterfall, then if you want a fast page, you've got to do something about it. So all I'm doing is I'm pulling in my page where all of the JavaScript I need is actually embedded in the page. Every time you do a call to some other domain for the various libraries and things that you need, each one of those takes up time. And so if everything that you need is actually embedded in the page, it's super quick. I have one font that I use. I have that font on my own server. I don't call it from Google or anywhere. Then this is actually the pulling in the first bunch of charts that I do on an initial page load, and then here's Google Analytics firing to follow what everybody's doing on the page. So the connection view is just two domains only. Excuse me. Okay, so I showed you all that. So the bandwidth, the initial page load is only 100 kilobytes, not whatever I said before. It's about 7.9 megabytes, the Tableau version that I showed you before on an initial page load. Way too much. No phone user ever wants to sit around waiting for that much to actually come in. 3.1 megabyte in total. That's once you get to the bottom of the page. That's all of the bits and pieces that have actually come in for the whole page. I'm using minimal.js library, and anything that I am using is inside the page. So my summary, for fast pages, keep it simple, keep it lean, avoid unnecessary JavaScript bloat, and there's way too much of that on the web these days, reduced domain calls. And caching everything makes a huge difference. Yeah. So achieving speed with a data heavy page can be done. I'm done. Thank you. Okay, thank you, Murray. Does anybody have any questions for Murray? Or any of your own stories with optimizing webpages? While you were talking, I looked up the 7-second download from CrazyEgg, and apparently CrazyEgg is an optimization tool, believe it or not. Website optimization, heat maps and A-B testing. Yes, it is. And that's a good example of something that does not need to be there on every page. You actually put up something like that when you first publish the page so that you can see where people are getting stuck with the UI or whatever is actually happening. And then you take it off. I bet there is nobody in the whole Tableau public hierarchy that ever looks at that. It's just a slow loading piece of JavaScript that they could really do with that. Mm-hmm. Or something like that you could just load for one in 20 users, so it doesn't affect everybody, but you're still getting some data. Right. Yep. Here's an interesting thought for you. When Gmail changed about five or six years ago, probably more, I can't remember, but it used to be Gmail used to load like that. I mean, it's only just a bunch of text. It should load like that. But next time you open Gmail, have a look how long it actually takes to load. It's often 10 to 15 seconds to actually load just a little bit of text. It drives me nuts. Yeah, that bothers me too. I think it might have got a little bit faster recently, when their logo changed, it seems to load a bit faster as well. I'm not seeing the loading bar anymore. Yeah. But it's not plain HTML. It is still loading a, I guess we call it a single-page app, a JavaScript-driven app. I did use to use the plain HTML version because of, like you're saying, the main app is quite slow. I've been known to use that as well on occasion. It's just crazy. So what I expected people to say at this point is, yes, but my boss says I've got to have this and I've got to track that and I've got to have this and whatever, so I cannot do. One of the things, what's actually really interesting for me now is that I sold my website about six months ago. And with my own website, I had lots of analytics going on. I had lots of all sorts of things actually happening and it's actually really liberating to build websites from scratch and say, well, I don't actually need that. That's not really necessary. I don't need all that rubbish and just have the bare minimum and it's actually really quite nice. It's nice to go back to basics. Yeah. Okay, I'm done. Thank you. Okay, thank you. I guess one thing I'd say is there is a movement within the JavaScript community of what they call it, statically generated websites, which is, and also the server rendering, which is trying to, but the statically generated is you might use React to create how everything looks, but actually you'll render it ahead of time into static files on the web server and when people load your page it's just loading up those static files. Yeah. Yeah. As long as that's actually what's happening, I have played a bit with that myself, but actually a whole pile of Java, the ones I've tried out, a whole pile of JavaScript loads first and then you get your pages which are downloading from the server and I kind of think, no, I don't want to start from the server directly. But yeah, I know what you're talking about and I think that sounds good. Okay, well, thanks very much, Murray. If anybody has any questions in future, where can they find you? On Twitter? Yeah, I had my Twitter handle in the last thing. I shall put it in the chat. Great. So thanks to all the speakers and now we sort of have an open mic time and you can talk about whatever you like. If you have an announcement, if you're looking to hire someone, if you want to be hired, if you found something cool you want to share, if you have some problem with your work that you want to maybe get some input on. Yeah, so it's just a free chat now. So everybody go ahead. After that audio talk, I'm going to share something a little bit fun which is Plink.in which you may have seen before because it's not so new. Yeah, I've put it in the chat. So it's a music-making thing. Yeah. You should have started with this, Plink. Okay, but then we would have missed out on Tensi's musical. Yeah, just before his Eucalyptus was ready. Oh, I'm sorry. There seems to be a problem with their servers so there is no Plink in at the moment. Well, there's the intro. My name is Dan Ferret, if anyone is here. Oh, you got in? Yeah, I got in, it's all. With Shadow Bear. Oh, Shadow Bear is there, I guess. New person now. Oh, I got kicked out. You got kicked out? Okay, okay. Maybe we shouldn't be distracted by Plink. Oh, Mari has posted some links about music and transformation geometry. If you guys want to do open mic, you can just unmute this stuff. But I guess there probably isn't much announcement for today then. Do you want to ask the questions, Joey? What questions? You mean with our GitHub? Oh, yeah. Yeah, I know what you mean now. Yeah, okay. Yeah, so we have a couple of questions for our attendees, which is do you prefer we have two talks in a session or do you prefer we have three talks in a session? No answer. You can unmute your mics, because all your mics are muted. Mari likes three short ones. But we'll ask why you prefer that. Some people can be a little long-winded and people are usually too polite to say your time's up. So usually if you're trying to squash three, the problem with that is that, yeah, I mean, it can end up going quite late if everybody still wants to present everything. I actually think it's fine. Somebody might come along and say, look, I really need half an hour to do this properly. Well, you know, occasionally fine. It means you don't have to find as many speakers if you've only got two, that's for sure. Or maybe it should depend on what the speaker thinks they need and that can influence our decision. I think I gave a talk a few months back and I think I overran and I failed to interrupt myself and tell myself to stop. There's no time left running out. Today's timing was really good. Today's format? Yeah, today's timing was good. I mean, the length, the durations of the talks, right? Yeah. Yeah, I think... Sorry, go ahead. No, no, I was just thinking of the closing of the year for today and for next year, what are we expecting? Is top formats still working for you guys on a virtual manner? Is there anything that's missing that you're missing from real-life interactions or things like this? Feel free to rent or anything as well. We just want to know if the virtual formats are working because quite a lot of meetups have actually stopped. Is it still nice that there's meetups available virtually? I think it's better than none, but it's just, I don't know, I just feel awkward speaking in a big group and it's like virtual. I don't know, it's just something not natural about it, I suppose. Because it's too much good to me? No, not that, but... I don't know, I imagine it would be quite nice if we can have some form of off-site, like five people kind of virtual... Then we can be in small groups but somehow still connected via virtual and you can get to know... Yeah, I guess live interactions always trumps this kind of virtual stuff. But I think the format is great though. I still enjoy it a lot and listening to the different things that the speakers shared today. That was great, yeah. Cool. Yeah, actually that would be pretty nice if there's a big space and we can stay in the tables of five. Yeah, anybody wants to volunteer, you say? I think you're not allowed to go to the living room. Now I'm thinking of the tutorial room. They have a table of things. Yeah. And it's perfectly in space. Yeah, exactly. If let's say groups are, it can also be like really distributed. It's not necessary that everyone have to be in the same venue then can use a similar like this zoom format then like to link out all the groups together. So like a few different groups watching all the same zoom meeting. Like virtual breakout rooms? It's not really said breakout rooms but I'd rather say that the groups can be in one venue then another group in another venue then everyone like join in the same zoom all the groups join together in the same zoom. I get it, it's like a watch party. Yeah, it's a huge. It's kind of cute. Everybody's a turner. You wouldn't have to travel so far. You could go to your local watch party. Oh wow, that would be pretty sweet. That might be possible in phase three because there's eight people per group, right? Yeah, there's been two right? Yeah, two or three. I thought not necessary two or three group survivors but somehow it can scare it upwards. Instead of doing your breakout sessions it's definitely like you don't need a zoom then when you come together then you'll use the zoom. Okay, I have nothing to say or anything besides have a good end to the 2020. Anybody else? I guess since it's the last one in training for like already so on and having me in the organizing team as well and I just want to say thanks to engineers.ag for helping us throughout the year and on the attendees it's quite tough for the attendees to even just show up because it's so easy to to just build on us, right? And you guys are still short, so that's great. We really appreciate it. But if you have any feedback on the format just feel free to pop onto the telegram group and then post your comments. I think you prefer or if you saw some formats of other meetups maybe in other countries or whatever since they're all virtual now then feel free to just like suggest kind of things totally cool. And also if you want to help out or do stuff please also ping us on the telegram group. It's not like a really it's not a group for chatting like DevSG it's just more for like getting in touch with people so if you have any suggestions or whatever please don't feel shy, it's a very small group you just pop on there and just suggest like any format changes suggestions things like that. Yep, don't have my video? Cool, so we have a yes or no one? Summer Nick? Yeah. I'm going to say thanks to Michael Joker who is hosting us today I think for the first time so thanks for your help. And also to Eric who's been organizing a lot of the doing a lot of behind the scenes organizing. So yeah, getting the the talks together and of course thanks to our speakers as well because we could do it without you. So you think I should wrap up, Min? Let me wrap up, oh well thanks for the honour. So I wish all of you a very good end of 2020 I hope 2021 it might be slightly better in terms of everything it's been a very interesting year and I'm glad that everything is still going so we'll see you guys next year probably Jen or Sam if you have anything that you work over the holidays and it seems like most of us are not going anywhere can't be, yeah exactly 2021 can't be worse but let's not jinx it I guess everyone might be working on Pat projects or doing anything please feel free to just suggest the talks again we are a community driven thing going on for many years all because of speakers who are interested in what they're doing So yeah exactly, I agree we're very lucky to be in Singapore so we hope like maybe physical meetups might be possible next year that would be really, really nice to see everyone again and to get back to like chatting and suppers and just a bit of face to face cheat chatting since we're on the computer all the time now anyways So yeah again if you want to help out or if you have any suggestions or anything please feel free to just pop into our Charlie Graham group on GrigGenie.org and that's it that's it for this year's So, thanks everyone thanks everyone, bye thanks to today's speakers yeah thanks a lot Happy Christmas and Happy Holidays Happy Holidays I'm glad to meet you, I'm planning. Happy New Year, when it comes. There's like Christmas, there's New Year's, there's Chinese New Year's. Okay, I'm gonna head out. Bye.