yuadhのinterview_note yuadhのinterview_note
前端基础
软件框架
算法|数据结构
基础学科
系统|工具
项目
面试综合
专栏
GitHub (opens new window)
前端基础
软件框架
算法|数据结构
基础学科
系统|工具
项目
面试综合
专栏
GitHub (opens new window)
  • Browser
  • CN
  • CSS
  • Git
  • HTML
  • JS
  • Optimize
    • 会造成阻塞吗
    • 合成
      • DNS预解析
      • 缓存
      • 使用HTTP2.0
      • 预加载(首屏优化不提)
      • 预渲染
      • 减少HTTP请求
      • SSR
      • Gzip压缩
      • 避免重定向
      • 懒执行
      • 懒加载
      • 节流防抖
    • 合适图片格式
      • JPEG/JPG
      • PNG
      • SVG
      • GIF
      • Webp
    • webpack压缩
    • 雪碧图
    • iconfont
    • 内联Base 64
    • CSS代替图
    • CDN图片
    • 图片懒加载
    • 图片预加载
    • 响应式图加载
    • 渐进式图片
      • Webpack 优化
      • 监控
    • 加载慢的原因
    • 解决
      • 减少入口文件体积
      • 组件重复打包
      • SSR
    • 补充
  • OS
  • Project-Others
  • React
  • Review
  • Vue
  • 场景题
  • 备注
  • 专栏
yuadh
2022-12-19
目录

Optimize

# 优化指标

写给中高级前端关于性能优化的9大策略和6大指标 | 网易四年实践 (opens new window)

让用户感觉这个网站很「快」 , 一种是「真的快」一种是「觉得快」

  • 「真的快」 可 客观衡量的指标, 网页访问时间、交互响应时间、跳转页面时间

  • 「觉得快」 用户主观感知的性能,通过视觉引导等手段转移用户对等待时间的关注

  • 动画流畅

  • 表单提交速度

  • 列表滚动页面切换是否卡顿

  • 响应速度:页面初始访问速度 + 交互响应速度

  • 页面稳定性:页面出错率,资源加载错误,JS 执行报错

  • 外部服务调用:网络请求访问速度

最好的性能指标:100ms 内响应用户输入;动画/滚动在 10ms 内下一帧;最大化空闲时间;页面加载时长不超过 5 秒

系统架构、性能分析、网站优化、网站监控

# 权衡

一种优化方案可能适用于大多数项目,但是特殊情况下可能会起反效果

浏览器有单域名下并发请求限制,通常我们将依赖统一打包减少首屏请求数,依赖不变动文件指纹不变,利用缓存。依赖不多这么处理有助于提升加载速度,一旦依赖多起来,包就会特别 大, 弱网条件 严重拖慢页面显示

所以 根据情况 对vendor拆分, 如拆分到CDN,或者直接拆分到页面

因此, 在 性能优化过程中,必须根据最终能给用户体验带来的提升权衡后做出适合 的选择

# 优化手法

  • 聚焦用户
  • 尽快响应用户输入
  • 动画执行流畅
  • 最大化主线程空闲时间
  • 网页可交互性

# HTML

  • 避免HTML中直接写CSS
  • viewport加速页面渲染
  • 使用语义化标签
  • 减少标签的使用,DOM解析是一个大量遍历的过程
  • 避免src和href空值
  • 减少DNS查询数

# CSS

  • 避免后代选择符

  • 避免链式~

  • 避免!important

  • link代替@import

@import会将请求变得 串行化,导致加载增加延迟

  • 减少回流与重绘
  • CSS 放在 head 中
  • 压缩CSS 开启gzip压缩
  • 骨架屏+合理的loading
  • 优化选择器路径,避免 过多嵌套
  • 选择器合并:压缩空间和资源开销
  • 精确样式

比如设置{padding-left:10px}的值,避免{padding:0 0 0 10px}这样的写法

  • 异步加载CSS
  • 避免通配符

.a .b *{} 像这样的选择器,从右到左解析,在解析过程中遇到通配符(**)会去遍历整个dom

  • 少用float:渲染时计算量大
  • 0值不加单位:兼容性
  • 避免使用 昂贵 的属性

因为他们渲染成本挺高,渲染速度慢一些

  • border-radius
  • box-shadow
  • opacity
  • transform
  • filter
  • position: fixed
  • 使用先进布局方式——flex

# 会造成阻塞吗

  • CSS加载不会阻塞DOM树解析
  • CSS加载会阻塞DOM树渲染
  • CSS加载会阻塞后面JS执行

# JS

  • 避免循环操作DOM
  • 事件委托

绑定事件时,不绑定到目标元素上,而是绑定到其祖先元素上

  • 监听事件少
  • 新增节点时,无需增加事件绑定
  • scrip标签放在body后

CSS放在head

因为JS阻塞DOM的构建(因为DOM解析遇到JS会停止解析,开始下载脚本并执行) ,CSSOM的构建阻塞JS执行

  • 压缩文件
  • 按需加载
  • 避免逐个操作DOM样式,尽可能预留好CSS样式,通过样式名的修改改变DOM样式,集中式操作减少reflow的次数
  • 减少iframe数量

