Web Optimize(Web 优化)

前端性能优化——原理与实践

前置知识:HTML\CSS\JS\Vue

涉及内容:

前端性能优化原理:

目录(Contents)

1. 基础优化

Web 请求示意图

HTTP请求的过程及潜在的性能优化点:

1.1 资源的合并与压缩-HTTP请求的过程及潜在的性能优化点

node-minify:官网 Github

HTTP请求的过程性能优化的原则:

1.1.1 HTML 压缩

HTML 代码压缩:压缩这些在文本文件中有意义,但是在 HTML 中不显示的字符,包括空格制表符换行符等,还有一些有意义的字符,如 HTML注视 也可以被压缩。

HTML 压缩方法:

1.1.2 CSS 压缩

CSS 压缩:对无效代码压缩,进行 CSS 语义合并。

CSS 压缩方法:

1.1.3 JS 压缩和混乱

JS 压缩和混乱:是对 JS 中的无效字符进行删除、删除注视、代码语义的缩减与优化、代码保护。

JS 压缩和混乱方法:

1.1.4 文件合并

不进行文件合并的缺点:

文件合并的缺点:

文件合并的原则:

文件合并的方法:

1.1.5 开启 gzip

1.2 图片压缩

图片压缩:针对真实图片情况,舍弃一些相对无关紧要的色彩信息。

tinypng - 图片压缩 | 智图 - 图片格式转换 | spritecow - 雪碧图制作

png8/png24/png32 之间的区别:

不同格式图片的区别:

图片压缩方法:

2. 进阶优化

2.1 CSS、JS 的加载与执行

HTML 页面加载渲染的过程

HTML 渲染过程的特点:

2.2 懒加载和预加载

懒加载和预加载 - 掘金 懒加载和预加载 - 简书

懒加载:在所需资源(多为图片)进入可视区域后再请求资源,可减少无效资源的加载,避免并发请求资源过多导致的阻塞问题。适用于图片较多、页面较长的业务场景。

懒加载库:jquery_lazyload

Javascript图片预加载详解

<!-- 前台需要懒加载的图片标签(一定要有 height属性) -->
<img src='' class='image-item' lazyload='true' data-original='图片的URL地址' height='10px' />
// 可视区域的高度
var viewHeight = document.documentElement.clientHeight;

// 懒加载方法
function lazyLoad() {
    var eles = document.querySelectorAll('img[data-original][lazyload]');
    Array.prototype.forEach.call(eles, function(item, index) {
        var rect;
        if( item.dataset.original === '' )
            return;
        rect = item.getBoundimgClientRect();

        if( rect.bottom >= 0 && rect.top < viewHeight ) {
            !function() {
                var img = new Image();
                mg.src = item.dataset.original;
                img.onload = function() {
                    item.src = img.src;
                }
                item.removeAttribute('data-original');
                item.removeAttribute('lazyload')
            }
        }
    })
}

lazyLoad();// 加载时先调用一次,显示第一屏的图片
document.addElementListener('scroll', lazyload);

预加载:对图片等静态资源使用之前提前请求,资源使用时可从缓存中加载,提升用户体验。

预加载库:preloadjs

2.3 重绘与回流

频繁触发重绘与回流,会导致 UI 频繁渲染,从而导致 JS 变慢,这就是 CSS 性能让 JavaScript 变慢的原因。

回流:当 render-tree 中的一部分(或全部)因为元素的规模尺寸、布局、显示隐藏等改变而需要重新构建时称为回流。当页面布局和几何属性发生变化时就需要回流。

重绘:当 render-tree 中的元素需要更新属性,而这些属性只是影响元素的外观、风格,而不影响布局时称为重绘。

回流必将引起重绘,重绘不一定会引起回流。

触发页面重布局的属性:

盒子模型相关属性 定位属性及浮动 改变节点内部文字结构的属性
width / height top / bottom / left / right text-align
padding / margin position overflow / overflow-y
display float font 相关属性
border 相关属性 clear line-height
min-height   vertical-align
    white-space

