前端常见面试题-性能优化

加载优化

  1. webpack压缩合并
    CommonsChunkPlugin主要是用来提取第三方库和公共模块,避免首屏加载的bundle文件或者按需加载的bundle文件体积过大
  2. 代码分割,基于路由或者模块分割
  3. 第三方模块使用cdn方式
  4. 大模块异步加载,require.ensure
mapBtn.click(function() {
  require.ensure([], function() {
    var baidumap = require('./baidumap.js') //baidumap.js放在我们当前目录下
  })
})
//等价于
mapBtn.click(function() {
  //获取 文档head对象
  var head = document.getElementsByTagName('head')[0];
  //构建 <script>
  var script = document.createElement('script');
  //设置src属性
  script.async = true;
  script.src = "http://map.baidu.com/.js"
  //加入到head对象中
  head.appendChild(script);
})
//第一个参数用于依赖优先下载,如果A和B都要异步下载,B依赖于A,则需要先下载A
//也是请求下载的模块,如果想加载A require.ensure(['A.js'],function) 即可

  1. 零散的小模块合并一起加载
    使用entry 指定文件入口,或者头部import/require建立依赖关系
  2. 使用预加载prefetch,适用于分步场景

图片优化

  1. 小图片都是用sprite图片整合在一张图片,减少并发的次数,base64内联,
  2. 图片是用懒加载
  3. 使用webp格式
  4. 图片要压缩
  5. 使用srcset,配置不一样的分辨率对应不同的图片大小,能精准对应不同的尺寸用户,节省流量。

css优化

  1. css写在头部
    为了尽快在屏幕上显示内容,浏览器不会等到所有的HTMl元素解析之后在构建和布局dom树
    但是如果css写在底部,浏览器会一直等待 css全部加载完,才开始解析。
    而且下载并解析css完毕后,已经呈现的文字和图片就要需要根据新的样式重绘
  2. 避免css表达式
    background-color: expression((new Date()).getHours()%2 ? "#B8D4FF" : "#F08A00" );
  3. 移除没用的css定义规则
  4. 减少行内style样式
    样式分离,具有更好的易读性和方便维护

js优化

1. js放在body底部

这样处理的好处是无需担心因页面未完成加载,造成DOM节点获取不到,而且能避免因脚本运行缓慢造成页面卡死的问题。

2. js用defer放在头部,提前加载,又不阻塞dom解析

script标签的3个加载方式

  1. 默认,按顺序加载和执行,会阻塞
  2. async 异步下载,并一定会在onload之前执行,不按声明的顺序,只要加载完可能就立刻执行,会影响渲染。
  3. defer 异步下载,并一定会在onload之后执行,在DOMContentLoaded之前执行。多个defer会按顺序执行。

3. script标签添加crossorigin ,方便收集错误,

不加只能看到error: Script error.很少信息。注意:服务端必须开启Access-Control-Allow-Origin * ,不然也是无效,

渲染优化

1.尽量减少reflow回流和repaint重绘
网页如何生成:

  • 解析html绘制DOM树
  • 解析css绘制CSS树
  • 生成render tree(渲染树)
  • flow排列,将渲染树节点合成(渲染)
  • paint绘制,将排列绘制在屏幕上(渲染)

触发重排属性和方法
改变元素几何信息(大小和位置),都会引起

  • DOM改变
  • input 输入内容改变
  • resize
  • style属性改变
  • margin
  • 计算offsetWidth和offsetHeight

触发重绘的条件:

  • 改变元素外观属性。如:color,background-color等。

2.用变量缓存dom,不要频繁操作dom读取。
比如 let a = $("#a") 下次就直接使用a,而不是再调用一次查询$("#a")
3.使用DocumentFragment或者innerHtml批量插入dom
4.使用类似虚拟dom的方式完成所有修改,最后再一次性更新
5.动画元素使用absolute,脱离稳定流,不影响其他元素。动画不使用left,top设置,该用transform和opacity,同时开启渲染层 will-change 或者 translate3d(0,0,0)

transform和left,top动画区别

  • transform是视觉上的动画,不改变元素在dom里面的位置,并能开启GPU单独渲染,不影响主线程,只占用合成线程。
  • left,top动画会触发整个页面的重绘,重排,占用主线程,同时也会同步信息到 合成线程进行渲染。
    GPU3个加速的属性transform, opacity, filter

(1). 主线程的任务:

  • 运行Javascript
  • 计算HTML元素的CSS样式
  • layout (relayout)
  • 将页面元素绘制成一张或多张位图
  • 将位图发送给合成线程
    (2). 合成线程的任务:
  • 利用GPU将位图绘制到屏幕上
  • 让主线程将可见的或即将可见的位图发给自己
  • 计算哪部分页面是可见的
  • 计算哪部分页面是即将可见的(当你的滚动页面的时候)
  • 在你滚动时移动部分页面

