HTML5 app - avoid downloading every time? - html

I am getting ready to develop an HTML5 application. It's not a game but for sake of discussion let's call it a simple game.
Let's say I host the app/game on my web server.
User clicks to my web server, downloads the game (may take several seconds, to a minute?), sends a high score to the server, is put on a leaderboard.
Tomorrow the user comes back and wants to play again. Does the user need to download the game again?
Or, is this where the cache manifest can be used to prevent a re-download?
And, if they don't have to download the whole thing everytime, how can I force a download if I want an update to the game?

Browser Cache
If you do nothing the browser will download and cache copies of any static files your application uses the first time it encounters them. This is automatic and the files are stored in the browser cache.
The next time the file is requested by your application the browser will send a request to the server and include the date and time of the copy it already has. If the file has changed on the server a new copy will be provided. If not, the server will respond with a 304 code - Not modified and the browser will use its existing copy. In this case a request is always sent to the server, but the file is only downloaded if it's changed.
You can configure your server to add an expiry date to static files. The browser still caches the file locally as before, but on the next access the browser checks the expiry date sent with the copy it already has. If that date hasn't passed no request is sent to the server. Now, you've saved the round-trip time of every request that refers to a cached file.
A manifest
A manifest works differently. When the initial file is downloaded the cache maifest is read and every file listed in it (apart from some specific exceptions dependent on the content of the manifest) is downloaded and store in the application store. Often, this requires the user to give permission for it to happen.
On subsequent access the manifest file is requested from the server. If the manifest hasn't changed nothing more is done and the application is loaded and run from files stored in the application store.
if the manifest has changed in any way then the new manifest is used to download and update the existing application store files.
Pros and cons
Browser cache
For
Automatic & transparent
Largely maintenance free
Many files need not be downloaded or checked
Against
Distribution of new files may be delayed
Application must run online
Manifest
For
Application can run offline
Manifest gives good control over update distribution
Against
User permission often required to use the application store
Additional maintenance is required to update the manifest appropriately.

Related

How to get updated server files from elastic beanstalk?

I am hosting my server for my website on AWS Elastic beanstalk. On my server I am storing files that are getting uploaded by end users (or myself) in an "Images" folder. Thus new files are getting created in the folder every time an image gets uploaded to the website.
How can i download the latest file of my server on E.B. with these new images. I can download the original zip file I uploaded but it doesn't have the new data in the folders.
TY
You should not be storing any files worth anything on the EB node.
if user uploads content, you should be uploading that in turn to S3, or your DB, or any kind of file storage. That is usually decided during architecture.
So while the actual answer is "this should never happened in the first place", I must precise the main reason is that auto-scaling can kill your nodes without you knowing. which would destroy the uploads. or bring new nodes, spreading your content through multiple nodes.
While I also understand this answer might not be helping you if you already done the mistake have content to be transfered out of the node. I would
disable autoscaling
enable termination protection on the node
transfer data via rsync/ssh/s3 or favorite different options by SSH
automate transfer method to be done a subsequent time.
implement new upload method for the future of your app
deploy new method so no new content is uploaded to previous storage location
re-transfer your date from old to new storage location.
disable termination protection and reenable autoscaling
make sure new nodes and receiving traffic and why not kill that previous node
remember servers are cattle not pets

Where to store application data for webapp?

I have some data for a webapp that I would like to store on the server. What would be a good location to put those files?
I have a couple of static HTML pages that contain instance specific information. They need to survive a re-deploy of the webapp. They need to be editable by the server's administrator. They are included in other HTML pages using the html object tag.
I want to store preferences on the server, but cannot use a database. I am using JSP to write and read the preferences. There is no sensitive data in the preferences. Currently I am using the log directory. But obviously that is not a great choice.
I am using Tomcat. I thought of creating an appdata/myapp directory under the webapp directory. Is that good or bad?
If the server's administrator can also deploy the app, I would add the data file itself into the source control for the app, and deploy it all together. This way you get revision control of the data, and you get the ability to revert to known good data if the server fails.
If the administrator can't deploy the app, but can only edit the file, then you need plans to back up that file in the case that the server or server filesystem dies.
A third solution would be a hybrid: put the app in one source code repository. Put the data in a second source code repository. The administrator can edit the data and deploy the data. The developer can edit the app source code, and deploy the source code. This way, both are revision controlled, but you've separated responsibility for who maintains what.

Control appcache download