# 合成

  • 合成层的位图 交由GPU处理,比CPU块
  • repaint本身,不影响其它层
  • transform和opacity不触发重绘

# 代码问题

  • 频繁使用JSON.parse/JSON.stringify大对象
  • 正则灾难性回溯
  • 内存泄漏
  • 服务端开启文件压缩功能
  • 执行 JS 代码过长会卡顿,对需要很多时间计算的代码可用 web worker

# 网络相关

# DNS预解析

预先获得域名所对应的 IP,href的值是预解析的域名

<link rel="dns-prefetch" href="//xxx.example.com" />
1

preload和prefetch

preload强制浏览器立即获取资源, 具有较高优先级

prefetch的资源获取时可选 和 较低 优先级的,是否获取取决于浏览器

# 缓存

强缓存

协商缓存

选择合适缓存策略

对于大部分的场景都可以使用强缓存配合协商缓存解决

  • 使用 Cache-control: no-store ,表示该资源不需要缓存
  • 使用 Cache-Control: no-cache 并配合 ETag ,表示该资源已被缓存,但是每次都会发送请求询问资源是否更新
  • 使用 Cache-Control: max-age=31536000 并配合策略缓存使用,对文件进行指纹处理,一旦文件名变动就会立刻下载新的文件

# 使用HTTP2.0

  • 解析速度快
  • 头部压缩
  • 多路复用
  • 服务器推送
  • 浏览器由并发请求限制

# 预加载(首屏优化不提)

  • 有些资源不需要马上用到,但希望尽早获取

  • 预加载强制请求资源,不会阻塞 onload 事件

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

# 预渲染

将下载的文件预先在后台渲染

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

预渲染可以提高页面的加载速度,但是要确保该页面百分百会被用户,否则白白浪费资源

# 减少HTTP请求

# SSR

SSR (service side render),后端将HTML拼接好返回前端

优点

  • 前端耗时少
  • 利于SEO,有完整HTML页面,爬虫更易获取信息
  • 无需占用客户端资源
  • 后端生成静态化文件
  • 首屏加载更快

缺点

  • 不利于前后端分离
  • 占用服务器资源

客户端渲染

优点

  • 前后端分离
  • 体验更好

缺点

  • 前端响应较慢
  • 不利于SEO

# Gzip压缩

# 避免重定向

# 渲染优化

# 懒执行

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

# 懒加载

将不关键的资源延后加载——尽量只加载用户正 浏览 或即将会 浏览的图片

只加载自定义区域(通常是可视区域,但也可以是即将进入可视区域)内需要加载的东西

对于图片来说,先设置图片标签的 src 属性为一张占位图,真实的图片资源放入自定义属性data-src 中,当进入自定义区域时,就将自定义属性替换为 src 属性,这样就会下载图片资源

# 节流防抖

防抖:单位时间内多次触发,只执行最后的那一次,原理:延迟执行,期间但凡有新的触发就重置定时器

节流:单位时间只触发一次,原理:上锁,只有满足一定间隔时间才能执行

# 图片

电商类项目,存在大量图片,banner 广告图、菜单导航栏、列表头图等

图片众多以及体积过大影响页面加载速度

为啥?

有些图片请求并发,Chrome最多支持并发请求数有限,其他请求被push进队列中等待或停滞,直到上轮请求完成后才被发出,一部分资源需要排队等待时间,过多的图片影响页面加载展示

# 合适图片格式

  • WebP 格式具有更好的图像数据压缩算法,更小的图片体积,拥有肉眼识别无差异的图像质量,缺点是兼容性并不好
  • 小图使用 PNG,对于大部分图标,完全可以使用 SVG 代替
  • 照片使用 JPEG
  • 雪碧图( 将多个图标文件整合到一张图片中 )

可能请求非常多的小图片,会受到浏览器并发 HTTP 请求数的限制

  • 图片压缩
  • 不用图片,用CSS代替
  • 对于移动端来说,屏幕宽度就那么点,完全没有必要去加载原图浪费带宽。一般图片都用 CDN 加载,可以计算出适配屏幕的宽度,然后去请求相应裁剪好的图片

# JPEG/JPG

  • 高质量 有损压缩,体积小,不支持透明
  • 应用于轮播图 大的背景图、banner

# PNG

  • 无损压缩,质量好,体积大,支持透明
  • 应用小的logo

# SVG

  • 体积小,不失真,兼容好
  • 应用于图标

# GIF

  • 支持透明

# Webp

有损压缩与无损压缩(可逆压缩)的图片文件格式

比PNG/JPEG格式小

支持透明度

体积和效果上都做的不错

<picture>
    <source type="image/webp" srcset="/static/img/perf.webp">
    <source type="image/jpeg" srcset="/static/img/perf.jpg">
    <img src="/static/img/perf.jpg">
</picture>
1
2
3
4
5

# webpack压缩

配置 image-webpack-loader

# 雪碧图

CSS Sprites ,精灵图,图像合成技术,主要用于小图片显示

同原域名请求有最大并发限制,Chrome为6个,如 页面有10个小图,需要10次请求,2次并发

