性能优化 让你的页面更丝滑

吐槽君 分类:javascript

前言

性能优化是一个很宏大的命题,无论是是大厂还是小公司,都在为让页面更快的展现在用户面前做优化和探索,页面性能也是检验一个前端工程师项目成果的重要指标,所以,无论是不是要面试,常用的性能优化的手段还是要熟练掌握

在前面两篇文章前端工程师必看的服务器知识、追本溯源 浏览器渲染机制,详细介绍了
url从输入到页面的渲染中间的技术细节,这篇我们总结下,常用的性能优化操作

神图保存

navigation Timing流程图

减少HTTP请求

减少页面的HTTP请求数是个起点,这是提升站点首次访问速度的重要指导原则,小字当先

合并脚本和样式表

合并css和js文件,合并文件大小之后,大文件gizp之后不能超过33kb(不是一股脑的打包成一个),文件数量要适量

CSS Sprites

是减少图片请求数量的首选方式。把背景图片都整合到一张图片中,然后用CSS的 background-imagebackground-position 属性来定位要显示的部分。

行内图片(Base64编码)

用 data: URL模式 来把图片嵌入页面。这样会增加HTML文件的大小,把行内图片放在(缓存的)样式表中是个好办法,而且成功避免了页面变“重”。但目前主流浏览器并不能很好地支持行内图片。

配置多个域名和CDN加速

通常浏览器对于一个域名的并发请求是有限的,比如:有100个文件要加载,但浏览器一次只可能并发请求10个文件,这样并发多次就会耗时。因此配置多个域名能够最大限度的增加并发请求量。

但这里有个缺点就是会增加浏览器域名解析的次数,这里建议利用CDN来加载不是经常更新和修改的静态资源(图片,css库,js第三方库等等)。一个是CDN域名一般都会缓存到本地中,另一个是CDN网络请求速度是非常快的。

缓存策略

缓存资源是最立竿见影的手段,通过在请求头设置缓存属性,下次再次访问可以直接从本地获取资源,减少了不必要的数据传输,节省带宽、减少服务器的负担,提升网站性能、加快了客户端加载网页的速度、关于强缓存和协商缓存的内容可以看之前前端工程师必看的服务器知识。

image.png

缓存的优先级:cache-control > expires > Etag > last-modified

在第一次请求时,浏览器会检查是否有缓存设置,记入内存,下次请求,服务器判断返回304从缓存取,200会从服务器取。

cache-control

设置过期时间长度(秒),在这个时间范围内,浏览器就会直接读取缓存,当expires和cache-control都存在时,cache-control的优先级更大

expires

在http头中设置一个过期时间,这个过期时间之前,浏览器请求不会发出,从缓存中读取文件,除非缓存被清空,或者强制刷新,缺陷在于服务器时间和客户端的时间可能不一致,所有http1.1引入了cache-control来改进。

etag

服务器返回资源时,如果头部有etag,资源在下次请求时会把值自动加到请求头if-none-match中,服务器可以对比这个值,确定资源是否发生变化,如果没有变化返回304

last-modified

服务器返回资源时,如果头部有last-modified,资源请求时机会把值加入到if-modified-since中,服务器可以对比这个值,确定资源是否发生变化返回304

传输加载优化

启动gzip

在nginx中配置gzip: on

我们可以先来对比下,如果我们没有开启zip压缩之前,我们的对应的文件大小,如下所示:

image.png

现在我们开启了gzip进行压缩后的文件的大小,可以看到如下所示:

image.png
并且我们查看响应头会看到gzip这样的压缩,如下所示

image.png

这种压缩比例是非常客观的,大幅度提升了页面的效率。

Keep-Alive

在http请求头中加入Connection: keep-alive来告诉对方这个请求响应完成后不要关闭,下一次咱们还用这个请求继续交流.

Keep-Alive 在Http1.1 默认是开启的,可以在 Response Header 中可以看到 Connection: keep-alive

在nginx 配置中有两个比较重要的配置

keepalive_timeout 65  // 保持连接的时间,也叫超时时间,单位秒
keepalive_request 100 // 最大连接上限 
 

浏览器请求//xx.cn/a.js-->解析域名—>HTTP连接—>服务器处理文件—>返回数据-->浏览器解析、渲染文件。Keep-Alive解决的核心问题就在此,一定时间内,同一域名多次请求数据,只建立一次HTTP请求,其他请求可复用每一次建立的连接通道,以达到提高请求效率的问题。一定时间是可以配置的,

