深度讲解:web前端性能优化

栏目: CSS · 发布时间: 6年前

内容简介:jpg有损压缩:虽然损失一些信息,但是肉眼可见影响并不大png32是在png24上支持了透明,针对不同的业务场景选择不同的图片格式很重要直接通过script src在head中引入,html parse 认为js会动态修改文档结构,没有进行后面文档的分析

课程目标

  • 理解 减少http请求数量减少请求资源大小 两个优化要点
  • 掌握压缩与合并的原理
  • 掌握通过 在线网站fis3 两种实现压缩与合并的方法 ####浏览器的一个请求从发送到返回都经历了什么 动态的加载静态的资源
深度讲解:web前端性能优化
1、dns是否可以通过缓存减少dns查询时间
2、 网络请求的过程走最近的网络环境
3、 相同的静态资源是否可以缓存
4、 能否减少http请求大小
5、 能否减少http请求数量
6、 服务端渲染
复制代码

2、html压缩

资源的合并与压缩设计到的性能点:

1、减少http请求的数量
2、减少请求的大小
复制代码

google首页案例分析

1、html压缩
2、css压缩
3、js的压缩与混乱
4、文件合并
5、 开启gzip
复制代码

如何进行html的压缩

1、使用在线网站进行压缩
2、node.js提供了html-minifier工具
3、后端模板引擎渲染压缩
复制代码

3、css及js压缩

css的压缩

1、无效代码删除
 2、css语义合并
复制代码

css压缩的方式

1、使用在线网站进行压缩
 2、使用html-minifier对html中的css进行压缩
 3、使用clean-css对css进行压缩
复制代码

js的压缩语混乱

1、无效字符的删除
 2、剔除注释
 3、代码语意的缩减和优化
 4、代码保护
复制代码

js压缩的方式

1、使用在线网站进行压缩
2、使用html-minifier对html中的js进行压缩
3、使用uglifyjs2对js进行压缩
复制代码

4、文件合并优点

1、文件与文件有插入之间的上行请求,又增加了N-1个网络延迟
2、受丢包问题影响更严重
3、经过代理服务器时可能会被断开
复制代码

文件合并缺点

1、首屏渲染问题
2、缓存失效问题
复制代码

文件合并对应缺点的处理

1、公共库合并
2、不同页面的合并
3、见机行事,随机应变
复制代码

文件合并对应方法

1、使用在线网站进行合并
2、使用nodejs进行文件合并
复制代码

三、图片相关优化

课程目标

  • 理解图片相关的优化的核心概念
  • 结合facebook和淘宝移动首页案例分析
  • 掌握通过在线网站和fis3两种实现图片相关的一些优化

1、一张JPG的解析过程

深度讲解:web前端性能优化

jpg有损压缩:虽然损失一些信息,但是肉眼可见影响并不大

2、png8/png24/png32之间的区别

深度讲解:web前端性能优化

png32是在png24上支持了透明,针对不同的业务场景选择不同的图片格式很重要

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

不同格式图片的特点

1、jpg有损压缩,压缩率高,不支持透明 
2、png支持透明,浏览器兼容性好
3、webp压缩程度更好	,在ios webview中有兼容性问题
4、svg矢量图,代码内嵌,相对较小,图片样式相对简单的场景(尽量使用,绘制能力有限,图片简单用的比较多)
复制代码

不同格式图片的使用场景

1、jpg:大部分不需要透明图片的业务场景
2、png:大部分需要透明图片的业务场景
3、webp:android全部(解码速度和压缩率高于jpg和png,但是ios safari还没支持)
4、svg:图片样式相对简单的业务场景
复制代码

4、图片压缩的几种情况

1、针对真实图片情况,舍弃一些相对无关紧要的色彩信息
2、CSS雪碧图:把你的网站用到的一些图片整合到一张单独的图片中 
   //优点:减少HTTP请求的数量(通过backgroundPosition定位所需图片)
   //缺点:整合图片比较大时,加载比较慢(如果这张图片没有加载成功,整个页面会失去图片信息)facebook官网任然在用,主要pc用的比较多,相对性能比较强