6.动画尽量使用requestanimationFrame,不用定时器。
显示器有固定的刷新频率(60Hz 或 75Hz)。也就是说,每秒最多只能重绘 60 次或 75 次,1000/60 = 16.7ms ,1000ms / 75 = 13.3ms
requestAnimationFrame 的基本思想让页面重绘的频率与 这个刷新频率保持同步
注意settimeout和setinterval 是依赖event loop 有可能设置 settimeout( ()=>{},16.7)//会在18秒才触发,因为要等待前面队列的任务处理完。
requestanimationFrame

7.移动端硬件加速,触发gpu渲染,translate3d(0,0,0)

首屏优化

原则 显示快,滚动流畅,懒加载,懒执行,渐进式展示

  1. 代码分离,将首屏以外的代码分离掉
  2. 服务端渲染/ 预渲染,减少白屏时间
  3. DNS prefetch,pc端域名发散,移动端域名 收敛
    浏览器 发起URL请求的过程:阻挡、域名解析、建立连接、发送请求、等待响应、接收数据,
    (1)阻挡:浏览器处于性能考虑,相同的域名一次只能限制4-8条请求,其他均会阻塞,为了解决这个问题,可以把资源拆散到不同的二级域名下面。
    (2)域名解析:由于域名解析是在请求域名时候解析,会占用一部分解析的时间,可以提前预加载dns
    配置如下:meta告诉浏览器打开预dns解析,link添加rel="dns-prefetch" 告诉浏览器可以把对应的href进行提前解析,不用等到加载的时候。
    <meta http-equiv="x-dns-prefetch-control" content="on">
    <link rel="dns-prefetch" href="//www.zhix.net">
  1. 通过第三方工具分析当前页面关键路径css,把关键css改成内联。有效减少加载与渲染时间。
    每次页面加载都需要等待所有css加载执行完毕,才开始渲染,如果css体积过大可能会出现上时间白屏,可以把当前页面所需要的所有关键的css提取出来。直接内联到当前页面,那么css所需要的时间可以有效缩短。可以通过第三方工具分析提取有效的css进行内联。

打包优化

  1. 拆包DllPlugin
  2. 合并公用文件 CommonsChunkPlugin
  3. 缩小打包工具搜索范围 include exclude
  4. 开启缓存 loader启动cache
  5. 多线程加速打包 thead-loader
  6. tree-shaking开启摇树,移动无用的死代码
  7. scope hoisting es6 模块分析,(作用域提升)将多模块合并到一个函数,减少内存招用,减小体积,提高运行速度。

vue 性能优化

主要探讨Vue代码层面的优化

  1. 路由懒加载
 const router = new VueRouter({ 
  routes: [ 
{ path: '/foo', component: () => import('./Foo.vue') }   ] 
})
  1. keep-live 缓存组件
<template> 
  <div id="app"> 
    <keep-alive> 
      <router-view/>     
</keep-alive> 
  </div> 
</template> 
  1. 列表添加key,确保唯一性
  2. 列表绑定事件使用事件代理(v-for)
  3. v-if 和 v-for不同时使用,因为for优先,可以提取在外层先v-if判断
  4. 展示不变的大列表数据object.freeze冻结,不触发响应逻辑。
let list = Object.freeze(res.data); 
  1. 在需要复用大量数据显示的场景,使用v-show 代替v-if
  2. 对于大数据展示,可以使用虚拟滚动,先渲染可视力=范围 vue-virtual-scroller,vue-virtual-scroll-list
  3. 组件销毁时,只会自动解绑全部指令和事件绑定,仅仅限于组件本身,像setInterval需要手动解除
 created() { 
  this.timer = setInterval(this.refresh, 2000) }, 
 beforeDestroy() { 
  clearInterval(this.timer) 
 }

10.图片懒加载 vue-lazyload

<img v-lazy="/static/img/1.png">

react优化

  1. 路由懒加载 react-loadable
  2. 类组件添加 shouldComponent或PureCompoent
  3. 函数组件添加React.memo
  4. 列表添加key
  5. 函数组件使用hook 优化,useMeno useCallback

SEO优化

  1. 添加各种meta 信息 key 关键字
  2. 预渲染
    构建阶段生成匹配预渲染路径的 html 文件
  3. 服务端渲染
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,686评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,668评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,160评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,736评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,847评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,043评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,129评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,872评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,318评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,645评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,777评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,861评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,589评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,687评论 2 351

推荐阅读更多精彩内容