azl397985856 / fe-interview

宇宙最强的前端面试指南 (https://lucifer.ren/fe-interview)
Apache License 2.0
2.84k stars 260 forks source link

【每日一题】- 2019-12-11 - 如何让不支持webp的浏览器支持webp #81

Closed azl397985856 closed 4 years ago

azl397985856 commented 4 years ago

一些浏览器是不支持webp的,我们能不能想办法让这些浏览器支持呢?

image

feikerwu commented 4 years ago

想了一天,简单答下,不保证正确😐

  1. 浏览器能力检测,考虑写个webpack插件或者vue指令,如果浏览器支持webp,自动将png/jpg/gif图改为webp(需要cdn或者backend支持,一套图需要同时支持webp)

  2. 服务端支持,支持webp的浏览器在发送图片请求的时候,会在requests header上Accept上添加image/webp, nginx可以通过$http_accept来判断是否有webp,有则返回webp资源,否则返回正常图片资源

  3. 如果是在原生的webview里,前端可以什么都不做,直接用webp的资源,让ios客户端在webview拦截请求,替换webp请求为png/jpg请求

  4. 结合1,3,前端也可以直接通过service-worker拦截图片请求,根据浏览webp支持请求替换图片请求(不过service-worker自己兼容是个问题,ios到11.2,安卓4.4)

  5. 通过picture,通过排列webp和png的资源顺序,不支持webp自动向下兼容使用兜底png

  6. 前端通过js去转码,把png转成webp (有点蠢,不过把这个计算放到worker里做好像也算可以)

halu886 commented 4 years ago

楼上的老哥说的非常详细了 尝试补充一点

  1. 在img标签中添加onerror事件,当不支持webp格式时,在errorHandler中进行软解成base64格式,或者重试请求
azl397985856 commented 4 years ago

你们回答的很全面。 但是不是我想问的。

我澄清一点, 我的意思是如何在“不支持webp的浏览器,解析webp的图片,然后渲染到页面,不是退化到png等图片”

azl397985856 commented 4 years ago

可以考虑用c++或者其他语言写一个解析器,然后转化为wasm。 我们可以用胶水代码来和它进行交互。 关于WebAssembly 这里有一篇实践文章,我在《每日一荐》也推荐过。

WebAssembly 兼容性: image

如果你仔细观察web配合WebAssembly的兼容表会发现,其实WebAssembly支持的webp不一定支持,反之亦然。因此这种方案可行的情况只有“不支持webp但是支持WebAssembly的浏览器,比如safari”。 这恰好也是大家选择使用这种方法的原因。