3、Image-inline:将图片的内容嵌到html中  //base64信息,减少网站的HTTP请求,如果图片比较小比较多,时间损耗主要在请求的骨干网络
4、使用矢量图:使用SVG进行矢量图的绘制,使用icon-font解决icon问题 
5、在android下使用webp:webp的优势主要体现在它具有更优的图像数据压缩算法,能带来更小的图片体积,而且拥有肉眼识别无差异的图像质量;同时具备了无损和有损的压缩模式、Alpha透明以及动画的特性,在JPEG和PNG上的转化效果都非常优秀、稳定和统一
复制代码

四、css和js的装载与执行

课程目标

  • 理解浏览器端html、css、js的装载过程
  • 结合chrome的能力学习掌握css、js加载过程中的优化点
  • 通过案例分析和实战演练深入理解学习的优化点

1、HTML页面加载渲染的过程

一个网站在浏览器端是如何进行渲染的

深度讲解:web前端性能优化

2、HTML渲染过程中的一些特点

  • 顺序执行,并发加载
  • 是否阻塞
  • 依赖关系
  • 引入方式
阻塞的几种方式:
   css的加载是否会阻塞js的加载
   css的加载是否会阻塞js的执行
   css的加载是否会影响页面的渲染
   js的执行是否会阻塞js的执行和js的加载

依赖:
如果我们把css代码放在head中去引入的话,那么我们整个页面的渲染实际上就会等待head中css加载并生成css树,最终和DOM整合生成RanderTree之后才会进行渲染

js async异步加载


引入:
script src引入有相关阻塞页面行为
js资源是否需要动态加载
复制代码

3、顺序执行,并发加载

  • 词法分析
  • 并发加载
  • 并发上限

4、css阻塞和js阻塞

css阻塞

  • css head中阻塞页面的渲染
  • css阻塞js的执行
  • css不阻塞外部脚步的加载
css head中通过 link方式引入,避免页面闪动,因为这样只有等css加载完才会渲染
js的执行很可能要操作DOM
复制代码

js阻塞

  • 直接引入的js阻塞页面的渲染
  • js 不阻塞资源的加载
  • js顺序执行,阻塞后续js的执行

直接通过script src在head中引入,html parse 认为js会动态修改文档结构,没有进行后面文档的分析

五、懒加载与预加载

  • 理解懒加载和预加载的原理
  • 懒加载和预加载的案例分析
  • 懒加载与预加载的案例实战

1、懒加载原理

  • 图片进入可视区域之后请求图片资源
  • 对于电商等图片很多,页面很长的业务场景适用
  • 减少无效资源的加载
  • 并发加载的资源过多会会阻塞js的加载,影响网站的正常使用

img src被设置之后,webkit解析到之后才去请求这个资源。所以我们希望图片到达可视区域之后,img src才会被设置进来,没有到达可视区域前并不现实真正的src,而是类似一个1px的占位符。

2、预加载原理

  • 图片等静态资源在使用之前的提前请求
  • 资源使用到时能从缓存中加载,提升用户体验
  • 页面展示的依赖关系维护

3、懒加载原生js和zepto.lazyload

1、原理:先将img标签中的src链接设为同一张图片(空白图片),将其真正的图片地址存储再img标签的自定义属性中(比如data-src)。当js监听到该图片元素进入可视窗口时,即将自定义属性中的地址存储到src属性中,达到懒加载的效果。

注意问题: 1、关注首屏处理,因为还没滑动 2、占位,图片大小首先需要预设高度,如果没有设置的话,会全部显示出来

深度讲解:web前端性能优化
深度讲解:web前端性能优化

4、预加载原生js和preloadJS实现

预加载实现的几种方式

第一种方式:直接请求下来