I've developed an iPad web app that uses the appcache. It's not intended to be a fully offline app but I use the appcache to store large image files so that they're not sent over 3G. Problem is when the manifest is updated the appcache updates whether the iPad is on wifi or 3G, which could be expensive.
Is it possible to have the user decide if the appcache can be updated or not? From what I've seen, this isn't possible, it all happens automatically, you just get events. But perhaps there's some trickery like writing the manifest on the fly or similar.
Using PHP on the server side if that helps. Thanks.
Connection Type: Theory & Future
There is a draft spec of Network Information API on W3C that provides the information of the connection type (ethernet wifi 2g 3g 4g etc.), but it hasn't been implemented on any browser yet apart from:
the stock Android browser on Android 2.2+ (not the Google Chrome browser)
navigator.connection.type // Based on W3C draft, (Implemented on stock Android browser)
and PhoneGap which is not exactly a browser
navigator.network.connection.type // on PhoneGap
Having that information in the future you could detect if the user has cellular data, then temporarily remove the src of the images and ask the user through a confirmation dialog.
You will also probably have to cancel the app cache update using:
window.applicationCache.abort() (documentation)
Reality
Unfortunately, the Net Info API is not available (at least not widespread) at the moment, but certainly will help in the future.
Long shot
There is a database that includes network speed (DIAL = dial up, DSL = broadband/cable, COMP = company/T1), but I haven't used it and I doubt it will help.
Dynamic App Cache
While checking into this, I tried to generate the html tag along with the manifest declaration on the fly, in order to combine it with the Network Info API but the AppCache manifest is loaded before javascript execution and is not affected afterwards.
So altering the manifest file on the fly through Javascript is not possible and data URI is not an option.
Alternative solution
HTML5 application cache is an untamed beast at the moment and there are talks to improve it. Until it changes to support more complex configurations (bandwidth level flag would be awesome), you could change perspective on the solution, although App Cache may be the best you have at the moment.
Depending on how big your images are you could rely on the normal browser cache. You could combine localStorage and far-future expiration HTTP headers. LocalStorage in order to keep track of the loaded/cached images.
First add a far in the future date for expiration on your images HTTP headers
On page load, remove all src from imgs
Loop the images and check localStorage if each image was loaded in the past
If there are images that were not loaded in the past, display a dialog confirming for the downloading of those images
If the image was loaded in the past, then put back the src on the img
For every image that is downloaded, save its URL on localStorage
I don't know what the status of indexedDB is on the iPad, but this could be an alternative solution.
In short: Indexeddb is a clientside database. Data is stored in object stores which are key/value pairs. The maximum storage capacity is in theory the maximum of your disk space. For more information about indexeddb:
Specification
My blog
What you could do with the indexeddb:
When someone navigates to a page:
Check every image tag if it is present in the indexeddb
if present
Get the image from the indexeddb and put it in the image tag
if not present
Download it
store it in the indexeddb
put the image in the image tag.
As extra (in the future) you can do as discribed by Sev: check the connetion type and only download the image when working on a fast internet connection.
I have 'invented' a working solution developing a webapp on the iPad (iOS 6.0.x) that may answer your question.
The idea is first to check if a localstorage variable is set/defined or not yet (I use the title of the page, thus the webapp name.)
If this localstorage variable exists, then assume (in webapp sandbox context) that its the first time the app is being run. At this point I populate a UUID in conjunction with $PHP_SESSION($uuid) to avoid 'cross app contamination' in server-side PHP land.
In addition to this I have a dynamic manifest.appcache.php which includes in the CACHE section a list of files to add to the manifest. Thus;
<?
echo $manifest_file_list[0]."\n";
?>
Using the JS appcache manifest event listeners I then monitor the progress to something like $('#manifestappcache').html(result);

Change in cache-manifest file

Whenever there is a change in cache-manifest file i.e. a resource is changed, do I need to redeploy my web application on server or can I update the files dynamically i.e. is there any way to update the files dynamically when the server is running.
Assuming you are talking about the HTML5 cache manifest for an offline web application -- when you modify the cache-manifest file, all of the assets listed in the manifest are re-downloaded to the client browser when they access it next. There is no way to selectively update individual files in the cache. It's all or nothing unfortunately.
Also, I've found the the file containing the is automatically cached even if it's not listed in the manifest. When the manifest changes, this file is replaced, but only after it's loaded... so it effectively requires an additional refresh to see the changes. I've seen various JavaScript hacks to force a reload if the cache updates.
I wrote a fairly extensive blog post on html5 app cache and the various aspects of the manifest file at http://gregsramblings.com/2012/05/28/html5-application-cache-how-to/

How to solve this issue with the HTML5 manifest?

From my experiences so far, I've concluded that the HTML5 Manifest scheme was really terribly designed.
My site serves a manifest file when a user is logged in. Unfortunately, when they log out, they can still access the cached protected materials. Can anyone think of a way to fix this?
A manifest file is designed to take a website offline and still be able to navigate. It essentially just tells the browser to download and keep that stuff in cache. If your adding secret stuff to the manifest and the user goes offline, he needs to be able to still access it - or whats the point of having a special logged-in-manifest-file if he has to be loggedin (therefor online)?
You could add javascript that checks if the user is online again and if he is, tries to validate the "login state" and redirects or removes the secret stuff from localstorage (if you would use localstorage to save the "secret" stuff and javascript to display it instead of a manifest file )
Lets say the secret stuff is an image and you are not using a manifest file, but just displaying images when the user is logged in and its crusial, the user cant view that image after logout, you would need to set the http headers to no-cache and cache-expire to some random date of the past, so that a normal user would see it anymore. Problem then is, that the image is downloaded everytime somebody visits the website..
You need to approach the HTML5 Application Cache in a different way. It is not useful for caching server-side dynamically generated pages, especially those that require a login to reach. The Application Cache has no concept of logins, nor securing a page from somebody with a different/no login.
It is much more appropriate for an AJAX-based site, where all HTML/CSS/JavaScript is static and registered in the Application Cache, and data is instead fetched via AJAX then used to populate pages. If you need to cache data in the application for offline use, then use one of the offline data storage mechanisms such as Local Storage/Session Storage, or IndexedDB, for data.
You can then make your own judgement on how much data you want to cache offline, since there's no way to validate a login without making a call to the server that is naturally inaccessable whilst offline.
What if when the user logs out or is not logged in they get a manifest with only network:*