0
点赞
收藏
分享

微信扫一扫

前端开发之性能优化


从 V8 中看 JS 性能优化

测试性能工具

  • Chrome 已经提供了一个大而全的性能测试工具 Audits。
  • 除了 Audits 工具之外,还有一个 Performance 工具也可以供我们使用。

JS性能优化

  • JS 是编译型还是解释型语言其实并不固定。首先 JS 需要有引擎才能运行起来,无论是浏览器还是在 Node 中,这是解释型语言的特性。所以总的来说 JS 更偏向于解释型语言

前端开发之性能优化_后缀

  • 如果一个函数被多次调用并且参数一直传入同一类型,那么 V8 就会认为该段代码可以编译为 Machine Code,因为你固定了类型,不需要再执行很多判断逻辑了。
  • 可以通过 Audit 工具获得网站的多个指标的性能报告
  • 可以通过 Performance 工具了解网站的性能瓶颈
  • 可以通过 Performance API 具体测量时间
  • 为了减少编译时间,我们可以采用减少代码文件的大小或者减少书写嵌套函数的方式
  • 为了让 V8 优化代码,我们应该尽可能保证传入参数的类型一致。这也给我们带来了一个思考,这是不是也是使用 TypeScript 能够带来的好处之一

性能优化琐碎事

图片优化

  • 计算图片大小
  • 减少像素点
  • 减少每个像素点能够显示的颜色
  • 图片加载优化
  • 不用图片。很多时候会使用到很多修饰类图片,其实这类修饰图片完全可以用 CSS 去代替。
  • 对于移动端来说,屏幕宽度就那么点,完全没有必要去加载原图浪费带宽。一般图片都用 CDN 加载,可以计算出适配屏幕的宽度,然后去请求相应裁剪好的图片。
  • 小图使用 base64 格式
  • 将多个图标文件整合到一张图片中(雪碧图)
  • 选择正确的图片格式:
  • 对于能够显示 WebP 格式的浏览器尽量使用 WebP 格式。因为 WebP 格式具有更好的图像数据压缩算法,能带来更小的图片体积,而且拥有肉眼识别无差异的图像质量,缺点就是兼容性并不好。
  • 小图使用 PNG,其实对于大部分图标这类图片,完全可以使用SVG 代替。
  • 照片使用 JPEG。

DNS预解析

  • DNS 解析也是需要时间的,可以通过预解析的方式来预先获得域名所对应的 IP。
  • ​<link rel="dns-prefetch" href="//yuchengkai.cn">​

节流

  • 考虑一个场景,滚动事件中会发起网络请求,但是我们并不希望用户在滚动过程中一直发起请求,而是隔一段时间发起一次,对于这种情况我们就可以使用节流。

// func是用户传入需要防抖的函数
// wait是等待时间
const throttle = (func, wait = 50) => {
// 上一次执行该函数的时间
let lastTime = 0
return function(...args) {
// 当前时间
let now = +new Date()
// 将当前时间和上一次执行函数时间对比
// 如果差值大于设置的等待时间就执行函数
if (now - lastTime > wait) {
lastTime = now
func.apply(this, args)
}
}
}
setInterval(
throttle(() => {
console.log(1)
}, 500),
1
)

防抖

  • 考虑一个场景,有一个按钮点击会触发网络请求,但是我们并不希望每次点击都发起网络请求,而是当用户点击按钮一段时间后没有再次点击的情况才去发起网络请求,对于这种情况我们就可以使用防抖。

// func是用户传入需要防抖的函数
// wait是等待时间
const debounce = (func, wait = 50) => {
// 缓存一个定时器id
let timer = 0
// 这里返回的函数是每次用户实际调用的防抖函数
// 如果已经设定过定时器了就清空上一次的定时器
// 开始一个新的定时器,延迟执行用户传入的方法
return function(...args) {
if (timer) clearTimeout(timer)
timer = setTimeout(() => {
func.apply(this, args)
}, wait)
}
}

预加载