<img src="www.pic27.com/sadfafd/dafdsa.jpg" style="display: none"/>
<img src="www.pic27.com/sadfafd/dsaf.jpg" style="display: none"/>
<img src="www.pic27.com/sadfafd/dasfd.jpg" style="display: none"/>
<img src="www.pic27.com/sadfafd/fdsa.jpg" style="display: none"/>
复制代码

第二种方式:image对象

var image = new Image();
image.src = "www.pic26.com/dafdafd/safdas.jpg";
复制代码

第三种方式:xmlhttprequest

深度讲解:web前端性能优化
缺点:存在跨域问题
优点:好控制
复制代码

本质:平衡浏览器加载能力,让它尽可能饱和起来

六、重绘与回流

  • 理解浏览器重绘与回流的机制
  • 对于一些经典的案例进行分析
  • 重绘与回流的案例分析

1、css性能让javascript变慢

要把css相关的外部文件引入放进head中,加载css时,整个页面的渲染是阻塞的,同样的执行javascript代码的时候也是阻塞的,例如javascript死循环。

一个线程   =>  javascript解析
一个线程   =>  UI渲染
复制代码

这两个线程是互斥的,当UI渲染的时候,javascript的代码被终止。当javascript代码执行,UI线程被冻结。所以css的性能让javascript变慢。

频繁触发重绘与回流,会导致UI频繁渲染,最终导致js变慢

2、什么是重绘和回流

回流

  • 当render tree中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建。这就成为回流(reflow)
  • 当页面布局和几何属性改变时,就需要回流

重绘

  • 当render tree中的一些元素需要更新属性,而这些属性只是影响元素的外观,风格,而不影响布局,比如background-color。就称重绘

关系

回流必将引起重绘,但是重绘不一定会引起回流

3、避免重绘、回流的两种方法

触发页面重布局的一些css属性

  • 盒子模型相关属性会触发重布局
width、height、padding、margin、display、border-width、border、min-height
复制代码
  • 定位属性及浮动也会触发重布局
top、bottom、left、right、position、float、clear
复制代码
  • 改变节点内部文字结构也会触发重布局
text-align、overflow-y、font-weight、overflow、font-family、line-height、vertical-align、white-space、font-size
复制代码

优化点:使用不触发回流的方案替代触发回流的方案

只触发重绘不触发回流

color、
border-style、border-radius、
visibility、
text-decoration、
background、background-image、background-position、background-repeat、background-size、
outline、outline-color、outline-style、outline-width
box-shadow
复制代码

新建DOM的过程

1、获取DOM后分割为多个图层
2、对每个图层的节点计算样式结果(Recalculate style 样式重计算)
3、为每个节点生成图形和位置(Layout 回流和重布局)
4、将每个节点绘制填充到图层位图中(Paint Setup和Paint  重绘)
5、图层作为纹理上传至gpu
6、符合多个图层到页面上生成最终屏幕图像(Composite Layers 图层重组)
复制代码

chrome创建图层的条件

将频繁重绘回流的DOM元素单独作为一个独立图层,那么这个DOM元素的重绘和回流的影响只会在这个图层中

1、3D或透视变换CSS属性(perspective transform)
2、使用加速视频解码的<video>节点
3、拥有3D(webGl)上下文或加速的2D上下文的<canvas>节点
4、混合插件(如Flash)
5、对自己的opacity做css动画或使用一个动画webkit变换的元素
6、拥有加速css过滤器的元素
7、元素有一个包含复合层的后代节点(一个元素拥有一个子元素,该子元素在自己的层里)
8、元素有一个z-index较低且包含一个复合层的兄弟元素(换句话说,就是该元素在复合层上层渲染)
复制代码

gif图

总结

1、避免使用触发回流、重绘的CSS属性 2、将重绘、回流的影响范围限制在单独的图层(layers)之内 3、图层合成过程中消耗很大页面性能,这时候需要平衡考虑重绘回流的性能消耗