将频繁重绘和回流的 DOM 元素单独作为一个独立图层,那么这个 DOM 元素的重绘和回流的影响只会在这个图层1.

创建图层的条件:

  1. 3D 或透视变换(perspective transform)CSS 属性
  2. 使用加速视频解码的 <video> 节点
  3. 拥有 3D(WebGL)上下文或加速的 2D 上下文的 <canvas> 节点
  4. 混合插件(如 flash)
  5. 对自己的 opacity 做 CSS 动画或使用一个动画 webkit 变换的元素
  6. 拥有加速 CSS 过滤器的元素
  7. 元素有一个包含复合层的后代节点(一个元素拥有一个子元素,该子元素在自己的层里)
  8. 元素有一个 z-index 较低且包含一个复合层的兄弟元素

减少重绘与回流的优化点:

  1. 用 translate 替代 top
  2. 用 opacity 替代 visibility
  3. 不要频繁的修改元素的单个样式,使用 className 整体修改
  4. 把 DOM 离线后修改(如先把 DOM 隐藏(display=none,一次 Reflow)然后修改,完成后再显示)
  5. 不要把 DOM 节点的属性值放在一个循环里当成循环的变量
  6. 不要使用 table 布局(一个很小的改动会造成整个 table 的重新布局)
  7. 动画实现的速度的选择
  8. 对于动画新建图层(添加 will-change=transform 或 transform=translateZ(0) 属性)
  9. 启用 GPU 硬件加速(使用 transform=translateZ(0)和 transform=translate3d(0, 0, 0) 就可以开启 GPU 加速)

2.4 浏览器存储

2.4.1 Cookies

cookies 会造成同一域名下 cdn 的流量损耗。解决办法:cdn 的域名与主站域名分开,这样在请求 cdn 静态文件时就不会发送 cookie。

有关 Cookies 的更详细的信息可查看我的另外一个库: https://github.com/ChanMenglin/WebSecurity#3-前端-cookies-安全性 (这个仓库以 Web 安全为主,但较详细的介绍了 Cookies)

cookie 操作

// cookie 操作

// 写入 cookie
document.cookie = 'token=token'

// 读取 cookie
document.cookie // token=token

一个完整支持unicode的cookie读取写入器

前端 cookies 安全性

2.4.2 localStorage

localStorage 操作

// localStorage 操作

// 由于兼容性问题,需要在使用 localStorage 前做一个判断
if (window.localStorage) {
    // 写入 localStorage
    localStorage.setItem('userName', 'jack');

    // 读取 localStorage
    localStorage.getItem('userName')
}

2.4.3 sessionStorage

// sessionStorage 操作

// 由于兼容性问题,需要在使用 sessionStorage 前做一个判断
if (window.sessionStorage) {
    // 写入 sessionStorage
    sessionStorage.setItem('userName', 'jack');

    // 读取 sessionStorage
    sessionStorage.getItem('userName')
}

2.4.4 IndexedDB

使用 IndexedDB

2.4.5 service worker

chrome 中查看 service worker:

  1. chrome://serviceworker-internals/
  2. chrome://version/#inspect/#service-workers

service worker - 离线应用 | service worker - 消息推送

2.5 浏览器缓存

2.5.1 HTTP Headers

2.5.1.1 缓存策略控制 - cache-control
2.5.1.2 设置缓存过期时间 - Expires
2.5.1.3 基于客户端和服务端协商的缓存机制 - Last-modified and If-Modified-Since

last-modified 的问题

2.5.1.4 基于文件 hash 值校验的缓存机制 - Etag and If-None-Match

成功避免 last-modified 的问题,并将校验精度提高到毫秒级

2.5.2 多级缓存策略

多级缓存策略

多级缓存策略 - 流程图 PDF

多级缓存策略 - 流程图

多级缓存策略 - cache-control生效情况 PDF

多级缓存策略 - cache-control生效情况

3. 综合服务端的优化