​<link rel="preload" href="http://example.com">​

  • 有些资源不需要马上用到,但是希望尽早获取,这时候就可以使用预加载。
  • 预加载其实是声明式的 fetch ,强制浏览器请求资源,并且不会阻塞 onload 事件。
  • 预加载可以一定程度上降低首屏的加载时间,因为可以将一些不影响首屏但重要的文件延后加载,唯一缺点就是兼容性不好。

预渲染

​<link rel="prerender" href="http://example.com">​

  • 通过预渲染将下载的文件预先在后台渲染。
  • 预渲染虽然可以提高页面的加载速度,但是要确保该页面大概率会被用户在之后打开,否则就是白白浪费资源去渲染。

懒执行

  • 将某些逻辑延迟到使用时再计算。
  • 可以用于首屏优化,对于某些耗时逻辑并不需要在首屏就使用的,就可以使用懒执行。
  • 懒执行需要唤醒,一般可以通过定时器或者事件的调用来唤醒。

懒加载

  • 将不关键的资源延后加载。
  • 原理就是只加载自定义区域(通常是可视区域,但也可以是即将进入可视区域)内需要加载的东西。对于图片来说,先设置图片标签的 src 属性为一张占位图,将真实的图片资源放入一个自定义属性中,当进入自定义区域时,就将自定义属性替换为 src 属性,这样图片就会去下载资源,实现了图片懒加载。
  • 懒加载不仅可以用于图片,也可以使用在别的资源上。比如进入可视区域才开始播放视频等等。

CDN

  • 原理是尽可能的在各个地方分布机房缓存数据,这样即使我们的根服务器远在国外,在国内的用户也可以通过国内的机房迅速加载资源。
  • 可以将静态资源尽量使用 CDN 加载,由于浏览器对于单个域名有并发请求上限,可以考虑使用多个CDN 域名。
  • 对于 CDN 加载静态资源需要注意 CDN 域名要与主站不同,否则每次请求都会带上主站的Cookie,平白消耗流量。

Webpack 性能优化

减少 Webpack 打包时间

  • 优化 Loader
  • 对于 Loader 来说,影响打包效率首要就是 Babel
  • Babel 会将代码转为字符串生成 AST,然后对AST 继续进行转变最后再生成新的代码,项目越大,转换代码越多,效率就越低。
  • HappyPack
  • 受限于 Node 是单线程运行的,所以 Webpack 在打包的过程中也是单线程的,特别是在执行 Loader 的时候,长时间编译的任务很多,这样就会导致等待的情况。
  • 可以将 Loader 的同步执行转换为并行的,这样就能充分利用系统资源来加快打包效率。
  • DllPlugin
  • 特定的类库提前打包然后引入。
  • 可以极大的减少打包类库的次数,只有当类库更新版本才有需要重新打包,并且也实现了将公共代码抽离成单独文件的优化方案。
  • 小的优化点加快打包速度
  • resolve.extensions :用来表明文件后缀列表,默认查找顺序是 [’.js’, ‘.json’] ,如果你的导入文件没有添加后缀就会按照这个顺序查找文件。我们应该尽可能减少后缀列表长度,然后将出现频率高的后缀排在前面。
  • resolve.alias :可以通过别名的方式来映射一个路径,能让 Webpack 更快找到路径。
  • module.noParse :如果你确定一个文件下没有其他依赖,就可以使用该属性让 Webpack 不扫描该文件,这种方式对于大型的类库很有帮助。

减少 Webpack 打包后的文件体积

按需加载

  • 使用按需加载,将每个路由页面单独打包为一个文件。
  • 当使用的时候再去下载对应文件,返回一个 Promise ,当Promise 成功以后去执行回调。

Scope Hoisting

  • 分析出模块之间的依赖关系,尽可能的把打包出来的模块合并到一个函数中去。
  • 如果在 Webpack4 中你希望开启这个功能,只需要启用optimization.concatenateModules 就可以了。

Tree Shaking

  • 可以实现删除项目中未被引用的代码。
  • 使用 Webpack 4 的话,开启生产环境就会自动启动这个优化功能。


举报

相关推荐

0 条评论