面试官问你,对于性能优化你有什么方案?

164 阅读5分钟

前言

性能优化绝对是面试过程中问到频率最高的面试题,那我们作为前端切图仔,对于性能优化的方案应该是张口就来,侃侃而谈。下面整理了关于性能优化的各种方案,希望可以在面试过程中帮助到大家。

一、用户体验

一个页面被打开的时候,网页加载顺畅与否是用户可以最直观感受的,我们可以优先在对用户肉眼可以看到的地方先做一些优化。

  • 骨架屏

可以考虑使用一些插件生成骨架屏,在首屏加载完成之前先用骨架屏做占位

  • loading

增加一些有趣的loading过渡效果,减少用户等待时间的烦躁

二、浏览器的调试工具

  • Netword

Netword标签里面详情记录了每个资源的加载事件和缓存情况,可以根据里面提供的信息去对比加载慢的资源

  • waterfall瀑布流
  • lighthouse

lighthouse是chrome提供的一个开源的的网站性能评测工具,使用时,先提供一个需要审查的网址,它将针对此页面运行一连串的测试,然后生成一个有关页面性能的报告。

  • Perfomence
    performance面板有如下四个窗格:

  1、controls。开始记录,停止记录和配置记录期间捕获的信息

  2、overview。页面性能的高级汇总

  3、火焰图。 CPU 堆叠追踪的可视化

  4、统计汇总。以图表的形式汇总数据
  

三、webpack优化

具体可以参考之前写过相关的webpack优化的文章

webpack优化策略

四、压缩

  1. 开启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]\.";
  1. 服务端压缩

express中间件开启

    var compression = require('compression')
    var app = express();
    // 启用gzip
    app.use(compression());
  1. http2头部压缩

具体可以上网google下相关nginx开启http2的操作

五、缓存

  1. 静态资源缓存,是否开启强制缓存和协商缓存
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;

六、预加载

  1. preload
<link rel="preload" href="/path/to/style.css" as="style">

preload 提供了一种声明式的命令,让浏览器提前加载指定资源(加载后并不执行),需要执行时再执行

这样做的好处在于:

  • 将加载和执行分离开,不阻塞渲染和document的onload事件

  • 提前加载指定资源,不再出现依赖的font字体隔了一段时间才刷出的情况

==!!! 注意: 使用 preload后,不管资源是否使用都将提前加载。若不确定资源是必定会加载的,则不要错误使用 preload,以免本末倒置,给页面带来更沉重的负担==

  1. 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">
  1. 图片懒加载

可以参考之前写的文章实现懒加载

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属性

以上就是整理的性能优化方案,面试的时候做到心中有数,回答的时候才可以有条不紊。