前端性能优化

我们在工作中经常听到一个词:“前端性能优化”。

讲真,前端性能优化是我们工作中必须关注的现实问题,也是前端面试中屡屡被问到的点。

我记得我第一次面试的时候,面试官提出这个问题出来我人一愣。

总觉得有很多要讲的,但是又讲不出几条,那今天咱们来梳理一下吧。

1、减少HTTP请求次数

尽量将多个小文件合并成一个大文件,比如图片,CSS,JS。因为假如一个页面有 5 个 JS 文件的话,就会发 5 次 HTTP 请求,一个的话,就只会发出一次 HTTP 请求。

2、静态资源(CSS,JS,图片)使用 CDN

内容分发网络(CDN)是一组分布在多个不同地理位置的 Web 服务器。

我们都知道,当服务器离用户越远时,延迟越高。

CDN 就是为了解决这一问题,在多个位置部署服务器,让用户离服务器更近,从而缩短请求时间。

3、将 CSS 放在文件头部,JS 文件放在底部

网页上的资源加载时从上网下顺序加载的,所以 CSS 放在页面的顶部能够优先渲染页面,让用户感觉页面加载很快。

加载 JS 时会对后续的资源造成阻塞,必须得等 JS 加载完才去加载后续的文件 ,所以就把 JS 放在页面底部最后加载。

4、使用字体图标 iconfont 代替图片图标

因为 iconfont 文件特别小。

5、善用缓存,不重复加载相同的资源

数据如果要重复使用,就可以使用缓存,不要重复请求。

6、使用gzip压缩内容

gzip 能够压缩任何一个文本类型的响应,包括html,xml,json。大大缩小请求返回的数据量。

7、图片优化

(1). 图片延迟加载

首先可以将图片这样设置,在页面不可见时图片不会加载:

<img data-src="https://avatars0.githubusercontent.com/u/22117876?s=460&u=7bd8f32788df6988833da6bd155c3cfbebc68006&v=4">

等页面可见时,使用 JS 加载图片:

const img = document.querySelector('img')
img.src = img.dataset.src
(2). 不要在HTML中缩放图片

比如你需要的图片尺寸是50* 50

那就不用用一张500*500的大尺寸图片,影响加载

(3). 降低图片质量

例如 JPG 格式的图片,100% 的质量和 90% 质量的通常看不出来区别,尤其是用来当背景图的时候。我经常用 PS 切背景图时, 将图片切成 JPG 格式,并且将它压缩到 60% 的质量,基本上看不出来区别。

(4). 尽可能利用 CSS3 效果代替图片

有很多图片使用 CSS 效果(渐变、阴影等)就能画出来,这种情况选择 CSS3 效果更好。因为代码大小通常是图片大小的几分之一甚至几十分之一。

(5). 使用 webp 格式的图片

8、避免使用 CSS 表达式

举个 CSS 表达式的例子:

font-color: expression( (new Date()).getHours()%3 ? “#FFFFFF" : “#AAAAAA" );
这个表达式会持续的在页面上计算样式,影响页面的性能。并且 CSS 表达式只被 IE 支持。

9、 为文件头指定Expires

Exipres是用来设置文件的过期时间的,一般对CSS、JS、图片资源有效。

他可以使内容具有缓存性,这样下回再访问同样的资源时就通过浏览器缓存区读取,不需要再发出 HTTP 请求。

10、减少重绘重排

用 JS 修改样式时,最好不要直接写样式,而是替换 class 来改变样式。
如果要对 DOM 元素执行一系列操作,可以将 DOM 元素脱离文档流,修改完成后,再将它带回文档。推荐使用隐藏元素(display:none)或文档碎片(DocumentFragement),都能很好的实现这个方案。

11、使用事件委托

事件委托利用了事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。

所有用到按钮的事件(多数鼠标事件和键盘事件)都适合采用事件委托技术, 使用事件委托可以节省内存。

<ul>
  <li>苹果</li>
  <li>香蕉</li>
  <li>凤梨</li>
</ul>

// good
document.querySelector('ul').onclick = (event) => {
  const target = event.target
  if (target.nodeName === 'LI') {
    console.log(target.innerHTML)
  }
}

// bad
document.querySelectorAll('li').forEach((e) => {
  e.onclick = function() {
    console.log(this.innerHTML)
  }
}) 

12、通过 webpack 按需加载代码,提取第三库代码,减少 ES6 转为 ES5 的冗余代码

根据文件内容生成文件名,结合 import 动态引入组件实现按需加载。

output: {
 filename: '[name].[contenthash].js',
    chunkFilename: '[name].[contenthash].js',
    path: path.resolve(__dirname, '../dist'),
},

提取第三方库,这里需要使用 webpack4 的 splitChunk 插件 cacheGroups 选项。

optimization: {
   runtimeChunk: {
        name: 'manifest' // 将 webpack 的 runtime 代码拆分为一个单独的 chunk。
    },
    splitChunks: {
        cacheGroups: {
            vendor: {
                name: 'chunk-vendors',
                test: /[\\/]node_modules[\\/]/,
                priority: -10,
                chunks: 'initial'
            },
            common: {
                name: 'chunk-common',
                minChunks: 2,
                priority: -20,
                chunks: 'initial',
                reuseExistingChunk: true
            }
        },
    }
},

还可以减少 ES6 转为 ES5 的冗余代码,Babel 转化后的代码想要实现和原来代码一样的功能需要借助一些帮助函数。

13、避免跳转

有种现象会比较坑爹,看起来没什么差别,其实多次了一次页面跳转。比如当URL本该有斜杠(/)却被忽略掉时。

例如,当我们要访问 http://baidu.com 时,实际上返回的是一个包含301代码的跳转,它指向的是 http://baidu.com/(注意末尾的斜杠)。

在 nginx 服务器可以使用 rewrite。

14、减少DOM元素数量

减少DOM数量,就会减少浏览器的解析负担。

15、不要覆盖原生方法

无论你的 JS 代码如何优化,都比不上原生方法。

因为原生方法是用低级语言写的(C/C++),并且被编译成机器码,成为浏览器的一部分。当原生方法可用时,尽量使用它们,特别是数学运算和 DOM 操作。

16、 降低 CSS 选择器的复杂性

(1). 浏览器读取选择器,遵循的原则是从选择器的右边到左边读取。

例子:

#block .text p {
 color: red;
}
  1. 查找所有 P 元素。
  2. 查找结果 1 中的元素是否有类名为 text 的父元素
  3. 查找结果 2 中的元素是否有 id 为 block 的父元素
(2). CSS 选择器优先级
  1. 选择器越短越好。
  2. 尽量使用高优先级的选择器,例如 ID 和类选择器。
  3. 避免使用通配符 *。

17、配置 ETags

它用来判断浏览器缓存里的元素是否和原来服务器上的一致。比 last-modified date 更具有弹性,例如某个文件在 1 秒内修改了 10 次,Etag 可以综合 Inode (文件的索引节点( inode )数),MTime (修改时间) 和 Size 来精准的进行判断,避开 UNIX 记录 MTime 只能精确到秒的问题。

服务器集群使用,可取后两个参数。使用 ETags 减少 Web 应用带宽和负载

18、避免404

比如外链的 CSS、JS 文件出现问题返回 404 时,会破坏浏览器的并行加载。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值