简体   繁体   English

如何在 React Single page Web App 中使用 AVIF 图像

[英]How do I use AVIF images in React Single page Web App

Final Update最终更新

For most practical purposes, this question is obsolete as both firefox and chrome have native support for avif through the standard picture html tag with a source marked as type="image/avif".对于大多数实际目的,这个问题已经过时了,因为 firefox 和 chrome 都通过标准图片 html 标签对 avif 提供了本地支持,源标记为 type="image/avif"。 See https://reachlightspeed.com/blog/using-the-new-high-performance-avif-image-format-on-the-web-today/ .请参阅https://reachlightspeed.com/blog/using-the-new-high-performance-avif-image-format-on-the-web-today/ Fire fox still likes to hang and often forces a control F5 to bypass caches and requires sending the correct content type from the server. Fire fox 仍然喜欢挂起并经常强制控制 F5 绕过缓存并要求从服务器发送正确的内容类型。 Hopefully will be fixed soon.希望能尽快修复。

Here is the commit where I got avif support working: https://github.com/quackack/quackack-comics/commit/f1a98ed1f40b6a22584d61bc338bd91df3232fa5#diff-e25b0950ce48f4e928f98e0a6fbb694c .这是我得到 avif 支持的提交: https : //github.com/quackack/quackack-comics/commit/f1a98ed1f40b6a22584d61bc338bd91df3232fa5#diff-e25b0950ce48f4e928f98e94cf . Note that it contains many unrelated changes and in fact avif is barely mentioned, only as a content type and a file extension.请注意,它包含许多不相关的更改,实际上几乎没有提到 avif,仅作为内容类型和文件扩展名。

Original Question原始问题

I am trying to change a website where I host web comics from using jpegs to the newer avif image format.我正在尝试将托管网络漫画的网站从使用 jpeg 更改为更新的 avif 图像格式。 It is much smaller and seems to be the new image format with the most widespread support.它要小得多,似乎是支持最广泛的新图像格式。 Unfortunately, web browsers don't properly support the new format yet.不幸的是,网络浏览器还不能正确支持新格式。 So I was planning to use this package: https://github.com/Kagami/avif.js to allow my comics to be rendered.所以我打算使用这个包: https : //github.com/Kagami/avif.js来渲染我的漫画。 Some basic tests showed that AVIF would give the same quality as jpeg for less than half the space.一些基本测试表明,AVIF 将在不到一半的空间内提供与 jpeg 相同的质量。

Unfortunately, after more than 5 hours of time spent on this, I am unable to get this to work with my react framework.不幸的是,在花费超过 5 个小时的时间之后,我无法让它与我的反应框架一起工作。 You can see my website at the time of writing at 'https://github.com/quackack/quackack-comics/tree/cda4c3893d8477192c4ff3aa78d00096b7621ff7'.您可以在撰写本文时在“https://github.com/quackack/quackack-comics/tree/cda4c3893d8477192c4ff3aa78d00096b7621ff7”看到我的网站。

I tried using npm install to install avif.js and then added我尝试使用 npm install 安装 avif.js 然后添加

require("avif.js").register("/avif-sw.js");

to index.js .到 index.js 。 But I get error但我得到错误

Failed to register/update a ServiceWorker for scope ‘http://localhost:3000/’: Bad Content-Type of ‘text/html’ received for script ‘http://localhost:3000/avif-sw.js’. Must be a JavaScript MIME type

And avif files are still not able to load.而且 avif 文件仍然无法加载。 I think the requests are getting rerouted to index.html instead of the javascript package.我认为请求被重新路由到 index.html 而不是 javascript 包。 It seems like the appropriate thing to do is something like似乎应该做的事情是这样的

import * as avif from 'avif.js';
avif.register('avif.js/avif-sw.js');

But this fails too with the same error, as do many other similar variations.但这也失败了,并出现了相同的错误,许多其他类似的变化也是如此。

At this point I am inclined to wait for proper browser support for avif, as I don't get enough traffic to worry about data costs anyway.在这一点上,我倾向于等待对 avif 的适当浏览器支持,因为无论如何我都没有足够的流量来担心数据成本。 If this could easily be fixed, then I would love to have the improvements from avif.如果这可以轻松解决,那么我很乐意获得 avif 的改进。 I just want smaller file sizes and widespread browser support.我只想要更小的文件大小和广泛的浏览器支持。

Update更新

