sanlangguo / learn-notes

学习笔记
16 stars 1 forks source link

详细分析 web 性能优化 #5

Open sanlangguo opened 3 years ago

sanlangguo commented 3 years ago

性能优化

  1. Speed Index https://developer.mozilla.org/en-US/docs/Glossary/Speed_index
  2. TTFB https://developer.mozilla.org/en-US/docs/Glossary/time_to_first_byte
  3. 页面加载时间 https://developer.mozilla.org/zh-CN/docs/Web/Performance
  4. 首次渲染

性能优化-响应

  1. 交互动作的反馈时间
  2. 帧率 FPS
  3. 异步请求的完成时间

影响回流的操作-渲染优化与浏览器为友

  1. 添加/删除元素
  2. display: none
  3. 操作 styles
  4. 移动元素位置
  5. offsetLeft, scrollTop, clientWidth
  6. 修改浏览器大小,字体大小
  7. 避免逐项更改样式。一次性更改style属性,或者直接定义class属性

避免直接插入DOM。在documentFragment上操作,然后再插入document中 避免循环读取offsetWidth等属性。循环外存取 避免复杂动画。利用绝对定位将其脱离文档流 避免CSS选择符层级太多。尽量平级类名,参考 scss 中的&的用法 为频繁重绘或者回流的节点设置图层: iframe、video 等节点自动变为图层 通过 3d 动画出发:transform: translate3d(0, 0, 0) 提前通知浏览器:will-change 属性

JS-代码优化-对象优可以做那些

  1. 以相同顺序初始化对象成员,避免隐藏类的调整
  2. 实例化后避免添加新属性
  3. 尽量使用 Array 代替 array-like 对象

