PWA advice needed regarding large number of static assets - reactjs

I am a building a educational app that has around 1100 SVGs. They very small per svg like 800bytes. I am quite new to reactjs.
For each SVG I have an audio.
Therefore
1100 svgs
1100 audio clips
I am using create-react-app.
Intend using howlerJS to ensure audio files are cached.
Also lazy load the svgs.
Does create-react-app cache the svgs?
Should I change my approach? Maybe merge svgs into a sprite..
Should I merge mp3s and play parts of the audio as needed..
My main thing is that audio and svgs get installed when user installs PWA.
Any feedback will be appreciated

There is no magic bullet to your problem, but here are some key points to consider:
It won't take long for you to make a request and get a response for each and every pair of svg/audio that user selects (on demand, not 1100 altogether).
Not knowing your app's logic and UX, I can extrapolate that loading 3MB of SVG and 10MB of audio will be more noticeable, than waiting for on-demand request/response of 11KB.
As a background job, try to load as many files to upfront as you can, while there are no running requests from user.
Cache everything that was already loaded to avoid repeated requests
Try to optimize your sources in the first place, since minimal changes to an individual file will lead to a major impact on scale of x1000. A good place to start is checking your floating point in SVG: try to avoid something like <path d="M33.6286316,13.9605932... and keep it as simple as your precision allows you to. In most cases <path d="M33.62,13.96... will do the job.

Related

How to make images resize as per client device size

