在一些多图应用场景(电商、活动等)中,会存在图片没有压缩,导致加载变慢的场景。
同时在lighthouse跑分中,如果图片尺寸没有与承载容器尺寸相匹配也会影响到页面的加载速度和分数。
当后端无法精细化处理的时候,就需要前端针对当前场景进行处理了。
以下对阿里云oss、七牛、京东的图片来源地址进行了处理
来源 | 处理方式 | 案例(原链接|调整后链接) | 备注 |
---|---|---|---|
京东 | 尺寸: jfs → s220x220_jfs 更改图片质量:!q74.dpg |
https://img11.360buyimg.com/sku/jfs/t11383/145/2869635527/732077/6eef8592/5cda2c95Nf943ef20.jpg https://img11.360buyimg.com/sku/s360x360_jfs/t11383/145/2869635527/732077/6eef8592/5cda2c95Nf943ef20.jpg!q75.dpg |
偶现,部分图片跳帧·处理后,会请求不到京东图片比较特殊 |
七牛 | 尺寸: /thumbnail/220x220 质量:/quality/75 渐进显示:/interlace/1 格式:format/jpg |
https://demo.qiniu.com/FpeyGLFzQ2MLTy0_uf1Fh64Pz7ZE https://demo.qiniu.com/FpeyGLFzQ2MLTy0_uf1Fh64Pz7ZE?imageMogr2/thumbnail/220x220/quality/75/interlace/1 |
七牛文档七牛通过imageMogr2可直接调整图片渐进显示只支持jpg |
腾讯云 | 尺寸: /thumbnail/220x220 质量:/quality/75 渐进显示:/interlace/1 格式:format/jpg |
https://demo.tencent.net/error.ac4119ee.png https://demo.tencent.net/error.ac4119ee.png?imageMogr2/thumbnail/220x220/quality/75/interlace/1 |
腾讯云文档 |
综合以上,可实现以下vue指令和函数。以下为主要的代码实现
目前代码已上传至CSDN,可直接下载
export const imgMogr = function(url, option = {}) {
const cdnType = getCdnType(url);
url = replaceProtocol(url);
if (!cdnType) return url;
let { w, h, f } = option;
if (w) {
w = w * 2;
}
if (h) {
h = h * 2;
}
if (canUseWebp()) f = 'webp';
const sizeBoth = w && h;
const sizeMaybe = w || h;
return {
ali() {
return [
url,
'?x-oss-process=image/quality,q_70/interlace,1',
f ? `/format,${f}` : '',
sizeMaybe
? `/resize,${w ? 'w_' + w : ''}${sizeBoth ? ',' : ''}${h ? 'h_' + h : ''},m_fixed`
: ''
].join('');
},
qiniu() {
return [
url,
'?imageMogr2/quality/70/interlace/1',
f ? `/format/${f}` : '',
sizeMaybe
? `/thumbnail/${w || ''}${sizeBoth ? 'x' : ''}${h || ''}${sizeBoth ? '!' : ''}`
: ''
].join('');
},
jd() {
return [
w && h ? url.replace('jfs', `s${w}x${h}_jfs`) : url,
'!q70.dpg',
f === 'webp' ? '.webp' : ''
].join('');
}
}[cdnType]();
};
Promise
imgMogr ⇒ *
imgMogrDirective
imgMogrVue
string
getCdnType(url, checkProceed) ⇒ string
| boolean
canUseWebp() ⇒ boolean
handleTagType(el, binding, vnode, reset)
Promise
Kind: global constant
Returns: Promise
- Promise
Description:: 检测是否支持 webp
Example::
checkWebp() => Promise
Example::
checkWebp().then(res => console.log(res)) => true
*
Kind: global constant
Returns: *
- 压缩后的图片地址
Description:: 图片压缩,
数组 join 拼接 [url,基础压缩,格式转换,尺寸压缩].join(‘’)
京东的特殊
Example::
imgMogr('' , {w: 100, h: 100, f: 'webp'}) => ''
Param | Type | Description |
---|---|---|
url | * |
图片地址 |
option | * |
压缩参数 |
Kind: global constant
Description:: 图片处理指令
Example::
<img v-imogr="{w: 100, h: 100, f: 'webp'}" src="https://www.xxxx.com/xxx.jpg" />
Param | Type | Description |
---|---|---|
el | * |
指令所绑定的元素,可以用来直接操作 DOM |
binding | * |
指令的绑定对象 |
vnode | * |
Vue 编译生成的虚拟节点 |
Kind: global constant
Description:: 图片处理指令
Example::
<img v-imogr="{w: 100, h: 100, f: 'webp'}" src="https://www.xxxx.com/xxx.jpg" />
Example::
this.$imogr('' , {w: 100, h: 100, f: 'webp'}) => ''
Example::
<img src="'https://www.xxxx.com/xxx.jpg' | imgMogr" />
Param | Type | Description |
---|---|---|
el | * |
指令所绑定的元素,可以用来直接操作 DOM |
binding | * |
指令的绑定对象 |
vnode | * |
Vue 编译生成的虚拟节点 |
string
Kind: global function
Description:: 替换 http 为 https
Example::
replaceProtocol('' ) => ''
Param | Type |
---|---|
str | string |
string
| boolean
Kind: global function
Returns: string
| boolean
- cdn 类型
Description:: 通过 url 检测 cdn 类型, 已处理的会返回 false
Example::
getCdnType('' ) => 'ali'
Param | Type | Default | Description |
---|---|---|---|
url | string |
图片地址 | |
checkProceed | boolean |
true |
是否检测已处理过的 |
boolean
Kind: global function
Returns: boolean
- 是否支持 webp
Description:: 从本地存储中获取是否支持 webp
Example::
canUseWebp() => true
Kind: global function
Description:: 处理标签类型
Param | Type | Description |
---|---|---|
el | * |
指令所绑定的元素,可以用来直接操作 DOM |
binding | * |
指令的绑定对象 |
vnode | * |
Vue 编译生成的虚拟节点 |
reset | * |
是否重置 |