【问题标题】:Are cached images loaded by the browser when offline?离线时浏览器会加载缓存的图像吗?
【发布时间】:2016-10-06 06:31:33
【问题描述】:

我正在使用 AngularJS,我正在开发 SPA。我的目标是提供离线浏览。 JSON数据可以方便的存储在js变量中,图片可以缓存在Image对象中。

所以现在我想知道.. 如果一个人离线并尝试浏览内容,会发生什么?

1) 浏览器无法加载图像,因为处于离线状态,它无法检查图像的最新版本(缓存的还是在线的)

2) 浏览器在缓存中找到图像的引用。即使浏览器无法检查在线图像的最新版本,也会加载缓存的图像

注意:这不是一个重复的问题。

我使用 Angular 的事实与问题无关。会有其他人使用其他框架并寻找通用解决方案。

其次.. 这些答案只是指出使用 HTML5 和服务工作者。与 AngularJS 无关的事情。

【问题讨论】:

  • 首先,如果用户离线(未连接),您的应用程序将如何从服务器加载?
  • 这个故事的开端是:用户在线,有离线浏览内容的需求。因此,该应用程序将需要一些时间来下载数据和图像。每个页面(无限滚动)的 json 大约 15kb,而图像 100kb。
  • 我知道的大多数浏览器只会说您离线或“未连接到 Internet”(尝试在 iOS 上打开飞行模式并刷新页面以进行快速演示)。除非浏览器具有特定的“离线模式”,它实际上会下载所有内容,在这种情况下,它不是“缓存”,而是实际保存的页面

标签: javascript angularjs caching offline-caching


【解决方案1】:

好的,阅读您的答案后,最有用的是@Alexjohnson 答案中的那篇文章。 Makes Angular JS works offline 谈到浏览器缓存:

本机“旧”缓存在这里不起作用,因为它仍然需要 与服务器通信以获得“304 Not Modified”http 代码。

但我已经尝试过this technique,它的效果很奇怪。小伙伴们请自行尝试,你会看到,图片预加载后下线,图片就会显示出来。如果您将另一个 img 元素与网络图像的引用一起放置,则不会加载。

如果刷新页面,将显示缓存的图像。

您对此有何看法?

这是一个例子:

<html>
    <head>
    </head>

    <body>
        <script type="text/javascript">
            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;
            }
        </script>


        <!-- 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>

【讨论】:

    【解决方案2】:

    不满意但诚实的答案是“视情况而定”。除非您通过在 AppCache 或 ServiceWorker 中列出您的图像来使用特定说明,否则浏览器缓存可能会或可能不会显示您的图像。较旧的浏览器会在您离线打开文件时显示 HTML 文档及其内容,但确实具有上述功能的浏览器会更积极地告诉您您离线并且根本不会显示该页面。原因是浏览器制造商无法保证良好的体验,因此您不会显示可能会或可能不会显示图像的文档,而是会收到“您离线”消息。

    您可以指示浏览器将图像缓存很长时间,这会增加它们被显示的可能性https://developers.google.com/speed/docs/insights/LeverageBrowserCaching 但是没有明确的方法可以指示浏览器不要查找它们的较新版本,除非您在AppCache 或 ServiceWorker。

    【讨论】:

      【解决方案3】:

      我建议对您的图像进行 base64 编码,这实际上将它们转换为字符串。 Base64 字符串可用作图像源。您可以将这些字符串保存到 localStorage 中,并在离线时读取它们。

      查看此代码:

          <img src="#" class="myImage" />   
      
          <style type="text/css">
              .myImage {
            content: url('data:image/gif;base64,R0lGODlhEAAQALMPAAAAAIAAAACAAICAAAAAgIAAgACAgMDAwICAgP8AAAD/AP//AAAA//8A/wD//////yH5BAEAAA8ALAAAAAAQABAAQAQ78EkJqp10LaB759sDVh4ZiqVVTqC3om6smVvcAmz74Zioz7zMRmfC/WTAGXI0Ws5gtc+HhXz2fJagJAIAOw==');
          }
          
          </style>

      【讨论】:

      • 是的,这可行,但它会显着降低 DOM 渲染性能。与原始尺寸相比,Base64 编码的图像很大。
      【解决方案4】:

      作为 Alex Johnson 回答的伴侣,您可能应该查看Service Workers API。在this Github repo 中也对该技术进行了很好的解释。它将允许您确保您的架构支持愉快的离线体验。

      【讨论】:

      • 很好的补充!感谢分享。 Service Worker 仍然被认为是一种“实验性技术”,但肯定值得研究。
      【解决方案5】:

      浏览器缓存不适合在客户端未连接到互联网(离线)时使网站保留功能。

      看看:Makes Angular JS works offline

      您可以通过多种方式将资产提供给离线用户。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-09-30
        • 1970-01-01
        • 2013-07-08
        • 2014-03-26
        • 2019-10-03
        • 2014-11-16
        • 2014-02-06
        相关资源
        最近更新 更多