Skip to content

19.静态文件优化方案有哪些?

1.图片优化

图片格式:

  • jpg:适合色彩丰富的照片、banner 图;不适合图形文字、图标(纹理边缘有锯齿),不支持透明度
  • png:适合纯色、透明、图标,支持半透明;不适合色彩丰富图片,因为无损存储会导致存储体积大
  • gif:适合动画,可以动的图标;不支持半透明,不适和存储彩色图片
  • webp:适合半透明图片,可以保证图片质量和较小的体积
  • svg 格式图片:相比于 jpg 和 jpg 它的体积更小,渲染成本过高,适合小且色彩单一的图标;

图片优化:

  • 避免空 src 的图片

  • 减小图片尺寸,节约用户流量

  • img 标签设置 alt 属性, 提升图片加载失败时的用户体验

  • 原生的 loading:lazy 图片懒加载

    html
    <img loading="lazy" src="./images/1.jpg" width="300" height="450" />
    <img loading="lazy" src="./images/1.jpg" width="300" height="450" />
  • 不同环境下,加载不同尺寸和像素的图片

    html
    <img
      src="./images/1.jpg"
      sizes="(max-width:500px) 100px,(max-width:600px) 200px"
      srcset="./images/1.jpg 100w, ./images/3.jpg 200w"
    />
    <img
      src="./images/1.jpg"
      sizes="(max-width:500px) 100px,(max-width:600px) 200px"
      srcset="./images/1.jpg 100w, ./images/3.jpg 200w"
    />
  • 对于较大的图片可以考虑采用渐进式图片(骨架屏)

  • 采用 base64URL 减少图片请求

  • 采用雪碧图合并图标图片等

2.HTML 优化

  • 语义化 HTML:代码简洁清晰,利于搜索引擎,便于团队开发
  • 提前声明字符编码,让浏览器快速确定如何渲染网页内容
  • 减少 HTML 嵌套关系、减少 DOM 节点数量
  • 删除多余空格、空行、注释、及无用的属性等
  • HTML 减少 iframes 使用 (iframe 会阻塞 onload 事件可以动态加载 iframe)
  • 避免使用 table 布局

3.CSS 优化

  • 减少伪类选择器、减少样式层数、减少使用通配符
  • 避免使用 CSS 表达式,CSS 表达式会频繁求值, 当滚动页面,或者移动鼠标时都会重新计算 (IE6,7)
    css
    background-color: expression((new Date()) .getHours() %2 ? "red": "yellow");
    background-color: expression((new Date()) .getHours() %2 ? "red": "yellow");
  • 删除空行、注释、减少无意义的单位、css 进行压缩
  • 使用外链 css,可以对 CSS 进行缓存
  • 添加媒体字段,只加载有效的 css 文件
    html
    <link
      href="index.css"
      rel="stylesheet"
      media="screen and (min-width:1024px)"
    />
    <link
      href="index.css"
      rel="stylesheet"
      media="screen and (min-width:1024px)"
    />
  • CSS contain 属性,将元素进行隔离
  • 减少@import 使用,由于@import 采用的是串行加载

4.JS 优化

  • 通过 async、defer 异步加载文件 async-defer

  • 减少DOM操作,缓存访问过的元素

  • 操作不直接应用到DOM上,而应用到虚拟DOM上。最后一次性的应用到DOM上。

  • 使用webworker解决程序阻塞问题

  • IntersectionObserver

    js
    const observer = new IntersectionObserver(function(changes) { 
        changes.forEach(function(element, index) {
            if (element.intersectionRatio > 0) {
                observer.unobserve(element.target);
                element.target.src = element.target.dataset.src;
            }
        });
    });
    function initObserver() {
        const listItems = document.querySelectorAll('img');
        listItems.forEach(function(item) {
            observer.observe(item);
        });
    }
    initObserver();
    const observer = new IntersectionObserver(function(changes) { 
        changes.forEach(function(element, index) {
            if (element.intersectionRatio > 0) {
                observer.unobserve(element.target);
                element.target.src = element.target.dataset.src;
            }
        });
    });
    function initObserver() {
        const listItems = document.querySelectorAll('img');
        listItems.forEach(function(item) {
            observer.observe(item);
        });
    }
    initObserver();
  • 虚拟滚动 vertual-scroll-list

  • requestAnimationFramerequestIdleCallback

  • 尽量避免使用eval, 消耗时间久

  • 使用事件委托,减少事件绑定个数。

  • 尽量使用canvas动画、CSS动画

5.字体优化

css
@font-face {
    font-family: "Bmy";
    src: url("./HelloQuincy.ttf");
    font-display: block;
    /* block 3s 内不显示, 如果没加载完毕用默认的   */
    /* swap 显示老字体 在替换 */
    /* fallback 缩短不显示时间, 如果没加载完毕用默认的 ,和block类似*/
    /* optional 替换可能用字体 可能不替换*/
}
body {
    font-family: "Bmy"
}
@font-face {
    font-family: "Bmy";
    src: url("./HelloQuincy.ttf");
    font-display: block;
    /* block 3s 内不显示, 如果没加载完毕用默认的   */
    /* swap 显示老字体 在替换 */
    /* fallback 缩短不显示时间, 如果没加载完毕用默认的 ,和block类似*/
    /* optional 替换可能用字体 可能不替换*/
}
body {
    font-family: "Bmy"
}
  • FOUT(Flash Of Unstyled Text) 等待一段时间,如果没加载完成,先显示默认。加载后再进行切换。

  • FOIT(Flash Of Invisible Text)字体加载完毕后显示,加载超时降级系统字体 (白屏)

Released under the MIT License.