取自 Artifact Austin: Leaving Pixels Behind - Todd Parker,哪些图片适合使用 SVG?
在网页中,图片通常在所有资源大小中占了最多比例,最简单的优化方式就是缩小图片,但事实上在各式各样的设备中,不同的网路速度、图片处理效能、萤幕特性等等也是必须考量的因素,本篇文章整理了在品质和速度的权衡下进行图片优化的各种手段。
使用 JPG、PNG 等等点阵图之前,请先考虑以下几点:
由於点阵图通常档案较大,且载入後会耗费较多浏览器效能和记忆体,有较大机率影响使用者体验,此时就需要进行更多优化手段。
若一定得使用图片,优先考量 SVG:
SVG 档本身也可以透过工具如 SVGO 降低档案大小。
优化图片最直接的方式就是压缩,压缩的方式主要分为两种:
图片适合的压缩方式要看网站的特性(是否接受失真、是否较关心档案大小),以下几点算是较为通用的部分:
除了 IE 之外,常见的浏览器都支援 WebP 图片格式,网页使用基本上是首选:
一款 Plugin based 图片压缩工具,可搭配 Webpack 使用,可依据想要压缩的图片格式和压缩方式安装插件、设定参数,来压缩专案中用到的图片。
使用 Webpack + url-loader
插件来打包图片资源,当图片大小在 limit
之内时会转为 DataURL(Base64) 直接放入引入图片的档案里面,因为请求资源时需要额外一次 Round trip,花费的时间会超过直接把图片内容 Inline 到档案内多出来的一点下载时间。
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|gif)$/i,
use: [
{
loader: 'url-loader',
options: {
limit: 8192,
},
},
],
},
],
},
};
说到动图首先想到的就是 GIF,不过 GIF 实在是非常大,不建议直接在网页中使用,可用 FFmpeg 等工具把 GIF 转成 MP4 或是 WebM(非常小,不需支援 IE 的首选)。
<video>
HTML 的 video
元素加上一些属性後就能做到:自动开始、循环、无声、避免全萤幕,和 GIF 没两样,只差在不能直接使用 img
元素。
<video autoplay loop muted playsinline>
<source src="my-animation.webm" type="video/webm">
<source src="my-animation.mp4" type="video/mp4">
</video>
利用
source
和type
让不支援 WebM 的浏览器使用 MP4。
在 img
加上一些属性让浏览器依据使用者萤幕大小自动判断最适合的图片,保持使用者体验的同时不浪费流量和效能,例如:
<img
src="flower-large.jpg"
srcset="flower-small.jpg 480w, flower-large.jpg 1080w"
sizes="(max-width: 600px) 480px, 50vw"
/>
srcset
标示图片名称和图片的实际大小。
sizes
可以设定 Media query,告诉浏览器此图的 CSS 宽度(实际 CSS 还是要自己设),浏览器会依据 sizes
和 DPR、DPI 来决定要读取 srcset
中的哪一张图片。
注意可以使用各种单位、calc
,但不能用 %。
实际测试:https://web.dev/codelab-specifying-multiple-slot-widths/
DPR 代表萤幕中显示一个 CSS pixel 所用的实际 Pixel 比例,例如 iPhone X 萤幕的 DPR 是 3,浏览器显示一个 CSS pixel 实际上是用了 3 * 3 = 9 个 Pixels。
DPI 代表每个每寸内的 Pixels 数量,由於 iPhone X 的 DPI 较高,每个 Pixel 靠得很近,如果 CSS 设定 10px 就真的只显示萤幕中的 10 个 Pixels 会让元素小到几乎看不到。
在此附上一个 Demo - Blur Canvas,当 Canvas 自身的宽度为 200,CSS 宽也设为 200px,在 DPR 为 2 的萤幕上显示时每个色点会放大 2 * 2 = 4 倍,看起来就会糊糊的,若把 Canvas 的宽度设为 400,以同样比例画图,再把 CSS 设为 200px,就能实际用上萤幕的所有 Pixels,显示清晰的图片。
src
当浏览器不支援 srcset
、sizes
时会 Fallback 到 src
,放在 src
的图片应该要能涵盖所有设备萤幕可用的大小。
即时转换、优化图片并进行快取,搭配 CDN 能够让图片传输速度更快,可用网址输入图片转换的参数,例如利用以下网址把图片转为 300 x 200 的大小:
https://<thumbor-server>/300x200/原始图片网址.png
有些图片不适合行动设备中使用,直接等比例缩小到手机宽度的话会让图片变得很丑,因此可以用到 Art direction 的技巧在不同萤幕宽度显示不同的图片。
在手机中显示剪裁过的图片
source
使用 picture
+ source
会回传第一个 Media query 是 true 的图片,否则 Fallback 到 img
,如果在 source
用了 Media query 就不需要 sizes
了。
<picture>
<source media="(max-width: 799px)" srcset="elva-480w-close-portrait.jpg">
<source media="(min-width: 800px)" srcset="elva-800w.jpg">
<img src="elva-800w.jpg" alt="Chris standing up holding his daughter Elva">
</picture>
实际测试:https://web.dev/codelab-art-direction/
浏览器的 HTML parser 还没解析完 JavaScript、CSS 就能开始下载图片,这也是为什麽需要 srcset
、sizes
等详细大小资讯。
通常会以 3 到 5 为准,以使用者体验和效能来说是越多越好,但需要更多 Server 储存空间和撰写更多 HTML。
sizes
?若能够设定多种 sizes
区间能够让使用者体验最好,更进一步还能根据网站使用者的萤幕宽度来决定,可参考 GA 搭配 https://screensiz.es/。
若真的只想使用一张图片,且图片是使用相对宽度,也必须确保该图片够大,刚好涵盖大部分的使用者萤幕宽度。
https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images#Art_direction
https://web.dev/fast/#optimize-your-images
>>: [DAY 28] 复刻 Rails - Routing 威力加强版 - 2
3D场景的基础 基础的要素:物体、光源、材质与摄影机 基础几何形状 平面 plane() 长方体 b...
如果在网页中输入了非预期的 URL,或是做出非预期的动作时,正常会出现 404 Not Found ...
本篇大纲:d3.line( )、d3.bisector( )、d3.defined( )、范例图表...
同样的例子。 假设这次我希望某些状态是依赖於某些状态的! 比如说有输入有效(valid)跟输入无效(...
本篇文章同步发布於个人部落格 (後续更新皆会以部落格为主):GitHub 操作介面介绍 上一篇文章我...