Optimizing a slideshow and an image gallery [GAE / GWT]? - google-app-engine

I would like to implement my own slideshow and image gallery (for a foto reporting website).
Is there a best approach or tehcniques (using GAE and GWT) related to :
reducing the slideshow's loading time (a slideshow containing 30 images (960px * 780px) for example, should I load them all firstly and then let the user navigating ?)
should I do scaling operation (the image's resolution is greater than the browser's one) on the server side or in the client side ?
is there some know-well problem concerning the storage (if I have a lot of images) ?
If you have some advice or links about this topics, could you post them please ? Thanks you.

Question 1: preload vs lazy
Answer: The more you load to start the longer it takes your instance to spin up and the longer and larger the bandwidth. So in general you should probably use a lazy loader but prefetch the thumbnails and the next image.
Question 2: image scaling
Answer: I suggest creating a scaled version on upload that you serve then allow the user to download the full size image. Don't do this on the client again the bandwidth would eat you alive.
Question 3: storage
Answer: Use the blobstore/python or blobstore/java instead of db.BlobProperty because it saves money on storage and allows for files over 1mb.

Related

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!

Codename One URLImage reduce image resolution and size

The app I am building is to take a member picture and save to amazon s3 bucket.
Again thanks Codename one team( especially Shai) for helping me out through the process.
I am now facing some performance issue as in I am using iPhone 6s Plus. When I take the picture and reload the label with the image, it takes really long time to load.
Is there any way to reduce the picture size and resolution before saving to amazon s3 bucket? Or what would be the best practice or optimized way of achieving this? Please suggest.
Thanks,
Yes.
You can use the version of capture that accepts width/height notice that -1 will keep the aspect ratio for that axis.
You can also use ImageIO to resize an image to any arbitrary size without opening the file.

Is it possible with Codename One to take a temporary photo?

Part of the process used in my app involves taking a photo (done with Capture.capturePhoto()). The photo is then resized to a small square of 200px and finally sent to a server.
I am able to delete the resized image with FileSystemStorage.delete() however the initial photo taken with Capture.capturePhoto() cannot be deleted because of the app being sand boxed (as described in this SO question )
This can be embarrassing for the user because these photos are polluting their gallery (the photos have no value for the user).
As deleting the initial photo is not possible, I was wondering if I could force the Captured photo to be stored in cache so that it gets automatically removed by the OS.
Maybe this question could be a solution for Android but I would prefer to avoid having to go native?
Consequently is it possible with Codename one to take a photo that will only be temporary and be deleted automatically ?
Thanks a lot,
Cheers
We try to delete the file automatically but since the OS takes the photo some platforms just stick it in the gallery and there isn't much we can do there. It's literally a matter of "this works on Android device A and fails on Android device B".
Apps like snapchat etc. don't use the device camera app but instead use the low level camera API's which are more complex and flaky. At this time we don't map these API's in Codename One so if you need something with lower level control you will need to use native interfaces. This is a non-trivial API though.

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.

Question on serving Images on App Engine ( 2 Alternatives )

