前言
性能优化绝对是面试过程中问到频率最高的面试题,那我们作为前端切图仔,对于性能优化的方案应该是张口就来,侃侃而谈。下面整理了关于性能优化的各种方案,希望可以在面试过程中帮助到大家。
一、用户体验
一个页面被打开的时候,网页加载顺畅与否是用户可以最直观感受的,我们可以优先在对用户肉眼可以看到的地方先做一些优化。
- 骨架屏
可以考虑使用一些插件生成骨架屏,在首屏加载完成之前先用骨架屏做占位
- loading
增加一些有趣的loading过渡效果,减少用户等待时间的烦躁
二、浏览器的调试工具
- Netword
Netword标签里面详情记录了每个资源的加载事件和缓存情况,可以根据里面提供的信息去对比加载慢的资源
- waterfall瀑布流
- lighthouse
lighthouse是chrome提供的一个开源的的网站性能评测工具,使用时,先提供一个需要审查的网址,它将针对此页面运行一连串的测试,然后生成一个有关页面性能的报告。
- Perfomence
performance面板有如下四个窗格:
1、controls。开始记录,停止记录和配置记录期间捕获的信息
2、overview。页面性能的高级汇总
3、火焰图。 CPU 堆叠追踪的可视化
4、统计汇总。以图表的形式汇总数据
三、webpack优化
具体可以参考之前写过相关的webpack优化的文章
四、压缩
- 开启gzip(nginx)
gzip on;
#不压缩临界值,大于1K的才压缩,一般不用改
gzip_min_length 1k;
#buffer,就是,嗯,算了不解释了,不用改
gzip_buffers 4 16k;
#用了反向代理的话,末端通信是HTTP/1.0,默认是HTTP/1.1
#gzip_http_version 1.0;
#压缩级别,1-10,数字越大压缩的越好,时间也越长,看心情随便改吧
gzip_comp_level 2;
#压缩的文件类型
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
#跟Squid等缓存服务有关,on的话会在Header里增加"Vary: Accept-Encoding"
gzip_vary off;
#IE6对Gzip不怎么友好,不给它Gzip了
gzip_disable "MSIE [1-6]\.";
- 服务端压缩
express中间件开启
var compression = require('compression')
var app = express();
// 启用gzip
app.use(compression());
- http2头部压缩
具体可以上网google下相关nginx开启http2的操作
五、缓存
- 静态资源缓存,是否开启强制缓存和协商缓存
Cache-Control / Expires / Max-Age
设置资源是否缓存,以及缓存时间
Etag / If-None-Match
如果有变化,从服务器拉取资源。如果没变化则取缓存资源,状态码304,也就是协商缓存
Last-Modified / If-Modified-Since
通过对比时间差异判断
2、keep-alive
nginx.conf
# 0 为关闭
#keepalive_timeout 0;
# 65s无连接 关闭
keepalive_timeout 65;
# 连接数,达到100断开
keepalive_requests 100;
六、预加载
- preload
<link rel="preload" href="/path/to/style.css" as="style">
preload 提供了一种声明式的命令,让浏览器提前加载指定资源(加载后并不执行),需要执行时再执行
这样做的好处在于:
-
将加载和执行分离开,不阻塞渲染和document的onload事件
-
提前加载指定资源,不再出现依赖的font字体隔了一段时间才刷出的情况
==!!! 注意: 使用 preload后,不管资源是否使用都将提前加载。若不确定资源是必定会加载的,则不要错误使用 preload,以免本末倒置,给页面带来更沉重的负担==
- prefetch
它的作用是告诉浏览器加载下一页面可能会用到的资源,注意,是下一页面,而不是当前页面。因此该方法的加载优先级非常低,也就是说该方式的作用是加速下一个页面的加载速度
<link rel="prefetch" href="./comment.js">
<link rel="prefetch" href="./category.js">
<link rel="prefetch" href="./post.js">
<link rel="prefetch" href="./home.js">
- 图片懒加载
可以参考之前写的文章实现懒加载
InterSectionObserver实现懒加载 4. 路由懒加载
const page = () => import('@views/components/page');
七、ssr
服务端渲染SSR,vue使用nuxt.js,react使用next.js,可以相应去看下如果配置,这里不展开说明
八、老生常谈
- 使用cdn加载体积大的外部库或者静态资源文件(js,img)
- 小的图片转为base64或者合并成雪碧图,减少请求次数
- 减少对dom的直接操作,减少页面重绘和回流。
以下操作都容易引起页面重绘,尽可能避免或者合并操作。
- 删除,增加,或者修改DOM元素节点。
- 移动DOM的位置,开启动画的时候。
- 修改CSS样式,改变元素的大小,位置时,或者将使用display:none时,会造成重排;- - 修改CSS颜色或者visibility:hidden等等,会造成重绘。
- 修改网页的默认字体时。
- Resize
- 内容的改变,(用户在输入框中写入内容也会)。
- 激活伪类,如:hover。
- 计算offsetWidth和offsetHeight
减少重绘和重排的操作
- 尽量避免style的使用,对于需要操作DOM元素节点,重新命名className,更改className名称。
- 如果增加元素或者clone元素,可以先把元素通过documentFragment放入内存中,等操作完毕后,再appendChild到DOM元素中。
- 不要经常获取同一个元素,可以第一次获取元素后,用变量保存下来,减少遍历时间。
- 尽量少使用dispaly:none,可以使用visibility:hidden代替,dispaly:none会造成重排,visibility:hidden会造成重绘。
- 不要使用Table布局,因为一个小小的操作,可能就会造成整个表格的重排或重绘。
- 使用resize事件时,做防抖和节流处理。
- 对动画元素使用absolute / fixed属性。
- 批量修改元素时,可以先让元素脱离文档流,等修改完毕后,再放入文档流。
- 巧用css3 transition,transform属性
以上就是整理的性能优化方案,面试的时候做到心中有数,回答的时候才可以有条不紊。