图片、字体与资源预加载

一、图片优化

图片压缩

常用压缩工具:

  • 智图压缩(免费、批量)
  • tinypng(免费、批量)
  • 使用 CDN 图片处理参数(如 ?w=400&q=75)实时裁剪

图片分割

单张图片建议不要超过 100KB。分割后通过布局拼接在一起,分割后的每张图片要设置 height,避免网速慢时样式塌陷。

图片懒加载

防止一次性加载过多图片导致请求阻塞,在长页面中只加载当前可视区域的图片。

方式一:getBoundingClientRect

1
<img data-src="real.jpg" class="lazy-image">
1
2
3
4
5
6
7
8
9
10
11
function inViewShow() {
const images = document.querySelectorAll('.lazy-image');
images.forEach(img => {
const rect = img.getBoundingClientRect();
if (rect.top < document.documentElement.clientHeight) {
img.src = img.dataset.src;
img.classList.remove('lazy-image');
}
});
}
document.addEventListener('scroll', throttle(inViewShow));

方式二:IntersectionObserver(推荐)

1
2
3
4
5
6
7
8
9
10
11
12
13
if ('IntersectionObserver' in window) {
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
img.classList.remove('lazy-image');
observer.unobserve(img);
}
});
});
document.querySelectorAll('.lazy-image').forEach(img => observer.observe(img));
}

二、字体优化(IconFont / WebFont)

WebFont

1
2
3
4
@font-face {
font-family: 'myFont';
src: url('myFont.ttf');
}

IconFont

使用字体图标替代图片,减少 HTTP 请求。常用平台:阿里妈妈 iconfont、Font-Awesome。

优点:可缩放矢量图形、单次 HTTP 请求加载多个图标、体积小、可应用 CSS 效果
不足:不支持复杂图像、通常只限单色、基于特定网格设计(如 16x16)

原理

IconFont 基于 @font-face。浏览器兼容写法:

1
2
3
4
5
6
7
8
9
10
@font-face {
font-family: 'defineName';
src: url('../fonts/custom-font.eot');
src: url('../fonts/custom-font.eot?#iefix') format('embedded-opentype'),
url('../fonts/custom-font.woff') format('woff'),
url('../fonts/custom-font.ttf') format('truetype'),
url('../fonts/custom-font.svg#defineName') format('svg');
font-weight: normal;
font-style: normal;
}

三、资源预加载

preload vs prefetch

  • preload:告知浏览器当前页面必定需要的资源,浏览器一定会加载
  • prefetch:告知浏览器页面可能需要的资源,浏览器空闲时加载
1
2
<link rel="preload" href="font.woff2" as="font" crossorigin>
<link rel="prefetch" href="/next-page.js" as="script">

使用方式

link 标签

1
<link rel="preload" href="/path/to/style.css" as="style">

HTTP 响应头

1
Link: <https://example.com/styles.css>; rel=preload; as=style

动态创建

1
2
3
4
5
const link = document.createElement('link');
link.rel = 'preload';
link.as = 'style';
link.href = '/path/to/style.css';
document.head.appendChild(link);

跨域字体 preload 注意事项

对字体进行 preload 时,必须加上 crossorigin 属性,否则浏览器会发起两次请求(一次 preload + 一次样式引入):

1
<link rel="preload" as="font" crossorigin href="https://cdn.example.com/font.woff2">

资源加载优先级

Chrome 中资源优先级分为五个级别:Highest、High、Medium、Low、Lowest。

  • HTML 主资源:Highest
  • CSS 样式:Highest
  • Script 脚本:<script> 最高,异步加载较低
  • Font 字体:样式文件中依赖的字体 Highest,preload 若不指定 crossorigin 则为 High

注意事项

  • 不要滥用 preload:只预加载当前页面必定使用的资源
  • 不要混用 preload 和 prefetch 加载同一资源:会导致重复加载
  • 对跨域资源 preload 必须添加 crossorigin 属性