Web/13-前端面试/02-性能优化/前端性能优化(一):静态资源优化.md
2021-01-14 17:05:23 +08:00

12 KiB
Raw Blame History

图片格式和应用场景

JPEG 格式

JPEGJoint Photographic Experts Group是一种针对彩色照片而广泛使用的有损压缩图形格式属于位图。

常用文件扩展名为.jpg,也有 .jpeg.jpe。JPEG 在互联网上常被应用于存储和传输照片。

  • 适合:颜色丰富的照片、彩色图大焦点图、通栏 banner 图;结构不规则的图形。

  • 不适合:线条图形和文字、图标图形,因为它的压缩算法不太这些类型的图形;并且不支持透明度。

PNG 格式

PNGPortable Network Graphics是一种无损压缩的位图图形格式支持索引、灰度、RGB 三种颜色方案以及 Alpha 通道等特性。

PNG 最初是作为替代 GIF 来设计的,能够显示 256 色,文件比 JPEG 或者 GIF 大,但是 PNG 非常好的保留了图像质量。支持 Alpha 通道的半透明和透明特性。最高支持 24 位彩色图像PNG-24和 8 位灰度图像PNG-8

  • 适合:纯色、透明、线条绘图,图标;边缘清晰、有大块相同颜色区域;需要带半透明的图片。

  • 适合:由于是无损存储,所以不太适合体积太大的彩色图像

比如说,如果你需要带透明背景的图片,此时就可以用 png 格式的图。

GIF 格式

GIFGraphics Interchange Format是一种位图图形格式以 8 位色(即 256 种颜色)重现真彩色的图像,采用 LZW 压缩算法进行编码。

支持 256 色仅支持完全透明和完全不透明如果需要带动画效果的图片GIF 是比较通用的选择。

  • 适合:动画,图标。

  • 不适合:每个像素只有 8 比特,不适合存储彩色图片。

Webp 格式

Webp 是一种现代图像格式,可为图像提供无损压缩和有损压缩,这使得它非常灵活。由 Google 在购买 On2 Technologies 后发展出来,以 BSD 授权条款发布。

Webp的优秀算法能同时保证图像质量和较小体积可以插入多帧实现动画效果可以设置透明度采用 8 位压缩算法。

无损的 Webp 比 PNG 小 26%,有损的 Webp 比 JPEG 小 25-34比 GIF 有更好的动画。

  • 适合:适用于图形和半透明图像。

总结

  • banner图、大图可以用 jpg、webp格式。

  • 图标、带透明背景的图,可以用 png 格式。

  • 带动画效果的图,可以用 gif 格式。

图片优化的常见方法

1、用工具压缩图片

压缩 PNG 图片

安装方法:

npm install node-pngquant-native

压缩 JPEG 图片

安装方法:

npm install g jpegtran

使用方法:

jpegtran -copy none -optimize -outfile output_file.jpg input_file.jpg

压缩 GIF 图

  • 工具Gifsicle

  • 官网(含安装方法):https://www.lcdf.org/gifsicle/

  • 介绍Gifsicle 通过改变每帧比例,减小 gif文件大小同时可以使用透明来达到更小的文件大小是目前公认的最好的解决方案。

使用方法:

# 压缩命令。注意这里是将压缩级别设置为3。如果将压缩级别设置为1或者2则基本不压缩。
gifsicle --optimize=3 -o out_file.gif in_file.gif

# 裁掉透明部分
gifsicle --optimize=3 --crop-transparency -o out_file.gif in_file.gif

2、将图片尺寸跟随网络环境进行变化

具体方案不同网络环境Wifi/4G/3G加载不同尺寸和像素的图片通过在图片 URL 中添加参数来改变。

图片 url 举例1图片的原始url链接

https://img12.360buyimg.com/img/s3866x3866_jfs/t1/149913/14/18648/719436/5fd8b9b5Eb697b825/7c23f3028aff8e2b.jpg

图片 url 举例2通过图片的url参数将这张图的尺寸设置为200px

https://img12.360buyimg.com/img/s200x200_jfs/t1/149913/14/18648/719436/5fd8b9b5Eb697b825/7c23f3028aff8e2b.jpg