若把10个图合成一个大图,只需1次请求

  1. 减少请求次数
  2. 减少服务器压力
  3. 减少并发
  4. 提高加载速度
  5. 减少鼠标滑过的一些bug
  6. 解决网页设计师在图片命名上的困扰

# iconfont

通过字体方式展示图标,用户 图标渲染、简单图形、特殊字体等

  • 轻量,已修改
  • 减少请求次数

# 内联Base 64

图片转为base64串,解析图片不会请求下载,而是解析字符串

缺点

  1. 比使用二进制体积增大 33%
  2. 全部内联后,原本可并行加载的图片会串行放入请求

适用于 更新频率低、首屏或骨架图上的小图标

# CSS代替图

实现修饰效果,半透明、阴影、圆角、渐变等

# CDN图片

# 图片懒加载

暂时不设置图片的src属性,先卸载data-src中,等图片到了可视区域再将真实src放进src属性

使用background-url,应用到具体元素时,才会下载图片

# 图片预加载

需要展示大量图,将图提前加载到本地缓存

# 响应式图加载

在不同分辨率的设备上显示不同尺寸的图

# 渐进式图片

和骨架屏 原理类似

在图完全加载完前先显示低画质版本,让用户产生图片加载变快的印象,而不是盯着一片空白

# CDN

内容分发网络

静态资源使用 CDN 加载,由于浏览器对于单个域名有并发请求上限,可以考虑使用多个 CDN 域名

# 其他

# Webpack 优化

  • 对于 Webpack,打包项目使用 production 模式,会自动开启代码压缩
  • ES6 模块开启 tree shaking,移除没有使用的代码
  • 优化图片,对于小图使用 base64 的方式写入文件
  • 按照路由拆分代码,实现按需加载
  • 给打包出来的文件名添加哈希,实现浏览器缓存文件

# 监控

采集——>上传——>分析——>报警

# 渲染几万条数据?

requestAnimationFrame 每 16 ms 刷新

分页+虚拟滚动、图片懒加载、图片的动态裁剪

# SPA首屏优化

浏览器从响应用户输入网址地址,到首屏内容渲染完成时间,整个网页不一定要完全渲染完成,但需要展示当前视窗内容

# 加载慢的原因

  • 网络延时
  • 资源文件体积过大
  • 资源加载重复发送请求
  • 加载脚本时,渲染内容阻塞

# 解决

  • 减少入口文件体积
  • 静态资源本地缓存
  • UI框架按需加载
  • 图片资源压缩
  • 组件重复打包
  • GZip压缩
  • 使用SSR
  • JS外联文件放在HTML文档底部,CSS外联文件放在HTML文档头部
  • 减少cookie体积
  • 骨架屏
  • h5方式一次性渲染

# 减少入口文件体积

路由懒加载,将不同路由对应组件分割成不同代码块,待路由被请求时单独打包路由,使得入口文件变小

以函数形式动态加载路由,可以把各自的路由文件分别打包,只在解析给定路由时,才会加载路由组件

# 组件重复打包

若A.js是一个常用库,多个路由使用它会造成重复下载

在webpack的config中,修改CommonChunkPlugin的配置

minChunks为3表示会把使用3次及以上的包抽离,放进公共依赖文件

# SSR

服务端渲染,Server Side ,组件或页面通过服务器生成html字符串,发送到浏览器

  1. 二次启动时先利用缓存渲染,后台进行异步数据更新
  2. 减少不必要的请求 和数据获取
  3. 提前请求或减少http请求
  4. 优化图片文件尺寸,压缩图片格式,压缩代码
  5. 启用gzip 压缩功能
  6. 使用CDN
  7. 网址后面加上“/”:对服务器而言,不加斜杠服务器会多一次判断的过程,加斜杠就会直接返回网站设置的存放在网站根目录下的默认页面。
  8. Ajax采用缓存调用

# 网页卡顿?

  1. 网络请求是否过多,导致数据传输变慢,可通过缓存优化
  2. 资源bundle太大,考虑拆分
  3. 代码是否有太多循环在主线程上花费太长时间
  4. 浏览器某个帧 中 渲染太多东西
  5. 页面渲染时,大量回流和重绘
  6. 内存泄露

# 动画优化

  • 合理布局
  • transform代替left、top 减少重排
  • 硬件加速
  • 避免不必要的图形层
  • requestAnimationFrame实现动画

动画每一帧都是re-render,显示器刷新频率 60 HZ,意味着每一帧任务耗时不超过 16ms

# React官网优化

React 渲染的未来 (opens new window)

# 补充

react官网不完全由react开发,得益于Gatsby库

Gatsby 性能很好,开发很自由,基于 React 和 GraphQL 构建网站的库。用于构建静态网站,如博客、企业官网、静态内容相对比较多的网站

监听link如何实现?

result:使用 Intersection Observer,兼容问题

编辑 (opens new window)
上次更新: 2023/02/07, 15:11:55
JS
OS

← JS OS→

最近更新
01
青训营真题day01
02-07
02
01day01-html与css
02-07
03
day02-js
02-07
更多文章>
Theme by Vdoing | Copyright © 2022-2023 yuadh | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式