sch*_*der 4 javascript compression gif bzip2
我的程序Precomp可用于进一步压缩已压缩的文件格式,如GIF,PNG,PDF,ZIP等.粗略地总结,它通过解压缩压缩流,重新压缩它们并存储预期压缩流和实际压缩流之间的差异来实现.例如,维基百科的旋转地球图片从1429 KB压缩到755 KB.该过程是无损的,因此可以恢复原始GIF文件.
GIF文件格式的算法可以相对容易地隔离和实现,因此我在思考JavaScript中的概念验证实现.这将导致Web服务器发送GIF文件的压缩版本(.pcf结束,基本上是GIF图像内容的bzip2压缩文件),客户端解压缩数据,重新压缩到GIF并显示它.以下事情将要做:
该过程是带宽与客户端CPU使用率的交易.
现在我的问题如下:
让我们首先回答您的具体问题.代码示例如下.
Q&A
- 加载不同文件并将其"转换"为GIF的过程是否存在任何常见问题?
主要问题是并发症.你正在有效地编写一个浏览器插件,就像JPEG2000那样.
如果您正在编写真正的浏览器插件,每个主流浏览器都会采用不同的方式,并偶尔更改插件格式,因此您必须积极维护它们.
如果您正在编写JS库,那么编写和维护将更容易,但它将是无特权的,并且受到诸如交叉原始限制之类的限制.
- 在客户端完成之前,您建议显示什么(图像占位符)?
取决于您的格式可以提供什么.如果您提前对图像尺寸和小缩略图进行编码,则可以很早地显示准确的占位符.
这是你的格式,毕竟.
- 我该怎么做才能确保缓存.pcf文件?如果没有缓存,带宽节省是无用的.
与其他文件没什么不同.
在服务器端配置Expires和Cache-Control标头,它们将被缓存.
Manifest并且prefetch也可使用.
- 如果JavaScript被停用,有没有办法显示原始GIF,但如果激活JavaScript,则避免加载GIF?
这很棘手.禁用JavaScript时,您只能替换元素,而不能替换属性.
这意味着您无法在某个指向.pcf文件的位置创建图像,并要求浏览器在JS不可用时重写src属性.
我认为支持没有JS的最佳解决方案是输出图像document.write,使用noscript后退:
<noscript>
<img src=demo.gif width=90>
</noscript><script>
loadPcf("demo.pcf","width=90")
</script>
Run Code Online (Sandbox Code Playgroud)
(某些库或框架可能会让您考虑<img src=demo.gif data-pcf=demo.pcf>.这对您不起作用,因为浏览器会在您的脚本启动之前预先加载 'demo.gif',从而导致额外的数据传输.)
或者,浏览器插件不受"禁用JS"设置的影响,因此如果您改为使用插件,则无需担心它.
- 我可以为用户提供配置行为的方法吗?例如,在移动设备上,有些可能会避免带宽,但其他人可能希望减少CPU使用率.
也许.您可以编写用户界面代码并将首选项存储在cookie或localStorage中.然后,您可以检测首选项并在服务器代码(如果cookie)或客户端代码中切换逻辑.
如果您正在做插件,所有浏览器都提供可靠的首选项机制.问题在于,每个浏览器都会以不同的方式执行此操作.
- 是否可以按照假设显示隔行扫描的GIF(从粗略版本到最终图像)?这将需要在再压缩的不同阶段多次更新图像内容.
如果您向浏览器提供部分图像,他们可能会认为图像已损坏并拒绝显示.在这种情况下,您必须实现自己的GIF解码器和编码器,以便您可以手动浏览完整的占位符图像,只是为了安全起见.
- (新)我可以解码从其他网站加载的图像吗?
我还必须重复警告,非插件JS图像解码不适用于交叉原始图像.这意味着,所有.pcf文件必须与使用它的站点位于同一服务器,相同端口和相同协议上.
例如,您无法共享多个站点的图像或执行域分片等优化.
代码示例
这是一个最小的例子,它创建一个<img>,加载一个gif,一半的宽度,然后把它放回去<img>.
要支持占位符或渐进式加载,请在onload上监听on progress,而不是onload.
<!DOCTYPE html><html><head><meta charset="UTF-8"><script>
function loadPcf( file, attr ) {
var atr = attr || '', id = loadPcf.autoid = 1 + ~~loadPcf.autoid;
document.write( '<img id=pcf'+id+' ' + atr + ' />' );
var xhr = new XMLHttpRequest();
xhr.responseType = 'arraybuffer'; // IE 10+ only, sorry.
xhr.onload = function() { // I am loading gif for demo, you can load anything.
var data = xhr.response, img = document.querySelector( '#pcf' + id );
if ( ! img || ! data instanceof ArrayBuffer ) return;
var buf = new DataView( data ), head = buf.getUint32(0), width = buf.getUint16(6,1);
if ( head !== 1195984440 ) return console.log( 'Not a GIF: ' + file ); // 'GIF8' = 1195984440
// Modify data, image width in this case, and push it to the <img> as gif.
buf.setInt16( 6, ~~(width/2), 1 );
img.src = URL.createObjectURL( new Blob( [ buf.buffer ], { type: "image/gif" } ) );
};
xhr.open( 'GET', file );
xhr.send();
}
</script>
<h1>Foo<noscript><img src=a.gif width=90></noscript><script>loadPcf("a.gif","width=90")</script>Bar</h1>
Run Code Online (Sandbox Code Playgroud)
如果你不需要<noscript>兼容性(因此阻止facebook/google +在共享页面时看到图像),你可以将pcf文件放在<img>src中并使用JS来处理它们,所以你不需要为每个图像调用loadPcf并使html 更加简单.
怎么样<video>?
从理论上讲,你所设想的大多数是可行的,但也许你应该重新考虑.
从您提出的问题来看,您很难顺利地定义和实现您的愿景.这也许是更好的动画编码中的WebM和使用<video>代替.
<video>有一些自适应视频技术,希望它们能很快稳定下来.<video>不依赖于JavaScript.对于非动画,PNG也可以进行颜色索引和7z 优化(保持PNG格式).图标大小索引PNG通常小于相同的GIF.
或许您的愿景(如pcf网站所述)能够编码许多不同的文件,而不仅仅是GIF.这更像是支持新的网络协议,并且可能超出了简陋的JavaScript范围.(例如,你将如何处理PDF格式下载或流媒体?)