3、响应式图片

方法1:通过 JavaScript 绑定事件,检测窗口大小,以此设置图片大小。

方法2CSS媒体查询。

代码举例:(在 640px的窗口大小里设置图片的尺寸为640px

@media screen and (max-width:640px) {
  my_image{
    width:640px;
   }
 }

方法3img标签的 srcset 属性。这个是 H5的新特性。

代码举例:

<img srcset="img-320w.jpg, img-640w.jpg 2x, img-960w.jpg 3x" src=“img-960w.jpg”
alt=“img”> x 描述符:表示图像的设备像素)

4、逐步加载图像lazyload、LQIP、LQIP

方法1、使用统一占位符。俗称图片的懒加载lazyload

方法2、使用 LQIP 的图片加载方式。也就是说,在大图没有完全加载出来的情况下,先这张图对应的的低质量图片进行占位。

LQIPLow Quality Image Placeholders低质量图像占位符。这种技术背后的想法是在网络环境较差的情况下你可以尽快向用户展示完全可用的网页为他们提供更好的体验。即使在更好的网络连接上这仍然为用户提供了更快的可用页面并且改善了体验。

代码举例:(将目标图片转换为 LQIP 形式的图)

const lqip = require('lqip');

//文件路径
const file = './in.png';

//将输入的图片转为base64
lqip.base64(file).then(res => {
    // 色值
    console.log(res);
});

lqip.palette(file).then(res => {
    //这里输出的是base64的图片地址
    console.log(res);
});

另外,我们还可以使用 SQIP 的图片加载方式。

SQIPSVG Quality Image Placeholders SVG 格式的图像占位符。

代码举例:(将目标图片转换为 SQIP 形式的图)

const sqip = require('sqip');

const result =  sqip({
    filename: './input_file.png',
    numberOfPrimitives: 10 //可根据不同应用场景设置大小
});

console.log(result.final_svg);

5、雪碧图Image spriting

雪碧图是比较常见的图片优化方式,也就是把多张小图合并成一张大图。这样的话,就只需做一次网络请求,减少图片的 http 请求次数。

读者们可以自行查阅。

6、有些场景下并不需要图片文件

有些场景下,并不需要图片,我们可以用其他的方式来代替图片。

举例:

  • Web Font 代替图片

  • 使用 Data URI 代替图片。base64就是属于 Data URI的方式。

7、在服务器端进行图片自动优化

图片服务器自动化优化是可以在图片 URL 链接上增加不同特殊参数,服务器自动化生成。通过这些参数,可以设置图片的不同格式、大小、质量。

常见处理方式

  • 图片裁剪:按长边、短边、填充、拉伸等缩放。

  • 图片格式转换:支持 JPGGIFPNGWebP 等,支持不同的图片压缩率。

  • 图片处理:添加图片水印、高斯模糊、重心处理、裁剪边框等。

  • AI 能力:鉴黄、涉政、智能抠图、智能排版、智能配色、智能合成等 AI 功能。

图片举例

比如JD公司的图片链接就会在服务器端做优化处理。通过修改图片链接中的参数就能自动达到相应的优化效果。

原始图片链接:

https://img12.360buyimg.com/img/s3866x3866_jfs/t1/149913/14/18648/719436/5fd8b9b5Eb697b825/7c23f3028aff8e2b.jpg

将图片压缩为 200*150

https://img12.360buyimg.com/img/s200x200_jfs/t1/149913/14/18648/719436/5fd8b9b5Eb697b825/7c23f3028aff8e2b.jpg

将图片转换为 webp 格式:

https://img12.360buyimg.com/img/s200x200_jfs/t1/149913/14/18648/719436/5fd8b9b5Eb697b825/7c23f3028aff8e2b.webp

将图片质量压缩至10%

https://img12.360buyimg.com/img/s3866x3866_jfs/t1/149913/14/18648/719436/5fd8b9b5Eb697b825/7c23f3028aff8e2b.jpg.q10

HTML优化

