前端性能优化1:静态资源压缩与优化

在大前端时代的今天,前端需要做的事情绝不仅仅是实现页面需求,完成页面开发任务。尤其是对于大项目来说,性能优化是一个非常重要,也非常体现前端能力的一个领域,但是前端性能是一个非常严肃的事情,一定要对其有系统的理解,不能去盲目的优化,否则会得不偿失。
本文是一个系列课程,从原理出发,分为基础优化(1,2章)、进阶优化(3,4,5,6章)、结合服务端的优化(7章)三大部分,一共7章,章名罗列如下:

  • 一、资源合并与压缩-http 清求的过程及潜在的性能优化点
  • 二、图片相关的优化- 一张JPG图片的解析过程

因为篇幅问题,以下几章的内容会出现在后续文章中

  • 三、css和js的装载与执行-HTML 页面加载渲染的过程
  • 四、懒加载与预加载-懒加载、预加载使用场景
  • 五、重绘与回流- 实战演练
  • 六、浏览器存储-PWA与Service Workers
  • 七、缓存

一、资源合并与压缩-http 清求的过程及潜在的性能优化点

本章目录:

  • 1.html压缩
  • 2.css压缩
  • 3.Js压缩与混乱
  • 4.文件合并
  • 5.eleme首页实战

首先需要了解浏览器的一个请求从发送到返回都经历了什么?
从过程中就发现一些可以优化的点


过程示意图.png

从请求过程中,我们寻找到了一些潜在的性能优化点:

  • dns是否可以通过缓存减少dns查询时间?
  • 网络请求的过程走最近的网络环境?
  • 相同的静态资源是否可以缓存?
  • 能否减少请求http请求大小?
  • 减少http请求
  • 服务端渲染

注意:深入理解http请求的过程是前端性能优化的核心

很多网站采用cdn去加速静态资源的加载,但是静态资源的加载都不需要携带cookie,所有cdn的域名最好设置的和普通的域名不一样,以便去进行识别,当请求cdn的时候不去携带cookie,减少http请求的体积。

资源的合并与压缩的两个思路:

  • 减少http请求数量(合并)
  • 减少请求资源的大小(压缩)

1.html压缩

HTML的全称是超文本标记语言,HTML网页本身是一种文本文件,通过在文件中添加标记符,可以告诉浏览器如何显示其中的内容,包括文字大小,颜色,图片显示等等。这就意味着在文本文件中的一些特定意义的字符可以在浏览器显示的时候就不一样了,HTML代码压缩就是压缩这些在文本文件中有意义,但是在HTML中不显示的字符,包括空格,制表符,换行符等,还有一些其他意义的字符,如HTML注释也可以被压缩。

如何进行html压缩

  • 1.使用在线网站进行压缩,这种方式在现代化的前端工程中几乎不会再去使用
  • 2.nodejs提供了html-minifier工具(构建层面的压缩)
  • 3.后端模板引擎渲染压缩(服务端层面的压缩)

2.css压缩

压缩css代码就是将无效的样式代码删除,将相同语义的css代码进行合并

如何进行css压缩

  • 1.使用在线网站进行压缩
  • 2.使用html-minifier对html中的css进行压缩
  • 3.使用clean-css对css进行压缩

3.Js压缩与混乱

Js压缩与混乱的意义

  • 无效字符的删除
  • 剔除注释
  • 代码语义的缩减和优化
  • 代码保护(这点非常重要,可以防止别人窃取自己的代码逻辑,也让js代码压缩成为最重要的一个环节)

对于大多数公司,HTML压缩可有可无,但是css和js压缩是必须要做的

如何进行js压缩和混乱:

  • 1.使用在线网站进行压缩
  • 2.使用html-minifier对html中的js进行压缩
  • 3.使用uglifyjs2对js进行压缩

4.文件合并

不进行文件合并存在的问题

  • 文件与文件之间有插入的上行请求,增加了N-1个网络延迟
  • 受丢包问题影响也更严重,每一次网络请求都可能会存在丢包的情况
  • 经过代理服务器时可能会被断开

但是也不是说合并文件就是万能的,文件合并存在的问题:

  • 首屏渲染问题,文件合并必然会增大文件的体积,如果页面的显示依赖于某个文件,但是这个文件因为体积太大迟迟加载不加来,必须会增加页面的白屏时间。这个问题在使用vue或者react之类的前端框架的时候尤为严重。
  • 缓存失效问题,如果一个合并后的js文件abc.js是由a.js和b.js和c.js合并形成的,那这三个文件的其中一个发生改变都必然会导致abc.js文件缓存的失效。

处理文件合并引发的副作用,可以进行以下操作

  • 1.将公共库单独打包成一个文件,因为在实际项目开发中,公共库往往是很少改变的
  • 2.对于单页面应用,我们肯定也希望当其中某个组件被用到的时候,组件代码才会被加载,而不是一定要等到所有的代码都加载完成才去显示首页,所以我们需要将不同页面的代码分开打包(实现方式:异步加载组件)
  • 3.见机行事,随机应变

如何进行文件合并:

  • 使用在线网站进行文件合并
  • 使用nodejs实现文件合并(基于常见的gulp或者webpack进行配置,如在webpack中,配置好entry和output,webpack自带的机制就会去自动根据文件之间的依赖关系进行打包)