HTTP1.1还是存在效率问题

  • 串行的文件传输
  • 连接数过多

HTTP/2对同一域名下所有请求都是基于流,也就是说同一域名不管访问多少文件,也只建立一路连接。同样Apache的最大连接数为300,因为有了这个新特性,最大的并发就可以提升到300,比原来提升了60倍!

懒加载

在可视化的窗口中才去加载图片,大大提高首次的渲染速度!
原生支持加loading属性需要浏览器支持

第三方插件

  • lazyload (opens new window)
  • react-lazyload(opens new window)

渲染中性能优化

上一篇中我们我们看到浏览器在渲染的时候生成了四棵树

  • GUI线程和js线程是互斥
  • 重排和重绘很消耗性能

把样式表放在顶部,js文件放在底部

雅虎军规规定,样式表放在顶部js文件放在底部,这样做的意义是为了二位爷不要打架,和谐执行。

减少重排和重绘

chrome DevTools可以检测到页面渲染的性能分析
我们用keyframes。来实现一个动画效果。

<div class="container">
  <div class="ball" id="ball"></div>
</div>

@keyframes run-around {
  0% {
    top: 0;
    left: 0;
  }
  25% {
    top: 0;
    left: 200px;
  }
  50% {
    top: 200px;
    left: 200px;
  }
  75% {
    top: 200px;
    left: 0;
  }
}
 

用chrome DevTols检测

image.png

  • Loading:网络通信和 HTML 解析
  • Scripting:JavaScript 执行时间
  • Rendering:样式计算和布局,即 Layout 重排
  • Painting:重绘

image.png

看到浏览器一直在重排和重绘合成的循环里

我们使用transfrom替换绝对定位进行GUI加速

0% {
  transform: translate(0, 0);
}
25% {
  transform: translate(200px, 0);
}
50% {
  transform: translate(200px, 200px);
}
75% {
  transform: translate(0, 200px);
}
 

再次录制

image.png

我们可以看到鲜明的对比,直接跳过了重排和重绘的过程,大大提升了页面的性能

requestAnimationFrame

动画操作,可以使用 requestAnimationFrame 要求浏览器在下次重绘之前调用指定的回调函数更新动画,可以达到和浏览器同步刷新,以避免不必要的开销。

雅虎军规

雅虎公司制定了8个部分,35条性能优化准则,本文部分取自军规详细展开,详情可以查看`参考链接`。
 

页面加载性能指标

思考一个问题?,我们在进行性能优化之后,是如何来评定我们的优化手段是否满足我们的业务,是否有量化的标准来帮助我们来分析是否还有不足,精准的定位到问题

image.png

阶段(简写) 描述 阶段(全称)
TTFP 首字节时间 Time TO Frist Byte
FP 首次绘制(第一个节点) First Paint
FCP 首次有内容的绘制(骨架) First Contentful Paint
FMP 首次有意义的绘制(包含所有元素/数据) First Meaningful
TTI 达到可交互时间,推荐的响应时间是100ms以内否则有延迟 Time To Interactive
Long tasks 超过了 50ms 的任务
SSR&&CSR 服务端渲染和客户端渲染 Server-Side-Rendering / Client Side Rendering
Isomorphic 同构化

以一个h5页面打开为例

image.png

用chrome面板监控 FP、FCP、FMP、TTI

image.png

SPA性能问题

通常用 React/Vue 编写的代码打包后如下:

image.png

只有一个根节点,dom是由js解析之后生成虚拟dom -> dom diff -> 页面

解决方案: 可以采用SSR服务端渲染把html内容填充进去,不过会牺牲TTFP时间。

小结

就像我们在电梯时会疯狂按关闭按键一样,用户是没有耐心等待一个页面的加载,一个性能很差的页面很容易流失用户。

本文承接上面两篇文章,对整个流程做了一个总结,分析中间可以优化的步骤,当然,这里只是尽可能多的举出优化的方案,参考链接中会给出一些比较好的优化整理,性能优化任重道远,本文会持续更新

参考链接

彻底弄懂强缓存与协商缓存

雅虎军规35条

前端性能优化小结

web前端性能优化总结

前端性能优化的七大手段

nginx缓存配置及开启gzip压缩

手机淘宝性能优化【分享】

前端性能优化 —— 减少HTTP请求

xikun's blog

作者:掘金-性能优化 让你的页面更丝滑

回复

我来回复
  • 暂无回复内容