1

I'm using AngularJS and I'm developing SPA. My goal was to provide offline brwosing. JSON data can be easily stored in js variables, images can be cached in Image objects.

So now I'm wondering.. if one person goes offline and tries to browse the content, what will happen?

1) the browser can't load the image because, being offline, it can't check what is the most-recent version of the image (the one cached or the one online)

2) the browser finds a reference for the image in the cache. The cached image is loaded even if the browser can't check the online image for the most-recent version

NOTE: THIS IS NOT A DUPLICATE QUESTION.

The fact I'm using Angular doesn't matter for the problem. There will be other people using other frameworks and looking for a general solution.

Secondly.. those answers just points out to use HTML5 and service workers. Things not related to AngularJS.

FrancescoN
  • 2,146
  • 12
  • 34
  • 45
  • First of all how is your app going to load from server if user is offline (not connected)? – Nikhil Vartak Jun 06 '16 at 15:20
  • the start of this story is: the user is online and has the need to browse the content offline. So the app will take some time to download data and images. the json for each page (infinite scroll) is about 15kb, while the images 100kb. – FrancescoN Jun 06 '16 at 15:22
  • most browsers I know of will just say you are offline or "not connected to the Internet" (try turning on airplane mode on iOS and refresh the page for a quick demo). Unless the browser has a specific "offline mode" where it actually downloads all the content, in which case it's not a "cache" but the actual saved page – Krease Jun 06 '16 at 15:25
  • Possible duplicate of [Makes Angular JS works offline](http://stackoverflow.com/questions/23652183/makes-angular-js-works-offline) – Krease Jun 06 '16 at 15:36

5 Answers5

1

Browser caching is not a suitable replacement for making a site retain functionality when the client isn't connected to the internet (offline).

Take a look at: Makes Angular JS works offline

There are a number of ways in which you can make assets available to offline users.

Community
  • 1
  • 1
Alex Johnson
  • 1,504
  • 13
  • 20
1

As a companion to Alex Johnson's answer, you should probably check out the Service Workers API. There is also a good explanation of the technology in this Github repo. It will allow you to ensure your architecture supports a pleasurable offline experience.

  • Good addition! Thanks for sharing. Service workers are still considered an "experimental technology", but certainly worth looking into. – Alex Johnson Jun 06 '16 at 15:37
1

I recommend base64 encoding your images, which essentially turns them into strings. Base64 strings can be used as image source. You can save these strings into localStorage, and read them when you're offline.

Check out this code:

    <img src="#" class="myImage" />   

    <style type="text/css">
        .myImage {
      content: url('data:image/gif;base64,R0lGODlhEAAQALMPAAAAAIAAAACAAICAAAAAgIAAgACAgMDAwICAgP8AAAD/AP//AAAA//8A/wD//////yH5BAEAAA8ALAAAAAAQABAAQAQ78EkJqp10LaB759sDVh4ZiqVVTqC3om6smVvcAmz74Zioz7zMRmfC/WTAGXI0Ws5gtc+HhXz2fJagJAIAOw==');
    }
    
    </style>
nixkuroi
  • 2,259
  • 1
  • 19
  • 25
  • Yes this works but it can significantly slow down your DOM rendering performance. Base64 encoded images are huge compared to their original sizes. – Jos Nov 14 '18 at 10:23
1

The unsatisfactory, but honest answer is "it depends". Unless you use specific instructions by listing your image in an AppCache or ServiceWorker, the browser cache may or may not show your images. Older browsers showed the HTML document and the content it had when you opened the file offline, but browsers that do have features like the ones mentioned are more aggressive in telling you that you are offline and will not show the page at all. The reason is that browser makers could not guarantee a good experience so instead of showing a document that may or may not display the images you get a "you are offline" message.

You can instruct browsers to cache images for a long time, which increases the likelihood of them being displayed https://developers.google.com/speed/docs/insights/LeverageBrowserCaching but there is no clean way to instruct the browser not to look for a newer version of them unless you specify it in AppCache or a ServiceWorker.

user30934
  • 154
  • 1
0

Ok, after reading your answers, the most useful was the piece in @Alexjohnson answer. Makes Angular JS works offline says something about browser caching:

The native "old" caching won't work here, because it still requires to communicate with the server to have the "304 Not Modified" http code.

But I've tried this technique, and it strangely works. Guys please try this by yourself, you'll see, by going offline after image preloading, the image will be displayed. And if you put another img element with a reference to the web image, this won't be loaded.

If you refresh the page the image cached will be displayed.

What do you think about this?

Here is an example:

var my_image1 = new Image();
                var my_image2 = new Image();
                var images = 2, count_images = 0;
    
                // notify the user that the image has been preloaded, and reveal the
                // button to use the preloaded image
                function notify()
                {
                    count_images++;
                    if (count_images == images) {
                        document.getElementById('preloadbutton2').style.display = 'none';
                        document.getElementById('after_preload').style.display = 'block';
                    }
                    console.log('finito');      
                }
    
                function preload()
                {
                    my_image1.onload = notify;
                    my_image2.onload = notify;
    
                    my_image1.src = 'https://mir-s3-cdn-cf.behance.net/project_modules/max_1200/47351a35419617.56f6327af207a.gif';
                    my_image2.src = 'https://mir-s3-cdn-cf.behance.net/project_modules/max_1200/2150fb35419617.56f6327b44e47.gif';
                }
    
                // using only the file name, we can take advantage of the preloaded image
                function use_preloaded_image()
                {
                    document.getElementById('offline_1').src = my_image1.src;
                    document.getElementById('offline_2').src = my_image2.src;
                }
 <html>
        <head>
        </head>
    
        <body>
            <!-- INSTRUCTIONS 
    
                OPEN THIS FILE IN THE BROWSER WITH ONLINE NETWORK, CLICK ON THE BOTTON TO PUT IMAGES IN CACHE
                GO OFFLINE AND REALOAD THE PAGE (INSPECT ID DOF THE IMAGES: IMAGES FRO MTHE WEB WON'T BE LOADED, THE ONES CACHED WILL BE SHOWED)
                RELOAD THE PAGE: AS BEFORE, IMAGES FROM CACHE ARE STILL THERE, THEY'RE VISIBLE
            -->
        
            <!-- IMAGES FROM THE WEB -->
    
            <img src="https://mir-s3-cdn-cf.behance.net/project_modules/max_1200/5aa12735419617.56f6327ab4f72.gif" width="500px" />
            <img src="https://mir-s3-cdn-cf.behance.net/project_modules/max_1200/74f16635419617.56f6327adcf75.gif" width="500px" />
    
            <br/>
        
            <!-- IMGES PUT IN CACHE ON BUTTON CLICK -->
    
            <input type="button" 
                id="preloadbutton2" 
                value="Preload Image" 
                onclick="preload();this.value='Loading. Please wait...'" />
    
            <div id="after_preload" style="display: none">
                <input type="button" value="Use Preloaded Image"
                onclick="use_preloaded_image()" /><br />
                <img src="" id="offline_1"  width="500px" />
                <img src="" id="offline_2" width="500px" />
                
            </div>
    
        </body>
    </html>
Synoon
  • 2,297
  • 4
  • 22
  • 37
FrancescoN
  • 2,146
  • 12
  • 34
  • 45