I have a react app that has many image references ( tags <img src=... /> and css background:url(...)) type.
These images are hosted on Azure Storage.
To speed up my App loading time on various devices (desktops and mobile), I need to resize these images before they hit the client, ie, on the server somewhere.
So far, I can think of the following options:
Pick each image, and produce multiple versions of them for various standard device sizes. Then, pick up each <img src=... /> tag, and, using JS alter the image name, such that the right size of image gets served. This will not work with css.
Use Azure CDN to automatically resize images. I was hoping that resizing would happen automatically, as the CDN portal retrieves the user-agent from the device. Does anyone know if this is true?
Serve images through an Azure function, resizing them on the fly (as suggested here)
Can someone suggest other options they can think of, or a pros / con of the above.
Since you're using javascript, use the window tag. For browsers, the window tab measures the resolution of the browser and you can set the height and width of your image to window.innerHeight and window.innerWidth. There are multiple other ways to do this but this is the easiest and most optimised if your coding project needs to be efficient with the least lines of code necessary.
More info about the window object here : https://www.w3schools.com/js/js_window.asp
P.S. this is only a solution for desktop, for mobile you can use screen.width, screen.height. This might not work on desktop but on a macOS Big Sur device it works, I tried it (This might be because macOS Big Sur is like a mobile optimised interface given that you can even run iOS apps on it but we don't know unless we try). That might be a better option as it is most likely common across all your devices.
More info about the screen object here : https://www.tutorialrepublic.com/faq/how-to-detect-screen-resolution-with-javascript.php
On the off-chance that none of them are common across all of your target devices, try making a detector program with which you can detect the device type and store that in a variable. Then create 2 if statements saying
if(deviceType = iOS){
<img src=..., screen.width, screen.height/>
}else if(deviceType = Windows){
<img src=..., window.innerWidth, window.innerHeight/>
}
Obviously this code won't work but it's just there to show you the flow where you can sort of understand what I meant. You need to integrate it your own way but this was just a way to make it easier as many times people mention that my answers are not easy to understand, just as a safety measure.
The best part of these options is that instead of remade copies of the image itself, this will resize the one, which saves storage space and eliminates the chance of the user using an unexpected display output like a 49" Samsung Odyssey G9 monitor where the resolution is extremely far from what you might have expected and resized. This also means you don't have to create a separate file just to make image resizing code, just the one to detect the OS (not necessary if the screen object works) which would've already been done since this is Azure we're talking about and they always detect their user base.
If you have any queries, please reply back.
Good luck!

What causes this warning on Safari? "This webpage is using significant energy. Closing it may improve the responsiveness of your Mac"

We have a React website running with lots of high-quality images that has been experiencing this warning. How do you begin debugging this warning message on Safari? Is there specific things that cause this?
This message is caused by Safari watchdog process that monitors the Javascript scripts running on a page. It is there to notify the user when a script is utilizing too many resources. Your page when loaded on my computer raises the CPU utilization to 68 percent. Be weary of loops and custom render code.
Notes for improvement:
Make the rendering code as efficient as possible.
Combine the your internal Javascript files into a single file, instead of 7 files. Major improvement.
When possible(due to licensing and update considerations) include the 9 external scripts into the single file stated above. Minor improvement.
Split the main page into different sections either as separate pages or dynamically loaded using AJAX. Major improvement.
Avoid svg files. SVG files require a lot of computing power to rasterize and display. This is the main cause of the 7 second load times. Convert the files to png at the largest expected display resolution and offer an expanded SVG file if more detail is wanted(by click or delayed mouse over). Major improvement.
The number of images is not the issue. It is the number of SVG images(on load) and the scripts causing the issue.
Open the page in Chrome, open the Developer Tools and then switch over to the "Performance tab".
Then use the 2nd icon from the left - the one that looks like a "reload" button. Which says "Start profiling and reload page".
You will have a full rundown on what is taking how much. You can see in the top what is eating up FPS and CPU, and then you can select the timeframes that had especially high load.
In the bottom part then select the "Call Tree" or "Bottom-Up" tabs, to get a rundown of which scripts and function calls cause performance issues.
Usually "normal" websites ( e.g. not games ) would not have a lot of frame redraws. You can then spot for example if loading spinners are animated with javascript, instead of transforms and transitions; and sometimes they're still re-rendering although they are out of reach.
On a React specific note : It might also make sense to inspect it additionally with the React Developer Tools. E.g. you might be able to spot if sub-frames are re-rendering constantly for no reason.

Ionic: fast loading images

I am building a small app with Ionic 3 and angular 2/4
I have a problem to load a list of images from an URL (5MB per image)
It takes a lot of time to display my images.
How can I load images faster ?
There is any way to display images in low quality first ? (like Facebook and Whatsapp)
Any link, any tutorial, any blog ...
//js
private photo = "http://my-url.com";
private photo2 = "http://my-url-2.com";
//html
<div> <img [src]="photo"> </div>
<div> <img [src]="photo2"> </div>
Thank you !
The most convenient ways imho are:
compression - the first thing you need to ask yourself: Do I really need a 5mb image? Is it too big? Can it be compressed (e.g. jpeg/png)?
thumbnails - 1 (or more) version of the original image which are a lot smaller and therefore a lot faster to load. In many cases (e.g. list, overview) you don't even need the original image because the size of your img container is way smaller. So one way is to only load + display the size you need for that specific usecase. When you really need the 5mb version you could start with the thumbnail and replace it when the fullsize one is finished loading. This doesn't reduce the loading time, but feels way smoother.
preloading - you could preload the images (e.g. when you know they will be shown soon) to remove the slow loading part when your image is actually displayed.
caching - when your images don't change that much you might consider caching the images on your device. That way whenever you need to load a 5mb image for the second time (even after app restart) it takes the local copy instead of the remote one and can be shown almost instantly.
Ideally (and depending on your usecase) you combine all four things: Compressed images, different sized versions of your images, preloading when necessary and caching to make sure an image is only loaded once.
In my apps I'm using the simple but great plugin ionic-image-loader which I can highly recommend. It's easy to implement and covers 3. and 4. with almost no effort.
I hope I could help!

Best strategy for a magazine app

I'm developing a Magazine app and trying to find the best strategy to optimize performance and stability. The app should be able to handle +100 pages and expect users to swipe between them fast and smoothly.
With all this in mind, this is what I've tried so far.
The basic structure would be using tabs, with tabs bar hidden, to allow user swipe. Since loading + 100 tabs with huge images would be a mistake, I always mantain three tabs: the current page, the previous and the following. With a selection listener I change the positions accordingly.
The way I load and dispose images as selection changes is the big deal here. The app downloads the images from Internet and cache them in FileSystemStorage. Those images are 768 x 1024. This is what I've tried with different luck:
Simply retrieve the images from FileSystem everytime a new page is requested:
if (FileSystemStorage.getInstance().exists(rutaImagen)) {
try {
int size = (int) FileSystemStorage.getInstance().getLength(rutaImagen);
EncodedImage imagenPubli = EncodedImage.create(FileSystemStorage.getInstance().openInputStream(rutaImagen), size);
} catch(IOException io) {
}
}
This has proven to be inefficient and risky in terms of memory usage. My iPad mini launch frequent low memory warnings, and end up killed by jetsam after a little while.
Store the images in a WeakHashMap, so Images don't need to be constantly loaded form FileSystemStorage, which seems to be the cause of problems and too expensive. Only if they are garbage collected, the first method comes in action.
This solution perfoms better, and the memory warnings are dramatically reduced, but are still there. After stressing hard the app, 15 or 20 minutes later jetsam jumps in and kill the app.
Similar approach: instead of WeakHashMap, I have tried CacheMap. This has been the best solution for me so far. I have to push hard to see some memory warnings once in a while, and no crash so far. Still not enterily happy though, because I believe I should not see any memory warnings at all.
I talk about iOS only here because the app performs well on Android whatever method I use, and I have never got any Out of Memory there.
What do you think? Am I in the right path? Would you guys use a different approach?
Thanks
I believe that you should use the "let-it-be-done" approach. So far you have tried to code everything yourself, while codenameOne has many optimized way of doing it. The easiest way would be to use a MultiList, which will display your images (by using an UrlImage). The UrlImage will allow codenameone to handle the caching and else. Basically, the image will be loaded when viewed and placed in cache afterwards.
It's unclear from the question where the magazine page is just an image. If so I would suggest using the ImageViewer class as it was designed exactly with the use case of an infinite list of large images to swipe and zoom thru.
The general strategy with the Tabs seems like a good start if you need something more elaborate than images. If it doesn't perform well you can always substitute Tabs for something else.

Is there anyway to improve the Javascript Built Apps's web page loading time?

I found the first web page loading time for CN1 Javascript Built taking too long, need about 2 minutes.
I attached the Chrome's network loading screen shot, found the classes.js is the most heavy page, possible to zip it?
Second, there is 2 theme files that downloaded sequentially, is it possible for them to load at the same time?
Kindly advice.
Normally I would answer that you can look at the performance section of the developer guide but the relevant sections there relate to reducing the theme.res size which seems pretty small in your case.
The largest portion in your code is the class files so I'm guessing that the best way to reduce them is to further reduce dependencies so the obfucator can remove more dead code. Keep in mind that the classes.js file is cached and can be deployed via CDN's such as cloudflair to improve download speeds. It can be served in a gzipped form as well which is a part of the CDN repertoire.

Resources