4、实战优化点总结

1、用translate替代top属性
2、用opacity代替visibility
//opacity不会触发重绘也不会触发回流,只是改变图层alpha值,但是必须要将这个图片独立出一个图层
//visibility会触发重绘
3、不要一条一条的修改DOM的样式,预先定义好class,然后修改DOM的className
4、把DOM离线后修改,比如:先把DOM给`display:none`(有一次reflow),然后你修改100次,然后再把它显示出来
5、不要把DOM节点的属性值放在一个循环里当成循环的变量
6、不要使用table布局,可能很小的一个小改动会造成整个table的重新布局
//div只会影响后续样式的布局
7、动画实现的速度的选择
//根据performance量化性能优化
8、对于动画新建图层
9、启用gpu硬件加速(并行运算),gpu加速意味着数据需要从cpu走总线到gpu传输,需要考虑传输损耗
//transform:translateZ(0)
//transform:translate#d(0)
复制代码

七、浏览器存储

  • 链接localstorage、cookie、sessionstorage、indexedDB的概念和使用
  • 学习理解pwa和service worker的应用
  • 案例分析和实战

1、cookies

多种浏览器存储方式并存,如何选择?

深度讲解:web前端性能优化
1、因为http请求无状态,所以需要cookie去维持客户端状态
2、cookie的生成方式:1.http  response  header set-cookie
				   2.js中可以通过document.cookie可以读写cookie
3、cookie的使用用处:1.用于浏览器端和服务器端的交互(用户状态)
				   2.客户端自身数据的存储			
4、expire:过期时间
5、cookie的限制:1.作为浏览器存储,大小4kb左右
				2.需要设置过期时间 expire	 
6、重要属性:httponly 不支持js读写(防止收到模拟请求攻击)	
7、不太作为存储方案而是用于维护客户关系
8、优化点:cookie中在相关域名下面-cdn的流量损耗 
         解决方案:cdn的域名和主站域名要分开			  
复制代码

2、localStorage

localstorage

  • 1、HTML5设计出来专门用于浏览器存储的
  • 2、大小为5M左右
  • 3、仅在客户端使用,不和服务端进行通信
  • 4、接口封装较好
  • 5、浏览器本地缓存方案

sessionstorage

  • 会话级别的浏览器存储
  • 大小为5M左右
  • 仅在客户端使用,不和服务器端进行通信
  • 接口封装较好
  • 对于表单信息的维护

3、indexedDB

  • IndexedDB是一种低级API,用于客户端存储大量结构化数据。该API使用索引来实现对该数据的高性能搜索。虽然Web Storage对于存储叫少量的数据很管用,但对于存储更大量的结构化数据来说,这种方法不太有用。IndexedDB提供了一个解决方案。
  • 为应用创建离线版本。
cdn域名不要带cookie
localstorage存库、图片
复制代码

4、Service Worker产生的意义

5、PWA与Service Worker

PWA(Progressive Web Apps)是一种Web App新模型,并不是具体指某一种前言的技术或者某一个单一的知识点,我们从英文缩写来看就能看出来,这是一个渐进式的Web App,是通过一系列新的Web特性,配合优秀的UI交互设计,逐步增强Web App的用户体验

6、PWA与Service worker

chrome 插件 lighthouse

检测是不是一个渐进式web app
1、当前手机在弱网环境下能不能加载出来
2、离线环境下能不能加载出来
...
复制代码
1、可靠:没有网络的环境中也能提供基本的页面访问,而不会出现“未连接到互联网”的页面
2、快速:针对网页渲染及网络数据访问有较好的优化
3、融入(Engaging):应用可以被增加到手机桌面,并且和普通应用一样有全屏、推送等特性
复制代码

####service worker

service worker是一个脚本,浏览器独立于当前页面,将其在后台运行,为实现一些不依赖页面的或者用户交互的特性打开了一扇大门。在未来这些特性将包括消息推送,背景后台同步,geofencing(地理围栏定位),但他将推出的第一个首要的特性,就是拦截和处理网络请求的能力,包括以编程方式来管理被缓存的响应。
复制代码
深度讲解:web前端性能优化