CSS 优化

  1. 降低 CSS 对渲染的阻塞
  2. 使用 contain 属性
  3. 利用 GPU 进行完成动画
  4. 使用 font-display 属性 (https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display

渐进式图片的解决方案

  1. progressive-image
  2. ImageMagick
  3. libjpeg
  4. jpegtran
  5. jpeg-recompress
  6. imagemin

使用响应式图片

  1. srcset 属性的使用
  2. sizes 属性的使用
  3. picture 的使用

使用 font-display

image

Babel 优化配置

  1. 在需要的地方引用 polyfill
  2. 辅助函数的按需引入
  3. 根据目标浏览器按需转换代码

noParse (https://webpack.js.org/configuration/module/#modulenoparse

  1. 提高构建速度
  2. 直接通知 webpack 忽略较大的库
  3. 被忽略的库不能有 import,require, define 的引入方式

DllPlugin (https://webpack.js.org/plugins/dll-plugin/#dllplugin

  1. 避免打包时对不变的库重复构建
  2. 提高构建速度

代码拆分做什么

  1. 把单个 bundle 文件拆分成若干小 bundles/chunks
  2. 缩短首屏加载时间

webpack 代码拆分的方法

  1. 手工定义入口
  2. splitChunks 提取公有代码,拆分业务代码与第三方库
  3. 动态加载

Minification

  1. Terser压缩 JS
  2. mini-css-extract-plugin 压缩 CSS
  3. HtmlWebpackPlugin-minify 压缩 HTML

持久化缓存方案

  1. 每个打包的资源文件有唯一的 hash 值
  2. 修改后只有受影响的文件 hash 变化
  3. 充分利用浏览器缓存

检测与分析

  1. stats 分析与可视化
  2. webpack-bundle-analyzer 进行体积分析 (https://www.npmjs.com/package/webpack-bundle-analyzer
  3. speed-measure-webpack-plugin 速度分析 (https://www.npmjs.com/package/speed-measure-webpack-plugin

React 按需加载

  1. React-Router 基于 webpack 动态引入
  2. 使用 Reloadable 高级组件

Gzip

  1. 对传输资源进行体积压缩,可高达90%
  2. 如何配置 Nginx 启用 Gzip

Keep Alive

  1. 一个持久的TCP连接,节省了连接创建的时间
  2. Nginx 默认开启 Keep Alive

HTTP 缓存

image

  1. Cache-Control / Expires
  2. Last-Modified + If-Modified-Since
  3. Etag + If-None-Match

Service Workers 原理

Service Workers 是一种在 Web 浏览器中运行的脚本,它可以独立于网页进行后台运行,并且能够拦截网络请求、缓存资源以及在离线状态下提供离线功能。

Service Workers 的工作原理如下:

Service Workers 注意

  1. 延长了首屏时间,但页面总加载时间减少
  2. 兼用型
  3. 只能 localhost / https 使用

HTTP2 优势

image

  1. 二进制传输
  2. 请求响应多路复用
  3. Server push 等

搭建 HTTP2 服务 (场景)

  1. HTTPS
  2. 适合较高的请求量

SSR 的好处

  1. 加速首屏加载
  2. 更好的 SEO 122638362-3ac6c680-d126-11eb-8507-dfaf976778db副本

是否使用 SSR

  1. 架构-大型,动态页面,面向公众用户
  2. 搜素引擎排名很重要

从PNG 到 IconFont

  1. 多个图标 ---> 一套字体,减少获取时的请求数量和体积
  2. 矢量图形,可伸缩
  3. 直接通过 CSS 修改样式(大小,颜色等等)

从IconFont 到 SVG

  1. 保持了图片能力,支持多色彩
  2. 独立的矢量图形
  3. XML 语法,搜素引擎 SEO和无障碍读屏软件读取

Flexbox 的优势

  1. 更高性能的实现方案
  2. 容器有能力决定子元素的大小,顺序,对其,间隔等
  3. 双向布局

资源优先级

  1. 浏览器默认安排资源加载优先级
  2. 使用 preload, prefetch 调整优先级

preload 优先加载当前资源 refetch 空闲时预加载资源

image

image

Prefetching/Preloading modules

预渲染的作用

  1. 大型单页面应用的性能瓶颈:JS下载 + 解析 + 执行
  2. SSR 的主要问题: 牺牲 TTFB 来补救 First Paint; 实现复杂
  3. Pre-rendering 打包时提前渲染页面,没有服务端参与

dns-prefetch

DNS-prefetch (DNS 预获取) 是尝试在请求资源之前解析域名。这可能是后面要加载的文件,也可能是用户尝试打开的链接目标。

为什么要使用 dns-prefetch?

当浏览器从(第三方)服务器请求资源时,必须先将该跨域域名解析为 IP地址,然后浏览器才能发出请求。此过程称为 DNS解析。DNS 缓存可以帮助减少此延迟,而 DNS解析可以导致请求增加明显的延迟。对于打开了与许多第三方的连接的网站,此延迟可能会大大降低加载性能。

dns-prefetch 可帮助开发人员掩盖 DNS解析延迟。 HTML 元素 通过 dns-prefetch的 rel 属性 (en-US)值提供此功能。然后在 href属性中指要跨域的域名:

句法

<link rel="dns-prefetch" href="https://fonts.googleapis.com/"> 

Note: 如果页面需要建立与许多第三方域的连接,则将它们预先连接会适得其反。 preconnect 提示最好仅用于最关键的连接。对于其他的,只需使用 即可节省第一步的时间-DNS查找。

参看 MDN dns-prefetch

使用 React-Snap

  1. 配置 postBuild
  2. 使用 ReactDOM.hydrate()
  3. 内联样式,避免明显的 FOUC(样式抖动)

windowing 的作用

  1. 加载大列表,大表单的每一行严重影响性能
  2. Lazy loading 仍然会让 DOM变得过大
  3. windowing 只渲染可见的行,渲染和滚动的性能都会提升

使用 react-window

  1. 配置一个一维列表
  2. 配置一个二维列表
  3. 配置滚动到指定元素

使用骨架组建减少布局移动(Layout Shift)

浏览器输入URL 发生了什么

image 13551624086947 image image image

首屏优化

image image image image

image image image image image image image