接下来我们根据非常简单,容易上手fis3进行资源合并与压缩的实战讲解。

5.eleme首页实战

首页代码示意图.png

因为没有使用webpack,fis等构建工具,代码的的管理有以下问题:
1.代码没法从ES6自动转换到ES5
2.js代码只能通过script进行引入(命名空间污染,引入必须按照依赖顺序)

接下来我们把这个项目部署到带宽上线为1M的云服务器,首次加载,资源请求事件如下:


资源加载图.png

如图所示,11个请求,大小是610KB,一共用了2.9s的时间

利用如https://tool.oschina.net/jscompress
的在线工具手动压缩和合并js代码后(需要注意一点,在线压缩代码工具一般都不支持压缩es6代码,因为手动压缩代码本来就只是传统的代码处理方式),加载时间如下:

压缩后的加载时间.png

可以看到,就算只是手动的压缩和合并一下代码,带来的加载时间的收益都是如此的明显。

接下来我们使用自动化构建工具fis3进行优化
首先在项目的根目录中新建一个fis-conf.js文件,fis通过fis-match去定义规则,接下来在命令行工具中执行fis3 release -cd output将代码打包编译进output文件夹下,再次对比首页资源加载时间后发现加载时间和我们手动压缩的效果是一样的,当然了,好处就是我们成功实现了自动化。

二、图片相关的优化- 一张JPG图片的解析过程

所有的图片类型在对原始图像数据进行处理的时候都会进行压缩处理,jpg是一种典型的有损压缩,只是在压缩过程中丢弃的是一些不是那么紧要的图像数据,和原始数据比起来,呈现出来的显示效果肉眼难辨。

png8/png24/png32之间的区别
png格式除了携带有原始图像数据,还会建立一个自己的图片数据索引,这个索引就指向了自身所有的所有颜色。

  • png8 —— 256色(2^8) + 支持透明
  • png24 —— 2^24色 + 不支持透明,相同的图片,转换成png24的大小是转换成png8的三倍
  • png32 —— 2^24色 + 支持透明

每种图片格式都有自己的特点,针对不同的业务场景选择不同的图片格式很重要

不同格式图片常用的业务场景

  • jpg有损压缩,压缩率高,不支持透明,适合大部分不需要透明图片的业务场景,jpg相对于png来说,图片会更小
  • png支持透明,浏览器兼容好,有png8以及24和32可以选择,在使用过程中可以进行降阶选择,适合大部分需要透明图片的业务场景,在实际项目中,png的使用频率要比jpg高,最大的原因就是png支持透明。
  • webp压缩程度更好,在ios webview有兼容性问题,在只考虑安卓场景时进行使用,缺点就是兼容性问题,但是解码速率以及压缩率确定高。
  • svg矢量图,代码内嵌,相对较小,图片样式相对简单的场景,适合图片样式相对简单的业务场景,在实际项目中,尤其是简单的图片场景,推荐优先考虑使用svg,因为这种方式让图片内嵌在html中,不需要加载更多资源,同时iconfont等字体图标网站也让svg的使用变得非常方便。
  • 另外还有一种图片格式gif,如果需要使用动图,则需要选择这种格式。

进行图片压缩
针对真实图片情况,舍弃一些相对无关紧要的色彩信息
所以:图片越简单,被压缩之后的体积就越小

CSS雪碧图
把你的网站上用到的一些图片整合到一张单独的图片中
最大的优点就是减少你的网站的HTTP请求数量
但是在实际项目中,雪碧图的使用已经越来越小, 因为当整合图片比较大时,一次加载会比较慢,如果这张整合图片的加载失败了,那后果更惨,所有用到这种图片的位置都会无法正常显示。同时其他图片使用技术(如svg,Image inline等)的强制发展,让雪碧图的发展受限严重,目前使用雪碧图的网站基本都是pc端网站。

Image inline
将图片的内容内嵌到html当中
减少你的网站的HTTP请求数量
方式:将图片转换成base64格式
尤其是网站上的一些非常小的图片,将其转换成base64内嵌到html中显得优势十足。

使用矢量图
使用SVG进行矢量图的绘制
使用iconfont解决icon问题
这种方式和Image inline,也不需要让图片再去经过http请求才能拿到了。

在安卓下使用webp
WebP 的优势体现在它具有更优的图像数据压缩算法,能带来更小的图片体积,而且拥有肉眼识别无差异的图像质量;同时具备了无损和有损的压缩模式、Alpha 透明以及动画的特性,在 JPEG 和 PNG 上的转化效果都非常优秀、稳定和统一。

实战分析

根据对实际网站的分析,发现facebook的pc端网页使用了雪碧图技术,但是也把不同业务场景的icon进行整合和分割。其他大型的移动端网站暂时没有发现雪碧图的使用场景了。

这里推荐一个可以在线压缩图片并且转换格式和查看压缩率的网站https://zhitu.isux.us/

模板图片.png

另外通过fis3的一些插件可以自动实现将图片转换成webp等格式。

如果项目中使用到了雪碧图,推荐一个网站http://www.spritecow.com/
,这个网站可以快速生成雪碧图代码:

模板图片.png