案例分析

chrome://serviceworker-internals/
chrome://inspect/#service-worker/
复制代码

service worker网络拦截能力,存储Cache Storage,实现离线应用

indexedDB

深度讲解:web前端性能优化
callback && callback()写法
相当于 
if(callback){
   callback();
}
复制代码

7、cookie、session、localStorage、sessionStorage基本操作

8、indexedDB基本操作

object store:对象存储
本身就是结构化存储
复制代码
function openDB(name, callback) {
            //建立打开indexdb  indexedDB.open
            var request = window.indexedDB.open(name)
            request.onerror = function(e) {
                console.log('on indexedDB error')
            }
            request.onsuccess = function(e) {
                    myDB.db = e.target.result
                    callback && callback()
                }
                //from no database to first version,first version to second version...
            request.onupgradeneeded = function() {
                console.log('created')
                var store = request.result.createObjectStore('books', {
                    keyPath: 'isbn'
                })
                console.log(store)
                var titleIndex = store.createIndex('by_title', 'title', {
                    unique: true
                })
                var authorIndex = store.createIndex('by_author', 'author')

                store.put({
                    title: 'quarry memories',
                    author: 'fred',
                    isbn: 123456
                })
                store.put({
                    title: 'dafd memories',
                    author: 'frdfaded',
                    isbn: 12345
                })
                store.put({
                    title: 'dafd medafdadmories',
                    author: 'frdfdsafdafded',
                    isbn: 12345434
                })
            }
        }
        var myDB = {
            name: 'tesDB',
            version: '2.0.1',
            db: null
        }

        function addData(db, storeName) {

        }

        openDB(myDB.name, function() {
            // myDB.db = e.target.result
            // window.indexedDB.deleteDatabase(myDB.name)
        });

        //删除indexedDB
复制代码

9、indexDB事务

transcation 与  object store建立关联关系来操作object store
建立之初可以配置
复制代码
var transcation = db.transcation('books', 'readwrite')
 var store = transcation.objectStore('books')

 var data =store.get(34314)
 store.delete(2334)
 store.add({
     title: 'dafd medafdadmories',
     author: 'frdfdsafdafded',
     isbn: 12345434
 })

复制代码

10、Service Worker离线应用

serviceworker需要https协议

11、如何实现ServiceWorker与主页面之间的通信

详细学习 https://lavas.baidu.com/guide/v1/foundation/lavas-start

八、缓存

期望大规模数据能自动化缓存,而不是手动进行缓存,需要浏览器端和服务器端协商一种缓存机制

  • 理解Cache-Control所控制的缓存策略
  • 学习理解last-modified 和 etage以及整个服务端浏览器端的缓存流程
  • 案例分析和实战,基于node实践以上缓存方式

1、httpheader

可缓存性

1、 public:表明响应可以被任何对象(包括:发送请求的客户端,代理服务器,等等)缓存。
2、 private:表明响应只能被单个用户缓存,不能作为共享缓存(即代理服务器不能缓存它)。
3、 no-cache:强制所有缓存了该响应的缓存用户,在使用已存储的缓存数据前,发送带验证器的请求到原始服务器
4、 only-if-cached:表明如果缓存存在,只使用缓存,无论原始服务器数据是否有更新
复制代码

到期

1、 max-age=<seconds>:设置缓存存储的最大周期,超过这个时间缓存被认为过期(单位秒)。与     Expires相反,时间是相对于请求的时间。
2、 s-maxage=<seconds>:覆盖max-age 或者 Expires 头,但是仅适用于共享缓存(比如各个代理),并且私有缓存中它被忽略。cdn缓存
3、 max-stale[=<seconds>]
表明客户端愿意接收一个已经过期的资源。 可选的设置一个时间(单位秒),表示响应不能超过的过时时间。
4、 min-fresh=<seconds>
表示客户端希望在指定的时间内获取最新的响应。
复制代码

