We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
页面初载时,所有未压缩的 JavaScript 脚本大小:<=200KB;
页面初载时,所有未压缩的 CSS 资源大小:<=100KB;
HTTP 协议下,请求资源数:<=6 个;
HTTP/2 协议下,请求资源数:<=20 个 ;
**90%**的代码利用率(也就是说,仅允许 10% 的未使用代码);
Ctrl + Shift + P 搜索Coverage调出查看代码利用率的工具。
Ctrl + shift + p 搜索选中 show frames meter 实时查看fps,GPU内存。
Shift+Esc 查看浏览器内存管理器
Page Speed 或者lightHouse 做整体项目性能分析
如果想要上报一些性能有关的数据,建议查看 window.performance 相关api
chrome中的performance + network + memory 部分工具
chrome 工具中的memory Heap snapshot。其实就是当前页面的js对象及其相关的DOM节点的内存分布情况。 可以在内存泄露前生成一份堆快照,再在内存泄露后生成一份堆快照。通过对比的方式,找出两份堆快照存在的内存泄露点。最好是在一次操作后分析,以便分析出问题。
网上常见的性能优化方案,基本可以分为3类
好了,性能优化说完了。。。。
前两条,资源加载和渲染,可以一起说,这就避不开一个问题,就是从输入URL到页面加载完成,发生了什么,搞明白这个问题,才能有针对的优化。
这里只列出简易说明,详细请看 这里
这几个过程中可以进行优化的方向在括号中都已说明。 下面说下具体怎么做。
link标签有rel值,可以帮开发者做资源预加载。
rel=preload 做资源的预加载,加载后并不执行。
rel=dns-prefetch
浏览器会对某个域名预先进行 DNS 解析并缓存。这样,当浏览器在请求同域名资源的时候,能省去从域名查询 IP 的过程,从而减少时间损耗
<meta http-equiv="x-dns-prefetch-control" content="on"> <link rel="dns-prefetch" href="xxx">
rel=preconnect。
让浏览器在一个 HTTP 请求正式发给服务器前预先执行一些操作,这包括 DNS 解析、TLS 协商、TCP 握手,通过消除往返延迟来为用户节省时间。
prefetch / preload。
两个值都是让浏览器预先下载并缓存某个资源,但不同的是,prefetch 可能会在浏览器忙时被忽略,而 preload 则是强制浏览器在不阻塞document的onload事件的情况下请求资源。使用 preload 和 prefetch 的逻辑可能不是写到一起,但一旦发生对用一资源 preload 或 prefetch 的话,会带来双倍的网络请求。
prefetch可以用来加载关键的脚本,字体,主要图片等。
preload 加载资源一般是当前页面需要的,prefetch 一般是其它页面有可能用到的资源。
对跨域的文件进行 preload 的时候,我们必须加上 crossorigin 属性
<link rel="preload" as="font" crossorigin href="https://xx/font_zck90zmlh7hf47vi.woff">
rel = prerender
浏览器不仅会加载资源,还会解析执行页面,进行预渲染。
<link rel="dns-prefetch" href="//g.alicdn.com"> // 慎用,浏览器自己有自己的一套域解析方法 <link rel="preload" href="/path/to/style.css" as="style">
使用http响应头的Link字段创建
Link: <https:/ /example.com/other/styles.css>; rel=preload; as=style
关于资源的预加载,要注意一点。加载资源可能会加长首屏渲染的时间,请谨慎使用。
关于网络请求这部分直接用http缓存就好,详情查看 这里
1.缩减用户和服务器的距离,提升加载效率
2.浏览器对一个域名的并发请求有限制,所以用cdn域名专门加载静态资源
比如项目中用到的echarts等第三方包,可以用cdn引入。
加载资源如果是图片的话,可针对图片进行优化。
使用base64的编码方式,对这个图片进行 Base64 编码,浏览器原来是可以理解这个字符串的,它自动就将这个字符串解码为了一个图片,而不需再去发送 HTTP 请求。用于小图 Base64 编码后,图片大小会膨胀为原文件的 4/3(这是由 Base64 的编码原理决定的)
jpeg,jpg, 体积小,加载快,不支持透明,用与大图,有损压缩,不好处理矢量图,颜色对比强烈的图
png 无损压缩,高保真,体积大,用于logo,图标,透明图
svg 体积小,灵活,矢量图不失真,可编程,渲染成本高
webp 体积和质量相对最平衡的一种图片类型
雪碧图 减少HTTP请求
关于图片除了使用合理文件类型,雪碧图,还可以通过image-webpack-loader压缩,减少体积。
除了客户端渲染之外,还有另一种方案--服务端渲染。
客户端渲染模式下,服务端会把渲染需要的静态文件发送给客户端,客户端加载过来之后,自己在浏览器里跑一遍 JS,根据 JS 的运行结果,生成相应的 DOM。
服务端渲染的模式下,当用户第一次请求页面时,由服务器把需要的组件或页面渲染成 HTML 字符串,然后把它返回给客户端。客户端拿到手的,是可以直接渲染然后呈现给用户的 HTML 内容,不需要为了生成 DOM 内容自己再去跑一遍 JS 代码
搜索引擎只会查找现成的内容,不会帮你跑 JS 代码。
img中的alt属性是搜索引擎判断图片与文字是否相关的重要依据,优化搜索引擎.
服务端渲染本质上是本该浏览器做的事情,分担一部分给服务器去做。这样当资源抵达浏览器时,它呈现的速度就快了。乍一看好像很合理:浏览器性能毕竟有限,服务器多牛逼!能者多劳,就该让服务器多干点活!
但仔细想想,在这个网民遍地的时代,几乎有多少个用户就有多少台浏览器。用户拥有的浏览器总量多到数不清,那么一个公司的服务器又有多少台呢?我们把这么多台浏览器的渲染压力集中起来,分散给相比之下数量并不多的服务器,服务器肯定是承受不住的,所以需要合理使用服务端渲染。
浏览器拿到资源后,进行解析资源的过程。
我们知道,只有当我们开始解析 HTML 后、解析到 link 标签或者 style 标签时,CSS 才登场,CSSOM 的构建才开始。很多时候,DOM 不得不等待 CSSOM。因此我们可以这样总结:
CSS 是阻塞渲染的资源。需要将它尽早、尽快地下载到客户端,以便缩短首次渲染的时间。
这个“把 CSS 往前放”的动作,对很多同学来说已经内化为一种编码习惯。那么现在我们还应该知道,这个“习惯”不是空穴来风,它是由 CSS 的特性决定的。
当渲染引擎解析 HTML 遇到 script 标签引入文件时,会立即进行一次渲染。所以这也就是为什么构建工具会把编译好的引用 JavaScript 代码的 script 标签放入到 body 标签底部,因为当渲染引擎执行到 body 底部时会先将已解析的内容渲染出来,然后再去请求相应的 JavaScript 文件。如果是内联脚本(即不通过 src 属性引用外部脚本文件直接在 HTML 编写 JavaScript 代码的形式),渲染引擎则不会渲染。
以上就说明了两点,css引入放开头,js引入放结尾。 js文件可以通过async,defer加载,避免阻塞dom树的解析。
浏览器自己清楚,如果每次 DOM 操作都即时地反馈一次回流或重绘,那么性能上来说是扛不住的。于是它自己缓存了一个 flush 队列,把我们触发的回流与重绘任务都塞进去,待到队列里的任务多起来、或者达到了一定的时间间隔,或者“不得已”的时候,再将这些任务一口气出队。
当要用到像这样的属性:offsetTop、offsetLeft、 offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、clientTop、clientLeft、clientWidth、clientHeight 时,就要注意了!
这些值有一个共性,就是需要通过即时计算得到。因此浏览器为了获取这些值,也会进行回流。
除此之外,当我们调用了 getComputedStyle 方法,或者 IE 里的 currentStyle 时,也会触发回流。原理是一样的,都为求一个“即时性”和“准确性”。
对于回流重绘,只能想办法减少次数。
new HtmlWebpackPlugin({ filename: 'xxxx.html', template: 'template.html', loading: loading // loading组件 })
不变的框架代码做缓存,只发布业务代码。 react,react-dom等依赖,webpack打包的时候单独抽离。
不是每个设备都需要polyfill,使用polyfill.io这样的动态polyfill,保证在需要时引入
代码分割 SplitChunksPlugin,基于路由做分包,react.lazy或者bundle-loader。
不是所有的设备都需要babel编译到es5的代码
<script type="module" src="main.js"></script> <script nomodule src="main.es5.js"></script>
支持type=module的浏览器,必然支持async/await promise, class 箭头函数 等等 而不支持 <script type="module"> 的老旧浏览器,会因为无法识别这个标签,而不去加载 ES2015+ 的代码。另外老旧的浏览器同样无法识别 nomodule 熟悉,会自动忽略它,从而加载 ES5 标准的代码。
至此,加载资源和渲染说完了。
https://zhuanlan.zhihu.com/p/62047452
The text was updated successfully, but these errors were encountered:
No branches or pull requests
性能标准
页面初载时,所有未压缩的 JavaScript 脚本大小:<=200KB;
页面初载时,所有未压缩的 CSS 资源大小:<=100KB;
HTTP 协议下,请求资源数:<=6 个;
HTTP/2 协议下,请求资源数:<=20 个 ;
**90%**的代码利用率(也就是说,仅允许 10% 的未使用代码);
性能分析工具
Ctrl + Shift + P 搜索Coverage调出查看代码利用率的工具。
Ctrl + shift + p 搜索选中 show frames meter 实时查看fps,GPU内存。
Shift+Esc 查看浏览器内存管理器
Page Speed 或者lightHouse 做整体项目性能分析
如果想要上报一些性能有关的数据,建议查看 window.performance 相关api
chrome中的performance + network + memory 部分工具
chrome 工具中的memory Heap snapshot。其实就是当前页面的js对象及其相关的DOM节点的内存分布情况。
可以在内存泄露前生成一份堆快照,再在内存泄露后生成一份堆快照。通过对比的方式,找出两份堆快照存在的内存泄露点。最好是在一次操作后分析,以便分析出问题。
网上常见的性能优化方案,基本可以分为3类
好了,性能优化说完了。。。。
前两条,资源加载和渲染,可以一起说,这就避不开一个问题,就是从输入URL到页面加载完成,发生了什么,搞明白这个问题,才能有针对的优化。
这里只列出简易说明,详细请看 这里
这几个过程中可以进行优化的方向在括号中都已说明。
下面说下具体怎么做。
link标签有rel值,可以帮开发者做资源预加载。
rel值:
rel=preload
做资源的预加载,加载后并不执行。
rel=dns-prefetch
浏览器会对某个域名预先进行 DNS 解析并缓存。这样,当浏览器在请求同域名资源的时候,能省去从域名查询 IP 的过程,从而减少时间损耗
rel=preconnect。
让浏览器在一个 HTTP 请求正式发给服务器前预先执行一些操作,这包括 DNS 解析、TLS 协商、TCP 握手,通过消除往返延迟来为用户节省时间。
prefetch / preload。
两个值都是让浏览器预先下载并缓存某个资源,但不同的是,prefetch 可能会在浏览器忙时被忽略,而 preload 则是强制浏览器在不阻塞document的onload事件的情况下请求资源。使用 preload 和 prefetch 的逻辑可能不是写到一起,但一旦发生对用一资源 preload 或 prefetch 的话,会带来双倍的网络请求。
prefetch可以用来加载关键的脚本,字体,主要图片等。
preload 加载资源一般是当前页面需要的,prefetch 一般是其它页面有可能用到的资源。
对跨域的文件进行 preload 的时候,我们必须加上 crossorigin 属性
rel = prerender
浏览器不仅会加载资源,还会解析执行页面,进行预渲染。
使用http响应头的Link字段创建
关于资源的预加载,要注意一点。加载资源可能会加长首屏渲染的时间,请谨慎使用。
关于网络请求这部分直接用http缓存就好,详情查看 这里
CDN
1.缩减用户和服务器的距离,提升加载效率
2.浏览器对一个域名的并发请求有限制,所以用cdn域名专门加载静态资源
比如项目中用到的echarts等第三方包,可以用cdn引入。
图片的优化
加载资源如果是图片的话,可针对图片进行优化。
使用base64的编码方式,对这个图片进行 Base64 编码,浏览器原来是可以理解这个字符串的,它自动就将这个字符串解码为了一个图片,而不需再去发送 HTTP 请求。用于小图
Base64 编码后,图片大小会膨胀为原文件的 4/3(这是由 Base64 的编码原理决定的)
jpeg,jpg, 体积小,加载快,不支持透明,用与大图,有损压缩,不好处理矢量图,颜色对比强烈的图
png 无损压缩,高保真,体积大,用于logo,图标,透明图
svg 体积小,灵活,矢量图不失真,可编程,渲染成本高
webp 体积和质量相对最平衡的一种图片类型
雪碧图 减少HTTP请求
关于图片除了使用合理文件类型,雪碧图,还可以通过image-webpack-loader压缩,减少体积。
服务端渲染
除了客户端渲染之外,还有另一种方案--服务端渲染。
客户端渲染模式下,服务端会把渲染需要的静态文件发送给客户端,客户端加载过来之后,自己在浏览器里跑一遍 JS,根据 JS 的运行结果,生成相应的 DOM。
服务端渲染的模式下,当用户第一次请求页面时,由服务器把需要的组件或页面渲染成 HTML 字符串,然后把它返回给客户端。客户端拿到手的,是可以直接渲染然后呈现给用户的 HTML 内容,不需要为了生成 DOM 内容自己再去跑一遍 JS 代码
搜索引擎只会查找现成的内容,不会帮你跑 JS 代码。
img中的alt属性是搜索引擎判断图片与文字是否相关的重要依据,优化搜索引擎.
服务端渲染本质上是本该浏览器做的事情,分担一部分给服务器去做。这样当资源抵达浏览器时,它呈现的速度就快了。乍一看好像很合理:浏览器性能毕竟有限,服务器多牛逼!能者多劳,就该让服务器多干点活!
但仔细想想,在这个网民遍地的时代,几乎有多少个用户就有多少台浏览器。用户拥有的浏览器总量多到数不清,那么一个公司的服务器又有多少台呢?我们把这么多台浏览器的渲染压力集中起来,分散给相比之下数量并不多的服务器,服务器肯定是承受不住的,所以需要合理使用服务端渲染。
解析资源
浏览器拿到资源后,进行解析资源的过程。
我们知道,只有当我们开始解析 HTML 后、解析到 link 标签或者 style 标签时,CSS 才登场,CSSOM 的构建才开始。很多时候,DOM 不得不等待 CSSOM。因此我们可以这样总结:
CSS 是阻塞渲染的资源。需要将它尽早、尽快地下载到客户端,以便缩短首次渲染的时间。
这个“把 CSS 往前放”的动作,对很多同学来说已经内化为一种编码习惯。那么现在我们还应该知道,这个“习惯”不是空穴来风,它是由 CSS 的特性决定的。
当渲染引擎解析 HTML 遇到 script 标签引入文件时,会立即进行一次渲染。所以这也就是为什么构建工具会把编译好的引用 JavaScript 代码的 script 标签放入到 body 标签底部,因为当渲染引擎执行到 body 底部时会先将已解析的内容渲染出来,然后再去请求相应的 JavaScript 文件。如果是内联脚本(即不通过 src 属性引用外部脚本文件直接在 HTML 编写 JavaScript 代码的形式),渲染引擎则不会渲染。
以上就说明了两点,css引入放开头,js引入放结尾。
js文件可以通过async,defer加载,避免阻塞dom树的解析。
关于渲染时的回流重绘
浏览器自己清楚,如果每次 DOM 操作都即时地反馈一次回流或重绘,那么性能上来说是扛不住的。于是它自己缓存了一个 flush 队列,把我们触发的回流与重绘任务都塞进去,待到队列里的任务多起来、或者达到了一定的时间间隔,或者“不得已”的时候,再将这些任务一口气出队。
当要用到像这样的属性:offsetTop、offsetLeft、 offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、clientTop、clientLeft、clientWidth、clientHeight 时,就要注意了!
这些值有一个共性,就是需要通过即时计算得到。因此浏览器为了获取这些值,也会进行回流。
除此之外,当我们调用了 getComputedStyle 方法,或者 IE 里的 currentStyle 时,也会触发回流。原理是一样的,都为求一个“即时性”和“准确性”。
对于回流重绘,只能想办法减少次数。
具体的性能优化的方案
不变的框架代码做缓存,只发布业务代码。
react,react-dom等依赖,webpack打包的时候单独抽离。
不是每个设备都需要polyfill,使用polyfill.io这样的动态polyfill,保证在需要时引入
代码分割 SplitChunksPlugin,基于路由做分包,react.lazy或者bundle-loader。
不是所有的设备都需要babel编译到es5的代码
支持type=module的浏览器,必然支持async/await promise, class 箭头函数 等等
而不支持 <script type="module"> 的老旧浏览器,会因为无法识别这个标签,而不去加载 ES2015+ 的代码。另外老旧的浏览器同样无法识别 nomodule 熟悉,会自动忽略它,从而加载 ES5 标准的代码。
至此,加载资源和渲染说完了。
哪些情况容易导致内存泄露
https://zhuanlan.zhihu.com/p/62047452
The text was updated successfully, but these errors were encountered: