几乎所有的开发者都会面临着开发的网站存在加载问题,想要加快网页的加载速度。前端的页面更需要在性能优化上下功夫,只有这样才能实现更好的用户体验。本文从构建、浏览器渲染、缓存、PWA、服务端优化等多方面,梳理前端性能优化的技术点、综合分析技术的原理,根据不同的业务场景选择合适的性能优化点进行应用,最终为你的网站带来显著的速度提升和整体性能提升。
先看一下早期CS架构的开发与部署过程
再看一下现在BS架构的开发与部署过程
从地址栏输入url到页面渲染出来,整个过程经历了什么(一道经典的面试题。。)让我们用一张图来了解整个过程:
从上图这个请求过程,我们可以思考一下其中一些潜在的性能优化点:
- dns是否可以通过缓存减少dns查询时间?
- 网络请求的过程走最近的网络环境?
- 相同的静态资源是否可以缓存?
- 能否减少请求http的请求大小?
- 减少http请求数量?
- 服务端渲染?
综上,我们得出深入理解http请求过程
是前端性能优化的核心
资源合并与压缩
html压缩
HTML代码压缩就是压缩这些在文本文件中有意义,但是在HTML中不显示
的字符,包括空格
、制表符
、换行符
等,还有一些其他意义的字符,如HTML注释
也可以被压缩。
HTML代码压缩的意义:
以google为例,google的流量,占到整个互联网的40%,2016年全球网络流量达到1.3ZB(1ZB=10^9TB)
,那么google在2016年的流量就是1.3ZB*40%,如果google每1MB请求减少一个字节,每年可以节省流量近500TB
。
那么如何进行HTML的压缩呢?
- 使用在线网站进行压缩
- nodejs提供了html-minifier工具
- 后端模版引擎渲染压缩
css及js压缩
如何进行css压缩:
- 使用在线网站进行压缩
- 使用html-minifier对html中的css进行压缩
- 使用clean-css对css进行压缩
如何进行js压缩和混乱:
- 使用在线网站进行压缩
- 使用html-minifier对html中对js进行压缩
- 使用uglify2对js进行压缩
文件合并
但是文件合并也存在它自己的问题:
- 首屏渲染问题
- 缓存失效问题
解决方案:
- 公共库合并
- 不同页面的合并
- 随机应变,根据业务场景作出抉择,选出最优方案
如何进行文件合并:
- 使用在线网站进行文件合并
- 使用nodejs实现文件合并
图片相关的优化
一张JPG图片的解析过程
png8、png24、png32之间的区别
区别主要还是文件大小和色彩的丰富程度
-
png8
:256色 + 支持透明 -
png24
:2^24色 + 不支持透明 -
png32
:2^24色 + 支持透明
每种图片格式都有自己的特点,针对不同的业务场景选择不同的图片格式很重要。
不同格式图片常用的业务场景
先看一下四种常用图片格式的各自特点吧:
-
jpg
有损压缩,压缩率高,不支持透明 -
png
支持透明,浏览器兼容好 -
webp
压缩程度更好,在ios webview有兼容性问题 -
svg
矢量图,代码内嵌,相对较小,图片样式相对简单的场景
根据各自不同的特点得到适用的业务场景分别为:
-
jpg
:大部分不需要透明图片的业务场景 -
png
:大部分需要透明图片的业务场景 -
webp
:安卓全部 -
svg
:图片样式相对简单的业务场景,如icon
图片压缩几种方法-雪碧图、Image inline
css雪碧图
image inline
矢量图
- 使用svg进行矢量图的绘制
- 使用iconfont解决icon问题
在安卓下使用webp
webp的优势体现在它具有更优的图像数据压缩算法,能带来更小的图片体积,而且拥有肉眼识别无差异的图像质量;同时具备了无损和有损的压缩模式、Alpha透明以及动画的特性,在JPEG和PNG上的转化效果都非常优秀、稳定和统一。
css 和 js 的装载与执行
先用一张图来理解html页面加载渲染的过程:
html渲染过程中有以下特点:
顺序执行、并发加载
(1)词法分析 (2)并发加载 (3)并发上限
是否阻塞
- css阻塞:(1)css head中阻塞页面的渲染 (2)css阻塞js的执行 (3)css不阻塞外部脚本的加载
- js阻塞:(1)直接引入的js阻塞页面的渲染 (2)js不阻塞资源的加载 (3)js顺序执行,阻塞后续js逻辑的执行
依赖关系
引入方式
懒加载与预加载
懒加载
- 图片进入可视区域之后请求资源
- 对于电商等图片很多,页面很长的业务场景适用
- 减少无效资源的加载
- 并发加载的资源过多会阻塞js的加载,影响网站的正常使用
预加载
- 图片等静态资源在使用之前的提前请求
- 资源使用到时能从缓存中加载,提升用户体验
- 页面展示的依赖关系维护
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。