 which I relied on to get here and know which exit to take. That's Rauta, thanks for your answer. Rauta, I can't remember the name, I thought this would go with the thing. This project is, when Pokemon Go launched around that time, she started looking into all the different Pokemon themed repositories on GitHub and made something to show it off, which is really awesome. So he's basically going to tell us how he did it, what he did. Like, certainly. We could be a leader. So, can anyone hear? Testing, testing. There's no mic, right? There's the mic. That's okay for recording, it's not for anything else. So, yeah, you introduced me anyway. Yeah, so I'm Chee-Yan, I do fire stuff, everything Chris said just now, I do a lot of stuff. Yeah, so you might see me, like, before on TV. Yeah, very weird. So you might have seen me having blonde hair before, back in 2009. So yeah, so it's kind of weird. So now I'm like, I still look the same, right? Some people say that, oh, I still look young. Some years ago. So anyway, I'm also speaking for JSConf this November. Anyone knows JSConf Asia? We don't care about JavaScript. We need to strain our soul, there's a bit better, I think. Yeah, it's kind of weird, like a coffee hacker that's like weird. Yeah, it's a long catcher. Okay. So anyway, let me just, okay. So, before this, let me show what's the ad. Got this. I'll just start here anyway. Yeah, so I built an app. Just like you say, it's just a list of GitHub repositories with Pokemon names. So it's kind of like, goes back some time ago. I was like, look at this project called, like, Jorg, you know? So anyone knows this project? Okay. Can you slow down? Okay, yeah. So this project is kind of like an inspiration for me. So I look at this, right? This is really nice. This thing, like, you know. Okay. So I was kind of inspired by this project. Jorg is the name of a Pokemon in which generation? I forgot. The first generation, yeah. So it's a project name. So it's like, GitHub repo project name. You've got a nice little Pokemon image there. Nice image that gives this guy a little bit. So I kind of like, you know, like, when you do projects, there's always this naming thing. Before you start a project, there's always, like, what should I name it? And then some people came up with creative names, like, who knows? Who knows? So do you know what it's called? Anyone knows? Heard about it. So it's actually the name of an anime character in Dragon Ball. Do you know what Dragon Ball is? It's a lady name. Yeah. So it's actually that name. This guy actually, this guy, yeah. So it's, like, JG2. So it's a really interesting naming structure. You might be wondering where does it come from? So a lot of, like, this, like, cache. Cache means cross-platform bash. Yeah. And then there's lathe. Lathe means eval in reverse. So just fit the name. So quite creative in some way. And then, and some projects, they might not have, like, cool names. But it has, like, cool images. Like, whoa, this is really cool, right? You want to use it right away, right now. So it's actually, like, a test-runner thing. And then there are some projects, like, not so cool names also, but it has, like, very cool graphics. Yeah. So you'd be wondering who'd draw all these things, right? Like, some developers out there, they can draw all these cool stuff. Yeah. And then this is one of the cool ones. Even have, like, animated use, like, like, serverless framework, like, paper execution, like, they even can make, like, animated use, like, even less cool ones. So it's kind of like inspiration, right? You know, like, you need cool names and cool graphics for a project, right? So... So I was looking at a list of, like, Pokemon names. So I thought, like, you know, if there's Jolteon, there's probably, like, Orbezor, like, someone else have, like, created a repository called Orbezor or something. So I realized that there's, like, 720 of them. Actually, more. Oh, a lot, okay. So, yeah, 721 plus a few more unknowns. Yeah. So you can get, kind of, like, you can get all the games here, you know, like, if you're, like, not so creative. So... What I did is, like, I go to this website and I realized that I can kind of, like, track the images here, which is not supposed to be... Yeah, I'm not supposed to track the images. So... No one here works for Nintendo or anything like that. Please leave. That's him leaving the room now. So here's the thing, right? Should not publish the... So it turns out there are less... Sort of copyright. Yeah. You cannot say that this page is from my... So I was looking at this page, and I was looking at this AJAX call. So they actually have an AJAX call that has all the Pokemons. So it's, like, Pokemons, like, that has colors. Yeah. So they have everything here. So I'm like, look at this. The world is really cool. So I just, like, script the JSON. Yes. So I use the githubsearch.ai and if you use it before, it's kind of like... You have a rate limit of, like, 30 requests per minute and a 10 requests per minute if you are not authenticated. So what I do is I write a script to, like, like, search for the repository name. So it's kind of, like, just search and then... So I search, like, 720 calls of them. So it's kind of crazy, right? And since I'm, like, doing it and 30 requests per minute, so it takes about around, like, two minutes, two, three minutes, for what? Like, five minutes. So this is the repo. And this is how it looks like. Yeah. Yeah. So there's a power song. Like... Yeah. Like, even this are the stars, like, zero stars. Like Charmander, like, 46 stars. Yeah. So you can see the description of the repository. You don't really know what it does, but yeah, it's just a theme of a repository. You can see it links to, to the heat up repo, like, if it just... It's a gift, and then it just goes to the... the repository. And then you can find out that, oh, it's called Charmander. Yeah. Which is quite nice. So it turns out that there's quite a lot of them. A lot. Like, yeah. And then it goes through, like, first generation, second generation gets, like, less and less and more, right? Until the very last generation, usually the cool ones, like, are taken. The not-so-cool ones are not taken. Well, some are quite cool, but not taken as well. So it gets less and less, until, like, the very last... Oh, this is quite cool, actually. Yeah, it's quite funny, when you get this, yeah. So, uh, this... Some of them, I mean, you know, like, Gold Lab. Yeah. Yeah. Some of them, like, Legendary Pokemon or something. Final buy. So, until the very last round, it was really, like, upa. Upa. So, this is, like, you know, like, kind of, like, very easy. And, uh... So, when I was, like, posting, when I was like, Chinese, right, I was super excited. And I was like, oh, this is so cool, right? And then I tried to post, like, sneak peeks about it. And it's like, oh, like, I can get all of them, like, Croister, Gasly, Honda, Enga. And all of them, actually, repository is with, like, at least one people's house. Zero's house. Anyway. So, it was, like, seriously, like, so many. And then, uh, a lot more, like, like, Fever, Shawarma, or the H&M. Yeah. So, it's like, oh, these guys, like, you know, and developers, they are actually using, uh, Pokemon games. Yeah. So, anyway, so, in the beginning, right, if you look at this page, you go back to this page again. So, I kind of, like, like, cheat a bit, like, so every single image goes to... Yeah, you can see here, right? It goes to Pokemon.com. So, there's 720 images, so all calls to the server. And it's really, actually, it's quite fast. Actually, yeah. Surprisingly, quite fast. Yeah, so I'm like, I don't care anyway, so I'm like, yeah. But somehow, it's still kind of slow, it takes up a lot of memory and a lot of, like, it blocks. So the browser kind of, like, requests, like, eight images at a time. But since the server is so fast, you probably don't notice it. You probably notice it on mobiles, mobile phones, and then you use up, like, 20 megabytes of your, of your bandwidth. So you probably pay, like, if you pay $1 per megabyte, it's like $20 gone. That's my whole new feature. So I'm like, it's not good, right? And I feel bad, like, thinking to their website, so it's like, yeah. But do you write the reference like the pictures come from? Oh, yeah. It's at the bottom of the page, which you can just scroll all the way down. No, it's not good. It goes, like, you don't write that if somebody else discovered it, they would kick you. Yeah. So, yeah, that's it. So I actually remember to write that from the very beginning. So I kind of, like, tried to solve this problem. Actually, on Firefox, again, it always have that missing images for some reason, and it's quite laggy actually, yeah. It's just not missing yet. Yeah, it's just lag. So when you scroll down, it's, like, very slow, like, I don't know why. Yeah, so I wanted to fix that somehow. So I kind of, like, my first solution, okay, is to speed up, like, well, the description is a bit weird. So what I did is a lot of weird stuff. Okay, so I create a sprite, an image of all the images. So I read, so I write a script to download all 730 images, and then create a sprite image out of it. And then the sprite is, like, super huge. Like, is it huge? What size is it? Like 5,000 pixels or something? Yeah. So, and then, after I generate the sprite, I have to generate the CSS. So the CSS is kind of like this, you know, like, background position all the way. All the way down, man. So much. So I don't even know if I'm saying badly. Did you type it out yourself? Or use a script? I'll use a script, obviously. So you can see my script over here. So I pause the JSON and then download every image you can see, this thing, yeah. And then I actually run through this thing, sprite.js or something. So, yeah, let me just, so it's kind of like, through a lot of calculations that like, generate the image, find out the coordinates. So much analytics there. And then I put the classes, .img, plus id, those things. So it's like, quite nice. I use something called sprite-smith. It's like an npm module thing. Yeah. So, language you're using. Language? Yes. Java script. Okay. Just an npm script kind of thing. Yeah. So it's like, sprite-smith is kind of cool, and then, what do you do? Oh, you just have visualization or whatever. Okay. Sprite-smith. Okay. This is, yeah. Pretty cool. They have quite some cool stuff. They can also generate, yeah. They have like some plug-ins that wrap over sprite-smith to generate CSS, but I kind of like don't like it, so I generate myself. Yeah. Because some of them they are like, generate really ugly CSS for some reason. Yeah. They are like, try to be nice. Okay. So I like, generate my own custom ones. I also like to say, recommend this website. So, I use a lot of, like this compression things, like a lot of like, whatever you know out there, there's a lot of them. Somehow this guy, this, this panda, is doing a pretty good job. So what I did is I create a png file, convert it to jpeg, and then compress it here. And that's it. And the compression is quite good, actually. Like, you go down to like, you know bytes only, like, so from 20 megabytes down to like, actually not too, too few bytes, just two megabytes. So it's like, 10x the savings. And bytes, engineering. Sorry? 10 times engineering. Oh, 10 times. 10 times engineering. Yeah. And somehow this guy can do it really well. So I try a lot of tools, try to try that, I find it and try this, and I'm like, oh, this is insane, like insane savings. I don't know how they do it, but it's just pretty cool. Anyway, but somehow there's a bug. So someone reported me a bug. It's like, someone doesn't work on like, Chrome, on Android, or the default browser in Android. Yeah. So it's like, shows this, but it works on every single other browser. But it works on Chrome desktop. It works on Safari, it works on everywhere, I've said, like any browsers on Android. So I'm like, this is like weird, right? So something's wrong with my calculations, probably, or like the Repina images, whatever, right? So, I'm kind of like, this is so weird. And then, and then I debug it for a while, I realize that it only happens for JPEG. If I switch it to my my PNG original file, it works. So I'm like, probably something weird there, right? So what I did is, like a super quick fix. So I'll write some, like paragraphs of text for myself to read. So I actually convert the image to WebP. Somehow it works, yeah. If I, so as long as it's not JPEG, it's fine. So I kind of like, make use of this bar to learn something new. So I learned how to like convert the JPEG into WebP for our image using like the command line tools and stuff like that. So you can actually like, research it yourself or like, convert to WebP, which is kind of nice. And then, it kind of like, fix it. I even do like, detection. So it supports WebP class, kind of like that. So detection is actually pretty easy. Kind of weird, but they are pretty easy. You can like, find this on like, Google this somewhere. So it can even like, detect like, or if the WebP you need like, alpha transparency or not, or if you need, like, useless compression or lucy compression. So it's like, it can detect any of it. So it's kind of cool. So this one only detects lucy compression. Yeah. And that's the only image to detect if it supports lucy compression WebP. Yeah. So I'm like, wow, this is really cool. So I learned something new from just using WebP. And then, but okay, before I go here, so it kind of like, solved the problem, my first solution, but it's still slow. So it turns out that the image was too large. So it's like, 5,000 pixels. So even though the file size is small, but once it's encoded by the browser, right, it takes up a lot of memory and then like, but it's scrolled down, it's still the browser do a lot of work, basically. So this is not really relevant to Firefox or anything. So I just read this, I'm like, oh, Safari iOS actually got some limitations. So they do something like, oh, the maximum size what they coded with GIF, PNG and GIF is like, three megapixels. So if it's larger than that, it will try to do some magic somehow. And then JPEG got some special special way of like, decoding, yeah. So it's at 32 megapixels. So I kind of like, this kind of makes sense. Probably it doesn't just apply to Safari. If I apply to all browsers, which you don't really know. So I kind of like, perhaps I should do something different. So what I did is, I make everything into smaller sprites. So from that huge 5,000 pixel sprites, I make it into smaller, smaller sprites. So to kind of like, be nice to the browser, so that probably the browser will be smarter in like, managing the memory and stuff. Like if you scroll and see this image, it will probably try to like, re-use it back somehow. And it's kind of like, cool. What do I do actually? What do I do? So a few changes. But since I make it into multiple sprites, it starts to become complicated to do the CSS. So here's the tricky part. So anyone understands what this do? So it's kind of like, selecting all classes with i0 in front or back, whatever that is. And then i100. So if I don't do this right, I'll have to do something like this. 001, 002, 003, you're all the way down. So I'm lazy, so I just select all of it. Select all of it. So there's the S3 step, which is like a magic thing. We would just find for the value of the attribute, if it has i0. The basic class contains that. So the class attribute contains i0. It's probably not that performant in some way, but... CSS performance is never a problem, really. It's a little bit dangerous when you're using the star selector like that, unless you have control over what you're doing. Because you might have i0 to 1 somewhere and i0 to 2. Something is breaks. So you might say if you start with a way it's with or something, if you can. Or is it? Yeah, it's the start. Yeah, it's the start. It's not the start selector. It's not the start selector. No, no, no. But it's... That's a particular thing, yeah. But you can still have string starts and string ends with it. Oh, yeah. Which is the... I tried the start thing. Somehow it doesn't work. I don't know why. I was like too late. Considering you're controlling the generation of the class until it's safe because it's all controlled otherwise you can be careful. Yeah, kind of like that. It's a super easy way. So since all of them share the same properties, so it's kind of... The only thing that you don't share is the background position. Just like, yeah. But some of it actually share. Kind of like, yeah. Some actually share and like I did a workaround for that. Do you know what they are doing? Sprite scene. Yeah, you can see how I chunk the sprites to like maximum 100 pokemons per sprite. So a lot of mathematics again on the half. So much mathematics. Yeah. So and then I generate one at a time somehow. Generate again. Yeah. Until like it's done. So like basically it's like this. I want to see how it works. So... Okay. Yeah. So that's it. So my second solution somehow worked well for now. It's smoother on most browsers now. So no longer lag on Firefox, on Chrome. And somehow even though I use JPEG the bug doesn't happen anymore. I don't know why. Yeah. So it's like probably the image is so large and then yeah. So large that Chrome on Android they freak out and then like start to do weird things. So when I have a smaller JPEG image it's like, oh I'm okay. Yeah. Yeah. So somehow that bugs anyway. So anyway I would like to what is this? So anyway it's one of those I wanted to highlight this like why side projects should be stupid? So this is kind of like like stupid side project that I do. I mean like who want to build this? So it's like stupid and then I would like to highlight this last quote. So it's like I didn't build it because it stopped being fun it stopped being stupid. So I actually learned a lot from this stupid side project. Yeah. And that's that's the fun part right? And that's that's it. Yeah. That's striking because writing is reasonably common these days but it's not very well understood. The basic concept is as you see where you have one image that contains many and you only show a small part on the screen and you can find that the renders is very different from that and that's why Chiara's seeing problems. When you show a sprite so say you've got four different parts of the one image shown in different locations the browser renders that entire image four times. So that means in memory that image is repeated four separate times. Then the effect is even though you get less of a download you get much higher memory you see you see the browser and that's why you get problems like you saw with the JPEG in in Android like browser and Android Chrome. So that's what's going on. The solution is pretty much what you did what you worked out by accident which is you reduce the size of the sprite images so you have fewer things than sprites. The reason sprites came around in the first place was back in the 1980s trying to do video games where there was a limited amount of storage that you could actually write any code or anything on to having everything you still want to image paint a whole lot more sense and then you could just render that one thing on screen and once it still bumped up the memory like that but at least it was you basically grew sprites into a certain animation or something so if you've got an animation of Mario running along you'd have every lead movement in the same sprite so you'll have a Mario sprite you wouldn't have a Mario and Luigi on each you just have Mario that way you can contain your memory you should not go crazy that way so you've got there in the end but that's why that happens if you do the maths you can work it out so you do width by height by good depth so the color depth which is usually 24 or 32 bit multiplied by but you can basically work out how much memory is taken out so even though it's still going to take up a ton of memory these days because spritings reasonably common that browsers are semi aware of it but when you're in a constrained environment like Android it's going to be a problem you may not even notice that on your page maybe the render's okay but you're probably bumping the person's history out of memory at the same time so it may look alright when you're testing it but you build you're really careful with sprites that's when you get that stuff questions between you and I? you can consider archiving and so your immediate archiving or archiving is it the or why or is it one of the high-end operations it doesn't work when you've got an image of any description because compression already applies some of the sprites may turn out high-end or some things before compression again with an image of any compression before that of a tone if you zip a JDP you'll probably increase the size of it because it's already optimized same thing with a pink it's already compressed as much as it possibly can if you've got a bitmap which is un-compressed you'll see a change but otherwise you won't see a thing so the difference between audio and an MP3 or something when you're in MP3 you reduce I mean it's lossy you're reducing the file size significantly because you're applying compression if you're in MP3 you shouldn't do anything you can't compress so you won't improve the graphics performance by zipping it if your service config correctly you don't jizz images because it's just unnecessary it's already compressed on a JPEG you don't have to really compress the compressed image anymore you have a lot of images you compress it you can there are a lot of that kind of yeah but that's like JPEG works exactly by doing that it basically brings all those similar pixels in together and reduces it that way PMUs is a very similar compression I think both of these same say but they basically do some sort of compression thing on it so if you can use Zip on a Zip it's much better do anything same thing Zip on any other compressing that's already done you can optimize images if you export something from Photoshop there are like that tiny JPEG there are tons of MPM tools and things to reduce the size of images what they do is they get rid of all the metadata so you have a JPEG it has also it has programming created it has the face of the moon and then the general vibe programmer was in when they were doing something so that should be done anyway but you still got the actual image itself which is impressive so the most you'll say that's whatever the tiny magic art you might have to let you see that but then the overhead actually Zip in the first place is going to counter it then you have to see can you speed and this is not worth it how about the images that are off the screen if you put them I was thinking visibility display none display none which acts as a space so you should be able to see people I think what if that might bring out memory and be combined into this display none would get them out of memory but then you're in kind of screen visibility get it to keep in memory just want to show you see that with so well okay so you could do display none and make the container the same size of the image but it would repaint what? what people who have done image galleries and things like that the massive ones have worked out is you paint or you basically render what's on the screen plus the next reasonable amount of scroll minus the last reasonable amount of scroll and what usually happens is they'll use so you'll see what's on your screen and they'll render maybe the next half so when you're going through normal speed you can see the scroll will basically get rid of the ones on the top and the ones down the bottom so you need to tunnel and dust that for their infinite scroll although they retain the memory on the top which is not very efficient other ones get rid of that so they go because you keep jacking up the memory usage which will crush the browser pretty quickly he managed the non-crushed browser which is a miracle but close yeah that's basically how you get around that you just hold the door and really up the other thing I was going to mention on that is the way because you're only rendering a bit off the screen if you scroll quickly then your skeleton screen sort of shows to the square or something like that to show where any of you just go to load so show you something over the white screen so you know to get something back to notice what's going on anything yeah so and quite a bit last time I did a mobile game and you mentioned about the G&G conference that's what I did so what I did was you joined the G&G the first G&G the band the G&G and so on and so that it's very profound that you just from zero bytes to you know how many bytes in this file so you split up the file in one course then I did mobile game so you append the first 0.01 append 0.02 behind the first file and so on and you get a very big file do you want a big image? a big file not an image it's a file it's kind of like a split so it's a five-byte ring file so you're going to create a very big file what do you do what does that do with something? so you get to pass that you get to join up for the files you just mention all that then you can straighten the files very quickly and you get to like a sprite you get to render it very fast so everyone when you want to get an image out put it on put it into the dome then you turn it into a data stream you have to process you have to have a table what must file size to find out you guys have to use the exact table how do you get that same file size from the big very big file and how big you can grab it and grab it by the big file and then get it and you get to that's not something you can do on a web browser it's clickable for native mobile gaming or something like that it's a way of handling assets on any native environment so very often it's going to have on a web browser it's a really common technique with most native applications and then I would try this with my 1000k or something like that you join them up in memory leave it in some description pull out the assets you need and you're alright but that's that's file management and a little bit of management but the browser does all that stuff for you try to implement that and the browser would be correct with 2070 try it once try it any more more questions what level are you on to at the moment, yeah not very 18 18 I should have checked that before then should have checked what level you were on before before you could come up with a lot I've got a great browser here some of the some of them some of them have their bright pink it's a brief brief browser what's the engine on that is that running I mean is that working yes yes it's a great common browser it's a it's a it's created by the browser created by the idea it's not a dream it's definitely a yeah it's a very interesting way to use brief it's a yeah it's a it's a it's a it's a it's a it's a it's a it's a a it's a you and you and you and you and and it's it's It's still, probably when you get a scratch, you know, you run along and you basically need to reduce your stress on my sprays. Yeah. Alright. Okay. Thank you, Chiang. Thank you.