【问题标题】:Best practice for inlining images using data:-URLs?使用数据内联图像的最佳实践:-URL?
【发布时间】:2012-08-13 13:10:07
【问题描述】:

我有一个简单的 Rails 应用程序,它使用 canvasContext.toDataURL() 在 HTML5 站点中存储用户创建的图像。有一个 index 动作,显示缩略图列表,还有一个显示每个图像的动作,显示图像。

我这里绝对是在后台偷懒,我只是存储了原始图像的base64编码的data:image/png;base64,...字符串和一个缩略图,它也是在客户端生成的。图片使用<img src="data:"/> URI 包含在页面中。

现在,由于 v9 之前的 IE 不完全支持此功能,我将不得不实施某种解决方法,可能通过使用 data- 属性包含生成图像的 URL,然后在页面后替换源属性使用 jQuery 加载。

这提出了一个问题,使用data: URL 将相当大的图像内联到 HTML 中是否是一种好习惯...

是否有任何建议或最佳做法?图像可能高达 500 KiB,并且每个图像仅使用一次。包含图像的页面一旦创建就不会更改,因此它应该可以很好地缓存,包括图像。包含缩略图的索引页面(大约 60 KiB)使用分页,因此该页面几乎不可缓存。您可以假设 HTML 页面在生产中会被压缩或压缩。

【问题讨论】:

    标签: html image


    【解决方案1】:

    最佳做法是:不要。

    无论如何,您都需要一种解决方法,这将完全复制基本功能,因此您只是在另一个地方可能会出错并需要测试更多案例。

    您说图像应该非常可缓存,但您发送它们的方式不允许您包含有关缓存的信息。但是,使用通过单独的 HTTP 请求发送图像的更常见方法,您可以发送 expires 和 max-age 请求以指示图像在一年内不会更改。如果您对图像不会更改非常有信心,您还可以设置最后修改和电子标签(您甚至不需要任何逻辑来决定电子标签,只需发送“IMMUTABLE”作为标签) 并通过发送 304 甚至不检查来响应每个条件 GET(因为同样,只有在您超级自信时才这样做,否则尽管您仍然可以对 304 实施更常规的检查) .

    如果图像只使用一次,则让创建它的东西提供图像,并根据查询中的一些识别特征(正是你正在做的事情)写入它,并将其写入流中浏览器。您仍然可以在应用程序中进行更好的分离,以便在自己的位置完成此操作。

    即使使用 gzip,您也无法在流大小上击败它。

    【讨论】:

    • 包含图像的整个页面在创建后不会改变,我在我的问题中澄清了这一点。
    • @amiuhle 我坚持我的回答。如果您不需要 IE 的另一个实现,则可以提出一个论点,但是您仍然需要完成所有工作,那么通过使用data: 可以获得什么?
    • 没关系,我只是想澄清一下。就像我说的,在发现 IE 问题之前我已经实现了这个。谢谢你的回答。
    【解决方案2】:

    这不是一个好主意。我会改用普通的、单独的图像资源。

    通过使用内嵌图片,

    • 您破坏了静态图像的所有可缓存性 - 对于内联图像,每次 HTML 页面更改时,所有图像数据都必须重新加载。

    • gzipping/deflating 会花费更长的时间,并且会产生次优结果(因为图像数据更难压缩且效率更低)。

    • Internet 的其余部分面向 HTML 文档和图像作为单独的资源:预取器、缓存系统、代理...

    • 那么你就有了浏览器兼容性,正如你所指出的,这对于旧版 IE 来说是非常糟糕的。

    【讨论】:

    • 包含图像的整个页面在创建后不会改变,我在我的问题中澄清了这一点。
    • @amiuhle 这仍然不是一个好主意 - 压缩在服务器上会更加繁重......为什么这样做而不是使用适当的普通图像资源?
    • 就像我说的,我在后端很懒惰。我可以将图像数据作为文本存储在 MongoDB 中,避免诸如必须同步 db 和文件系统之类的事情。这是一个负载很小的小项目,肯定会以这种方式工作。之后我只是偶然发现了 IE 的问题,并开始想知道最好的方法是什么。
    • @amiuhle 只是将每张图片作为一个单独的资源提供......用任何语言都很容易做到。它会为你省去很多痛苦
    【解决方案3】:

    我的建议?不要这样做。

    使用后端库可以更轻松地修改真实文件,所以不要这样做。 如果您想在页面中使用 base64,您可以使用 HTML5 轻松实现。

    var xhr = new XMLHttpRequest();
    xhr.open('GET', 'images/myimage.png', true);
    xhr.responseType = 'arraybuffer';
    
    xhr.onload = function(e){
        if(this.status == 200){
            var bb = new WebKitBlobBuilder(); // Or MozBlobBuilder, MSBlobBuilder, etc.
            bb.append(this.response);
    
            var reader = new FileReader();
            reader.readAsDataURL(bb.getBlob('image/png'));
            reader.onloadend = function(e){
                $("#myimage").attr("src", reader.result);
            };
        }
    };
    
    xhr.send();
    

    【讨论】:

      猜你喜欢
      • 2014-09-20
      • 2020-02-09
      • 2013-02-17
      • 2023-03-24
      • 2012-09-26
      • 1970-01-01
      • 1970-01-01
      • 2010-11-06
      • 2014-05-23
      相关资源
      最近更新 更多