一、资源传输优化
使用压缩
Gzip
,如下所示: 对传输资源进行体积压缩,可高达 90%配置
Nginx
启用
Gzip
启用
Keep Alive
,如下所示: 一个持久的
TCP
连接,节省了连接创建时间
Nginx
默认开启
Keep Alive
HTTP
资源缓存,
HTTP
缓存是
client、cache、server
之间,提高重复访问时资源加载的速度。
HTTP
缓存,如下所示:
Cache-Control/Expries
Last-Modified + If-Modified-Sine
Etag + If-None-Match
Service Workers
,如下所示: 加速重复访问离线支持延长了首屏时间,但是页面总加载时间减少兼容性只能在
localhost
或
https
下使用
HTTP/2
的优势,如下所示: 二进制传输请求响应多路复用
Server push
搭建
HTTP/2
服务,如下所示:
HTTPS
适合较高的请求量 服务端渲染
SSR
的好处,如下所示: 加速首屏加载更好的
SEO
对于
React SSR
,可以使基于
Next.js
实现
SSR
。对于是否使用
SSR
,-如下所示: 架构大型、动态页面、面向公众用户搜索引擎排名很重要
二、渲染优化
从
PNG
到
IconFont
,如下所示: 多个图标到一套字体,减少获取时的请求数量和体积矢量图形,可伸缩直接通过
CSS
修改样式,颜色、大小等 从
IconFont
到
SVG
,如下所示: 保持了图片能力,支持多色彩独立的矢量图形
XML
语法,搜索引擎
SEO
和无障碍读屏软件读取
Flexbox
的优势,如下所示: 更高性能的实现方案容器有能力决定子元素的大小、顺序、对齐、间隔等双向布局
Flexbox
的使用,如下所示:
Flex container
容器
Flex items
元素 优化资源加载的顺序,资源优先级,如下所示: 浏览器默认安排资源加载的优先级使用
preload、prefetch
调整优先级
preload
和
prefetch
适用场景,如下所示:
preload
,提前加载较晚出现,但对当前页面非常重要的资源
prefetch
,提前加载后继路由需要的资源,优先级低 预渲染页面,预渲染的作用,如下所示: 大型单页应用的性能瓶颈,
JS
下载+解析+执行
SSR
的主要问题,牺牲
TTFB
来补救
First Paint
,实现复杂
Pre-rendering
打包时提前渲染页面,没有服务端参与 使用
React-Snap
,如下所示: 配置
postbuild
使用
ReactDOM.hydrate()
内联样式,避免明显的
FOUC
样式闪动
Windowing
窗口化提高列表性能,
windowing
的作用,如下所示: 加载大列表、大表单的每一行严重影响性能
Lazy loading
仍然会让
DOM
变得过大
windowing
只渲染可见的行,渲染和滚动的性能都会提升 对于使用
react-window
,如下所示: 配置一个一维列表
List
配置一个二维列表
Grid
配置滚动到指定元素 使用骨架组件减少布局移动,
Skeleton/Placeholder
的作用,如下所示: 占位提升用户感知性能 使用
react-placeholder
,如下所示: 预置的
placeholders
自定义的
placehlder
三、Web 加载和渲染原理
对于从输入
URL
到页面加载显示完成都发生了什么,如下所示:
UI thread
:搜索
or URL
-> 搜索引擎
or
请求的站点
Network thread
:
DNS
查找
IP
,建立
TLS
连接,如果收到 301 再来,然后设置
UA
等信息,发送
GET
请求,
Web server
上的应用处理请求,读取
Response
,分析数据类型,安全检查,通知
UI
数据准备就绪
Render process
:由
UI thread
到
Network thread
,再到
Main thread
Main thread
:解析文本构建
DOM
,边解析
DOM
边加载子资源,
JS
阻塞解析
async/defer
。然后解析
CSS
,计算
computed styles
,构造布局树位置和大小
Raster Thread、Compositor Thread
:创建绘制记录,确定绘制的顺序,将页面拆分图层,构建图层树,复合线程象素化图层,创建一个复合帧 首屏加载及优化,如下所示:
Web
增量加载的特点决定了首屏性能不会完美过长的白屏影响用户体验和留存首屏,相当于初次印象首屏,用户加载体验的3个关键时刻,测量指标,
First Contentful Paint(FCP)、Largest Contentful Paint(LCP)、Time to Interactive(TTI)
若资源体积太大,可以使用资源压缩、传输压缩、代码拆分、
Tree shaking、HTTP/2
、缓存等若首页内容太多,可以使用路由/组件/内容
lazy-loading
、预渲染/
SSR
、
Inline CSS
等若加载顺序不合适,可以使用
prefetch、preload
等
Javascript
内存管理,
JS
是怎样管理内存的,内存泄露会严重影响性能,什么情况下会造成内存泄露,如下所示: 变量创建时自动分配内存,不使用时自动释放内存,
GC
内存释放的主要问题是如何确定不再需要使用的内存所有的
GC
都是近似实现,只能通过判断变量是否还能在局部变量,函数执行完,没有闭包引用,就会被标记回收全局变量,直至浏览器卸载页面时释放引用计数,无法解决循环引用的问题标记清除,
MARK
到
SWEEP
避免意外的全局变量产生避免反复运行引发大量闭包避免脱离的
DOM
元素