重新验证和重新加载

1、must-revalidate:缓存必须在使用之前验证旧资源的状态,并且不可使用过期资源。
2、proxy-revalidate:与must-revalidate作用相同,但它仅适用于共享缓存(例如代理),并被私有缓存忽略。
3、immutable :表示响应正文不会随时间而改变。资源(如果未过期)在服务器上不发生改变,因此客户端不应发送重新验证请求头(例如If-None-Match或If-Modified-Since)来检查更新,即使用户显式地刷新页面。在Firefox中,immutable只能被用在 https:// transactions. 
复制代码
1、no-store:缓存不应存储有关客户端请求或服务器响应的任何内容。
2、no-transform:不得对资源进行转换或转变。Content-Encoding, Content-Range, Content-Type等HTTP头不能由代理修改。例如,非透明代理可以对图像格式进行转换,以便节省缓存空间或者减少缓慢链路上的流量。 no-transform指令不允许这样做。
复制代码

2、Expires

Expires

1、缓存过期时间,用来指定资源到期的时间,是服务器端的时间点
2、告诉浏览器在过期时间前浏览器可以直接从浏览器缓存中存取数据,而无需再次请求
复制代码
1、expires是http1.0的时候的
2、http1.1时候,我们希望cache的管理统一进行,max-age优先级高于expires,当有max-age在的时候expires可能就会被忽略。
3、如果没有设置cache-control时候会使用expires
复制代码

3、Last-modified和If-Modified-since

1、基于客户端和服务器端协商的缓存机制
2、 last-modified          -->      response header
    if-modified-since      -->      request header
3、需要与cache-control共同使用
复制代码
304:
200:
复制代码

last-modified有什么缺点

1、某些服务端不能获取精确的修改时间
2、文件修改时间改了,但文件的内容却没有变
复制代码

4、Etag 和 If-none-match

1、文件内容的hash值
2、etag            -->reponse header
   if-none-match   -->request header
3、需要与cache-control共同使用
复制代码

好处:

比if-modified-since更加准确
优先级比etage更高
复制代码
深度讲解:web前端性能优化

4、流程图

深度讲解:web前端性能优化
深度讲解:web前端性能优化

九、服务端性能优化

服务端用的node.js因为和前端用的同一种语言,可以利用服务端运算能力来进行相关的运算而减少前端的运算

课程目标

  • 理解vue渲染遇到的问题
  • 学习理解vue-ssr和原理和引用
  • 按理分析和实战

vue渲染面临的问题

先加载vue.js
=>  执行vue.js代码
=>  生成html
复制代码
以前没有前端框架时,
用jsp/php`在服务端进行数据的填充`,发送给客户端就是已经`填充好数据`的html
复制代码
使用jQuery异步加载数据
使用React和Vue前端框架
复制代码

怎么在vue这个层面对性能进行提升

1、构建层的模板编译(runtime,compile拆开),构建层做模板编译工作。webpack构建时候,统一,直接编译成runtime可以执行的代码 

2、数据无关的prerender的方式

3、服务端渲染
复制代码
深度讲解:web前端性能优化

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

疯狂Java讲义

疯狂Java讲义

李刚 / 电子工业出版社 / 2008-10 / 99.00元

《疯狂Java讲义》2000年至今,Java语言一直是应用最广的开发语言,并拥有最广泛的开发人群。如今,Java已经不再简单地是一门语言,它更像一个完整的体系,一个系统的开发平台。更甚至,它被延伸成一种开源精神。 《疯狂Java讲义》深入介绍了Java编程的相关方面,全书内容覆盖了Java的基本语法结构、Java的面向对象特征、Java集合框架体系、Java泛型、异常处理、Java GUI编......一起来看看 《疯狂Java讲义》 这本书的介绍吧!

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试