1、精简 HTML 代码

  • 减少 HTML 的嵌套。

  • 减少 DOM 节点数。

  • 减少无语义代码(比如:

    消除浮动其实可以用css来处理

  • 删除 http 或者 https如果URL的协议头和当前页面的协议头一致的或者此 URL 在多个协议头都是可用的,则可以考虑删除协议头。

  • 删除多余的空格、换行符、缩进和不必要的注释。

  • 省略冗余标签和属性。

  • 使用相对路径的 URL。

2、文件放在合适位置

  • CSS 样式文件链接尽量放在页面头部。

CSS 加载不会阻塞 DOM tree 解析,但是会阻塞 DOM Tree 渲染,也会阻塞后面 JS 执行。

任何 body 元素之前,可以确保在文档部分中解析了所有 CSS 样式(内联和外联),从而减少了浏览器必须重排文档的次数。

如果放置页面底部,就要等待最后一个 CSS 文件下载完成,此时会出现"白屏",影响用户体验。

  • JS 引用放在 HTML 底部

防止 JS 在加载、解析、执行时,阻塞了页面后续元素的正常渲染。

4、增强用户体验

  • 设置 favicon.ico

网站如果不设置 favicon.ico控制台会报错。另外页面加载过程中如果没有图标则会出现 loading 过程,也不利于记忆网站品牌,建议统一添加。

  • 增加首屏必要的 CSS 和 JS

页面如果需要等待所的依赖的 JS 和 CSS 加载完成才显示,则在渲染过程中页面会一直显示空白,影响用户体验,建议在首屏增加必要的 CSS 和 JS比如页面框架背景图片或者loading 图标,内联在 HTML 页面中。这样做,首屏能快速显示出来,缓解用户焦虑。现在很多网页在初始化的时候,流行做骨架屏,小伙伴们也可以研究下。

CSS优化

1、提升 CSS 渲染性能

  • 谨慎使用 expensive 属性,这类属性比较耗浏览器的性能。比如:nth-child 伪类;position: fixed 定位。

  • 尽量减少样式的层级数。

比如:div ul li span i {color: blue;}这样的层级就太深了。建议给 i 标签设置 class属性然后通过class直接设置样式属性可以提升浏览器的查询效率。

  • 尽量避免使用占用过多 CPU 和内存的属性。比如:text-indnt:-99999px

  • 尽量少使用耗电量大的属性。比如CSS3 3D transforms、CSS3 transitions、Opacity 这样的属性会消耗GPU。

2、合适使用 CSS 选择器

  • 尽量避免使用 CSS 表达式。

比如 background-color: expression( (new Date()).getHours()%2 ? "#FFF" : "#000" );这个属性的意思是,每间隔两小时,改变白景色。

  • 尽量避免使用通配选择器。

比如 body > a {font-weight:blod;}这样的属性,可能会把 body 里所有的标签遍历一遍,才找到 a 标签,比较耗时。

  • 尽量避免类正则的属性选择器:*= |= ^= $=

3、提升 CSS 文件加载性能

  • 使用外链的 CSS。

我们知道,内联的 css 是在html 内部写的。相比之下,外链的 CSS文件是放在CDN上的可以缓存既能减少 html 页面的体积大小,也能利用缓存减少资源的请求。

  • 尽量避免使用 @import 方法

整个CSS加载完成后浏览器会把 import 中所有依赖的文件全部加载完成后浏览器才会接着往下渲染。这个过程会阻塞CSS文件的加载过程。

4、精简 CSS 代码

  • 使用缩写语句

  • 删除不必要的零。比如 0.2 可以写成 .2

  • 删除不必要的单位,比如 0px 可以写成 0

  • 删除过多的空格;注释言简意赅

  • 尽量减少样式表的大小

当然,很多地方可以在编译时,通过压缩工具来处理;但是我们在写代码时,也应该有良好的编码习惯。

5、合理使用 Web Fonts

  • 将字体文件部署在 CDN 上。

  • 或者将字体以 base64 形式保存在 CSS 中并通过 localStorage 进行缓存

  • Google 字体库因为某些不可抗拒原因,应该使用国内托管服务

6、CSS 动画优化

  • 尽量避免同时出现过多动画。

  • 延迟动画初始化让其他的重要的CSS样式优先渲染。

  • 结合 SVG。