Okay, I found that I could get this to work if I changed from the default react bundler (which I believe to be webpack) to Parcel.好的,我发现如果我从默认的 react bundler(我认为是 webpack)更改为 Parcel,我可以让它工作。 Then it does work exactly as you expect... until I try to deploy the project.然后它确实按照您的预期工作......直到我尝试部署该项目。

There is an issue where I cannot load the service worker when i try to deploy my single page webapp to AWS as a single page web app.当我尝试将我的单页 Web 应用程序作为单页 Web 应用程序部署到 AWS 时,我无法加载 Service Worker。 There it makes a request to my url with avif-sw.js where there is not actually a js file.在那里,它使用 avif-sw.js 向我的 url 发出请求,其中实际上没有 js 文件。 I believe the issue is closely related to https://github.com/parcel-bundler/parcel/issues/670我相信这个问题与https://github.com/parcel-bundler/parcel/issues/670密切相关

So the first key is to use Parcel to build your web app.所以第一个关键是使用 Parcel 来构建你的 Web 应用程序。 But Parcel still does something wrong with deployment it seems.但是 Parcel 似乎在部署方面仍然有问题。 I will continue to investigate this in a few days.我将在几天内继续调查此事。

Here is the almost working version using parcel: https://github.com/quackack/quackack-comics/tree/parcel这是使用parcel的几乎可以工作的版本: https : //github.com/quackack/quackack-comics/tree/parcel

Update 2更新 2

My earlier update was incorrect.我之前的更新不正确。 I only thought it was working because of a cached service worker.我只是认为它是因为缓存的服务工作者而工作的。 My final solution is in the answer below.我的最终解决方案在下面的答案中。

It doesn't seem to be a problem now.现在似乎不是问题。 Simply convert your images to avif with tools like https://avif.io/ and use them as the image source or background source via typical CSS.只需使用https://avif.io/等工具将您的图像转换为 avif,并通过典型的 CSS 将它们用作图像源或背景源。 As Chrome and Firefox now support it (even though users still have to enable it on Firefox), everything goes well.由于 Chrome 和 Firefox 现在支持它(即使用户仍然必须在 Firefox 上启用它),一切都很顺利。 Even works on mobile now!现在甚至可以在手机上使用! :) :)

Okay, I finally got it working.好的,我终于让它工作了。 Unfortunately, mobile devices don't seem to be able to handle the large file sizes so I had to keep using jpeg anyway.不幸的是,移动设备似乎无法处理大文件,所以无论如何我不得不继续使用 jpeg。 It worked on my laptop though.不过它在我的笔记本电脑上工作。

Here is the commit that got everything to work: https://github.com/quackack/quackack-comics/commit/75e75307e688f0e515b4bbc9eb22eef290d2c209这是让一切正常工作的提交: https : //github.com/quackack/quackack-comics/commit/75e75307e688f0e515b4bbc9eb22eef290d2c209

What I had to do:我必须做的:

  1. Switch to Parcel.切换到包裹。
  2. Copy the contents of the avif.js library into source before building.在构建之前将 avif.js 库的内容复制到源代码中。 I used the command:我使用了命令:

     copyfiles -f node_modules/avif.js/*.js .
  3. Put this specifically into reg.js:将其专门放入 reg.js 中:

     require("avif.js").register("./avif-sw.js"); navigator.serviceWorker.register("./avif-sw.js", undefined);

What the last two steps do is trick parcel into actually keeping a copy of "avif-sw.js" around that can actually be loaded as a service worker.最后两步做的是欺骗包裹实际上保留一个“avif-sw.js”的副本,它实际上可以作为服务工作者加载。 Probably with a bit more tinkering you can get this to work without using parcel at all, just by copying local and then registering.可能需要更多的修改,您可以在不使用parcel的情况下使其工作,只需复制本地然后注册即可。 No requires required.不需要。 But I stopped investigating after I found this solution can't work on mobile.但是在我发现此解决方案无法在移动设备上运行后,我停止了调查。

This was exceptionally hard to debug because service workers are cached by the browser and I had to clear broswer data after every edit.这非常难以调试,因为 Service Worker 被浏览器缓存,每次编辑后我都必须清除浏览器数据。 It was also hard to debug because the source files are cached to so I had to delete my projects cache and build frequently too.调试也很困难,因为源文件被缓存到了,所以我不得不删除我的项目缓存并经常构建。

You might also want to use npm module "http-server-spa", or similar, to test how your built SPA will act when deployed.您可能还想使用 npm 模块“http-server-spa”或类似模块来测试您构建的 SPA 在部署时的行为方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM