0%

优化4.资源优化

资源的压缩与合并

为什么要压缩合并

  • 减少 HTTP 请求数量
  • 减少请求资源大小

HTML 压缩:

CSS 压缩:

  • 使用在线工具进行压缩
  • 使用 clean-css 等 npm 工具

JS 压缩与混淆

  • 使用在线工具进行压缩
  • 使用 Webpack 对 JS 在构建时压缩

CSS JS 文件合并:

  • 比如有 20 个 CSS,合并成一个 CSS 可能会比 20 个分别加载要快,因为每个资源请求都要经历不同的阶段:进行 DNS 查找、TCP 链接建立(这两个可以复用),TTFB 这个没办法避免,20 个肯定会比 1 个稍微大写,但是合并的话维护带来麻烦

图片格式优化

图片格式比较

JPEG/JPG:

image-min

imahe-min playground

优点:

  • 压缩比很高,画质还可以很好的保存,色彩保留也很丰富。JPG 通常采用 24 位存储方式,2^24 大约是 1万6千种颜色

使用场景:

  • 需要展示比较大的图片时,还想保留画质和色彩

缺陷:

  • 如果图片比较强调纹理或边缘,JPG 会显得有锯齿感或模糊,比如:Logo 不会用 JPG,边缘会显得粗糙

PNG:

imagemin-pngquant

优点:

  • 可以做透明背景的图片,PNG也有 24 位格式,色彩丰富程度也是没问题
  • 通常 quality 设置在 65% ~ 80% 之间是比较好的,这样可以达到 80% 的压缩比率

使用场景:

  • 想强调线条、纹理、边缘这些细腻程度时

缺陷:

  • 因为保留了细节,所以体积相对会大些

WebP:

优点:

  • Google 新提出的图片格式,已经推了几年,普及程度不是很高,跟 PNG有相同的质量,但是压缩比率比 PNG 要高

图片加载优化

img-loading-lazy

  • 原生的图片懒加载方案

    1
    <img loading="lazy" src="https://placekitten.com/400/400">
  • 第三方图片懒加载方案

    vanilla-lazyload :用于延迟加载图片、背景图像、视频、iframe 和脚本。它利用 Intersection Observer,支持响应式图像

    yall.js:使用 Intersection Observer 并回退到事件处理程序的库

    lozad.js:使用 Intersection Observer 的轻量级选项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { LazyLoadImage } from 'react-lazy-load-image-component'

class MyCard extends React.Component {
render() {
return (
<LazyLoadImage
className={this.props.classes.media}
src={this.props.image}
effect="blur"
rel="preconnect"
/>
)
}
}

渐进式图片

图片不是一步到位加载出来,而是逐渐变清楚,最后变成非常清楚

  • 基线 JPEG,自上而下的行扫描形式
  • 渐进式 JPEG,会从低像素到高像素的过程

渐进式图片的优点和不足:

渐进式图片的解决方案:

响应式图片

响应式图片 MDN

不同屏幕尺寸都有一张合适的图片给用户达到最佳视觉体验,如何做?肯定不希望用一张超大的图加载到所有设备上,然后再根据屏幕尺寸去进行缩放,这样会造成浪费,而且在手机端网络情况可能不太好

  • Srcset 属性的使用

    srcset 定义浏览器选择的图像集,以及每个图像的大小

  • Sizes 属性的使用

    sizes 定义了一组媒体条件并且指明当某些媒体条件为真是,什么样的图片尺寸是最佳选择

  • picture 的使用

1
2
<img srcset="elva-fairy-480w.jpg 480w, elva-fairy-800w.jpg 800w"
sizes="(max-width: 600px) 480px, 800px" src="elva-fairy-800w.jpg" alt="">

字体优化

网页上的大部分内容以文字的形式展示给用户,为了让文字展示更漂亮,很多时候会使用自定义字体,这些字体资源就会通过网络加载到客户端

什么是 FOIT 和 FOUT

字体未下载完成时,浏览器隐藏或自动降级,导致字体闪烁

  • Flash Of Invisible Text

    文字从看不到到看到的闪烁变化过程

  • Flash Of Unstyled Text

    没有经过样式渲染,也就是文字开始看上去是一种样式,后来经过样式渲染又变成另外一种样式没这中间会有这个变化和闪动的过程

使用 font-display

这个属性有 5 个值:

  • auto

  • block

    开始不让文字进行显示,3s 之后字体下载完再用你的字体,3s 之后字体还没下载完,先用默认字体显示,直到字体下载完再换成你的字体

  • swap

    开始就使用默认字体进行显示,直到字体下载完成之后再换成你的字体,用户一开始就可以很快看到字体,不会看到白屏

  • fallback

    对 block 的优化,开始不显示的等待时间缩短了,只有 100ms

  • optional

    为手机端进行优化,浏览器可以判断用户网络情况,如果速度比较好,那 100ms 就用你下载的字体,如果下载不下来,就用默认字体进行显示

1
2
3
4
5
6
7
8
9
10
11
@import url(https://fonts.googleapis.com/css?family=Long+Cang);

@font-face {
font-family: 'Amatic SC';
font-style: normal;
font-weight: 400;
src: url('../fonts/amatic-sc-v11-latin-regular.eot'); /* IE9 Compat Modes */
src: local('Amatic SC Regular'), local('AmaticSC-Regular');
font-display: block;
unicode-range: U+00-FF;
}
  • font-family:字体名称
  • src:字体从哪加载,可以通过本地加载字体也可以来自 url
  • unicode-range:可以做个拆分,本来字符集非常大,比如中文汉字很多,如果把所有字体全放在一个文件里,字体文件就过大了。只有字体真正要用到的时候才会去下载这个字体,可以提高字体加载效率

使用 Ajax + Base64

  • 使用 Base64 把字体进行转码或嵌到 CSS 里或 JS 里,再进行加载,转码之后通过异步请求的方式去获取这个字体
  • 缺点:因为你把 Base64 嵌到其他资源里,导致文字就没有办法进行缓存,它的缓存实际就依赖于 CSS 的缓存