2

性能优化

1.让资源加载更快

减小资源体积

压缩代码

减少访问次数

资源合并、SSR服务器渲染、浏览器缓存
资源合并**
<script src="a.js"></script>
<script src="b.js"></script>
<script src="c.js"></script>
//合并
<script src="abc.js"></script>
SSR服务器渲染

服务器把需要的组件或页面渲染成 HTML 字符串,然后把它返回给客户端。

浏览器缓存

浏览器缓存其实就是浏览器保存通过HTTP获取的所有资源,是浏览器将网络资源存储在本地的一种行为。
浏览器缓存的分类

  1. 强缓存,2. 协商缓存
  • 强缓存

浏览器在加载资源时,会先根据本地缓存资源的 header 中的信息判断是否命中强缓存,如果命中则直接使用缓存中的资源不会再向服务器发送请求。header 中的信息指的是 expirescahe-control
Expires:绝对时间。这个时间代表着这个资源的失效时间,在此时间之前,即命中缓存。这种方式有一个明显的缺点,由于失效时间是一个绝对时间,所以当服务器与客户端时间偏差较大时,就会导致缓存混乱。
Cache-Control:相对时间
。Cache-Control:max-age=3600,代表着资源的有效期是 3600 秒。
Cache-Control 与 Expires 可以在服务端配置同时启用,同时启用的时候 Cache-Control 优先级高。

  • 协商缓存

当强缓存没有命中的时候,浏览器会发送一个请求到服务器,服务器根据 header 中的部分信息来判断是否命中缓存。如果命中,则返回 304 ,告诉浏览器资源未更新,可使用本地的缓存。
这里的 header 中的信息指的是 Last-Modify/If-Modify-SinceETag/If-None-Match
Last-Modify/If-Modify-Since:Last-modify :浏览器第一次请求资源的时候,服务器返回的 header 中会加上 Last-Modify,标识该资源最后修改的时间。当浏览器再次请求该资源时,request 的请求头中会包含 If-Modify-Since。该值为之前返回的 Last-Modify。服务器收到 If-Modify-Since 后,根据资源的最后修改时间判断是否命中缓存。如果命中缓存,则返回 304,并且不会返回资源内容,并且不会返回 Last-Modify。
ETag/If-None-Match:返回的是一个校验码。ETag 可以保证每一个资源是唯一的,资源变化都会导致 ETag 变化。服务器根据浏览器上送的 If-None-Match 值来判断是否命中缓存。
Last-Modified 不一样的是,当服务器返回 304 Not Modified 的响应时,由于 ETag 重新生成过,response header 中还会把这个 ETag 返回,即使这个 ETag 跟之前的没有变化。
Last-Modified 与 ETag 是可以一起使用的,服务器会优先验证 ETag,一致的情况下,才会继续比对 Last-Modified,最后才决定是否返回 304。
总结
当浏览器再次访问一个已经访问过的资源时,它会这样做:

  1. 看看是否命中强缓存,如果命中,就直接使用缓存了。
  2. 如果没有命中强缓存,就发请求到服务器检查是否命中协商缓存。
  3. 如果命中协商缓存,服务器会返回 304 告诉浏览器使用本地缓存。
  4. 否则,返回最新的资源。

参考文章:https://segmentfault.com/a/11...

使用更快的网络

CDN全称内容分发网络。用户在浏览网站的时候,CDN会选择一个离用户最近的CDN边缘节点来响应用户的请求。
当浏览器向CDN节点请求数据时,CDN节点会判断缓存数据是否过期,若缓存数据并没有过期,则直接将缓存数据返回给客户端;否则,CDN节点就会向服务器发出回源请求,从服务器拉取最新数据,更新本地缓存,并将最新数据返回给客户端。 CDN服务商一般会提供基于文件后缀、目录多个维度来指定CDN缓存时间,为用户提供更精细化的缓存管理。

使用DNS预解析

//强制打开a 标签的dns 预解析
<meta http-equiv="x-dns-prefetch-control" content="on">
<link rel="dns-prefetch" href-="/host name_ to_ prefetch.com">

在一些浏览器中页面中的a标签默认打开了DNS预解析,但是页面协议是以https开头,很多浏览器默认关闭DNS预解析,通过第一句强制打开a标签的预解析。

2.让页面渲染更快

3.节流和防抖

防抖(debounce)

函数防抖: 指触发事件后在规定时间内函数只能执行一次,如果在规定时间内又触发了事件,则会重新计算函数执行时间。
场景:监听一个输入框,文字变化后触发 change 事件,直接用keyup事件,则会频繁触发change 事件。使用防抖:用户输入结束或暂停时,才会触发change 事件

debounce.js
let input = document.getElementById("the_input");

//自定义防抖函数
function debounce(fn, delay = 100) {
    let timer = null;
    return function () {
        if (timer) {
            clearTimeout(timer);
        }
        timer = setTimeout(() => {
            fn.apply(this, arguments);
            timer = null;
        }, delay);
    }
}

input.addEventListener("keyup", debounce(function (e) {
    console.log(e.target);
    console.log(input.value);
}, 600));

节流(throttle)

节流:限制一个函数在规定时间内只能执行一次。
场景1:拖拽一个元素时,要随时拿到该元素被拖拽的位置。直接用drag 事件,则会频繁触发,很容易导致卡顿。使用节流:无论拖拽速度多快,都会每隔100ms 触发一次。
场景2:高频点击提交,表单重复提交。

throttle.js
const div1 = document.getElementById('div1')

// 自定义节流
function throttle(fn, delay = 100) {
    let timer = null

    return function () {
        if (timer) {
            return
        }
        timer = setTimeout(() => {
            fn.apply(this, arguments)
            timer = null
        }, delay)
    }
}

div1.addEventListener('drag', throttle(function (e) {
    console.log(e.offsetX, e.offsetY)
}))

错误监控

错误的捕获方式

1.代码错误

try-catch

try-catch只能捕获到运行时的非异步错误,而语法错误和异步错误就捕捉不到。比较消耗性能,少用。

window.onerror

当有javaSript脚本运行错误或者资源<img>、<script>加载失败时,都会触发Event接口的error事件
//方式一:
window.onerror = function(error) { 
    console.log(error);
    return true;
}

//方式二:
window.addEventListener('error', (error) => {
    console.log(error);
    return true;
}, true);

window.onerror只有在返回true时,异常才不会向上抛出,原理是冒泡机制。
window.onerror是无法捕获到网络异常的。

2.资源加载错误

1) object.onerror
2) performance.getEntries()//获取所有已加载资源的加载时长===间接获取没有加载资源的错误。
3) Error事件捕获

跨域的js错误

所有跨域文件的js错误信息:Script error
处理方式:
1、在script标签增加 crossorigin属性
2、设置js资源响应头Access-Control-Allow-Origin:*
这样就可以拿到详细的错误信息了。

上报错误的基本原理?

1、采用Ajax通信的方式上报
2、利用Image对象上报(是所有监控体系都在做的事)

<script>
    (new Image()).src = "http://vaidu.cpm";
</script>

梁柱
135 声望12 粉丝