planning to launch a comic site which serves comic strips (images).
I have little prior experience to serving/caching images.
so these are my 2 methods i'm considering:
1. Using LinkProperty
class Comic(db.Model)
image_link = db.LinkProperty()
timestamp = db.DateTimeProperty(auto_now=True)
Advantages:
The images are get-ed from the disk space itself ( and disk space is cheap i take it?)
I can easily set up app.yaml with an expiration date to cache the content in user's browser
I can set up memcache to retrieve the entities faster (for high traffic)
2. Using BlobProperty
I used this tutorial , it worked pretty neat. http://code.google.com/appengine/articles/images.html
Side question: Can I say that using BlobProperty sort of "protects" my images from outside linkage? That means people can't just link directly to the comic strips
I have a few worries for method 2.
I can obviously memcache these entities for faster reads.
But then:
Is memcaching images a good thing? My images are large (100-200kb per image). I think memcache allows only up to 4 GB of cached data? Or is it 1 Mb per memcached entity, with unlimited entities...
What if appengine's memcache fails? -> Solution: I'd have to go back to the datastore.
How do I cache these images in the user's browser? If I was doing method no. 1, I could just easily add to my app.yaml the expiration date for the content, and pictures get cached user side.
would like to hear your thoughts.
Should I use method 1 or 2? method 1 sounds dead simple and straightforward, should I be wary of it?
[EDITED]
How do solve this dilemma?
Dilemma: The last thing I want to do is to prevent people from getting the direct link to the image and putting it up on bit.ly because the user will automatically get directed to only the image on my server
( and not the advertising/content around it if the user had accessed it from the main page itself )
You're going to be using a lot of bandwidth to transfer all these images from the server to the clients (browsers). Remember appengine has a maximum number of files you can upload, I think it is 1000 but it may have increased recently. And if you want to control access to the files I do not think you can use option #1.
Option #2 is good, but your bandwidth and storage costs are going to be high if you have a lot of content. To solve this problem people usually turn to Content Delivery Networks (CDNs). Amazon S3 and edgecast.com are two such CDNs that support token based access urls. Meaning, you can generate a token in your appengine app that that is good for either the IP address, time, geography and some other criteria and then give your cdn url with this token to the requestor. The CDN serves your images and does the access checks based on the token. This will help you control access, but remember if there is a will, there is a way and you can't 100% secure anything - but you probably get reasonably close.
So instead of storing the content in appengine, you would store it on the cdn, and use appengine to create urls with tokens pointing to the content on the cdn.
Here are some links about the signed urls. I've used both of these :
http://jets3t.s3.amazonaws.com/toolkit/code-samples.html#signed-urls
http://www.edgecast.com/edgecast_difference.htm - look at 'Content Security'
In terms of solving your dilemma, I think that there are a couple of alternatives:
you could cause the images to be
rendered in a Flash object that would
download the images from your server
in some kind of encrypted format that
it would know how to decode. This would
involve quite a bit of up-front work.
you could have a valid-one-time link
for the image. Each time that you
generated the surrounding web page,
the link to the image would be
generated randomly, and the
image-serving code would invalidate
that link after allowing it one time. If you
have a high-traffic web-site, this would be a very
resource-intensive scheme.
Really, though, you want to consider just how much work it is worth to force people to see ads, especially when a goodly number of them will be coming to your site via Firefox, and there's almost nothing that you can do to circumvent AdBlock.
In terms of choosing between your two methods, there are a couple of things to think about. With option one, where are are storing the images as static files, you will only be able to add new images by doing an appcfg.py update. Since AppEngine application do not allow you to write to the filesystem, you will need to add new images to your development code and do a code deployment. This might be difficult from a site management perspective. Also, serving the images form memcache would likely not offer you an improvement performance over having them served as static files.
Your second option, putting the images in the datastore does protect your images from linking only to the extent that you have some power to control through logic if they are served or not. The problem that you will encounter is that making that decision is difficult. Remember that HTTP is stateless, so finding a way to distinguish a request from a link that is external to your application and one that is internal to your application is going to require trickery.
My personal feeling is that jumping through hoops to make sure that people can't see your comics with seeing ads is solving the prolbem the wrong way. If the content that you are publishing is worth protecting, people will flock to your website to enjoy it anyway. Through high volumes of traffic, you will more than make up for anyone who directly links to your image, thus circumventing a few ad serves. Don't try to outsmart your consumers. Deliver outstanding content, and you will make plenty of money.
Your method #1 isn't practical: You'd need to upload a new version of your app for each new comic strip.
Your method #2 should work fine. It doesn't automatically "protect" your images from being hotlinked - they're still served up on a URL like any other image - but you can write whatever code you want in the image serving handler to try and prevent abuse.
A third option, and a variant of #2, is to use the new Blob API. Instead of storing the image itself in the datastore, you can store the blob key, and your image handler just instructs the blobstore infrastructure what image to serve.

Resources