PWA
Vue-SSR
http
请求的过程及潜在的性能优化点减小http请求数量
和减小请求资源大小
两个优化要点压缩
与合并
的原理在线网站
和fis3
两种实现压缩与合并的方法动态的加载静态的资源javascript
dns
是否能够经过缓存减小dns
查询时间http
请求大小http
请求数量http
请求的数量html
压缩
HTML
代码压缩就是压缩这些在文本文件中有意义,可是在HTML
中不显示的字符,包括空格
,制表符
,换行符
等,还有一些其余意义的字符,如HTML
注释也能够被压缩php
意义css
html
的压缩node.js
提供了html-minifier
工具模板引擎渲染压缩
css
及js
压缩css
的压缩css
语义合并css
压缩的方式html-minifier
对html
中的css
进行压缩clean-css
对css
进行压缩js
的压缩与混乱a
,b
)等js
压缩的方式html-minifier
对html
中的js
进行压缩uglifyjs2
对js
进行压缩N-1
个网络延迟js
变大,若是首页的渲染依赖这个js
的话,整个页面的渲染要等js
请求完才能执行a.js
,只要等a.js
完成后就可执行js
js
md5
戳js
,任何一个改动都会致使大面积的缓存失效js
单独打包nodejs
进行文件合并JPG
的解析过程jpg
有损压缩:虽然损失一些信息,可是肉眼可见影响并不大
png8
/png24
/png32
之间的区别png8
----256色
+ 支持透明png24
----2^24
+ 不支持透明png32
---2^24
+支持透明文件大小
+ 色彩丰富程度
html
png32
是在png24
上支持了透明,针对不一样的业务场景选择不一样的图片格式很重要前端
jpg
有损压缩,压缩率高,不支持透明png
支持透明,浏览器兼容性好webp
压缩程度更好,在ios webview
中有兼容性问题svg
矢量图,代码内嵌,相对较小,图片样式相对简单的场景(尽可能使用,绘制能力有限,图片简单用的比较多)jpg
:大部分不须要透明图片的业务场景png
:大部分须要透明图片的业务场景webp
:android
所有(解码速度和压缩率高于jpg
和png
,可是ios
safari
还没支持)svg
:图片样式相对简单的业务场景针对真实图片状况,舍弃一些相对可有可无的色彩信息vue
CSS雪碧图
:把你的网站用到的一些图片整合到一张单独的图片中java
HTTP
请求的数量(经过backgroundPosition
定位所需图片)facebook
官网任然在用,主要pc
用的比较多,相对性能比较强Image-inline
:将图片的内容嵌到html
中(减小网站的HTTP
请求)node
base64信息
,减小网站的HTTP请求,若是图片比较小比较多,时间损耗主要在请求的骨干网络使用矢量图
android
SVG
进行矢量图的绘制icon-font
解决icon
问题在android下使用webp
webpack
webp
的优点主要体如今它具备更优的图像数据压缩算法,能带来更小的图片体积,并且拥有肉眼识别无差别的图像质量;Alpha
透明以及动画的特性,在JPEG
和PNG
上的转化效果都很是优秀、稳定和统一css
和js
的装载与执行HTML
生成Token对象
(当前节点的全部子节点生成后,才会经过next token
获取到当前节点的兄弟节点),最终生成Dom Tree
Chrome
为例,并发上限为6个css
阻塞
css
在head
中经过link
引入会阻塞页面的渲染
css
代码放在head
中去引入的话,那么咱们整个页面的渲染实际上就会等待head
中css
加载并生成css树
,最终和DOM
整合生成RanderTree
以后才会进行渲染css
不阻塞js
的加载,但阻塞js
的执行css
不阻塞外部脚步的加载(webkit preloader 预资源加载器
)js
阻塞
<script src>
引入会阻塞后面节点的渲染
html parse
认为js
会动态修改文档结构(document.write
等方式),没有进行后面文档的变化async
、defer
(async
放弃了依赖关系)
defer
属性(<script src="" defer></script>
) (这是延迟执行引入的js
脚本(即脚本加载是不会致使解析中止,等到document
所有解析完毕后,defer-script
也加载完毕后,在执行全部的defer-script
加载的js
代码,再触发Domcontentloaded
)
async
属性(<script src="" async></script>
)
js
脚本文件defer
的区别是async
会在加载完成后就执行,可是不会影响阻塞到解析和渲染。可是仍是会阻塞load
事件,因此async-script
会可能在DOMcontentloaded
触发前或后执行,可是必定会在load
事件前触发。img src
被设置以后,webkit
解析到以后才去请求这个资源。因此咱们但愿图片到达可视区域以后,img src
才会被设置进来,没有到达可视区域前并不现实真正的src
,而是相似一个1px
的占位符。
场景:电商图片
场景:抽奖
js
和zepto.lazyload
原理
先将img
标签中的src
连接设为同一张图片(空白图片),将其真正的图片地址存储再img
标签的自定义属性中(好比data-src
)。当js
监听到该图片元素进入可视窗口时,即将自定义属性中的地址存储到src
属性中,达到懒加载的效果。
注意问题:
var viewheight = document.documentElement.clientHeight //可视区域高度
function lazyload(){
var eles = document.querySelectorAll('img[data-original][lazyload]')
Array.prototype.forEach.call(eles,function(item,index){
var rect;
if(item.dataset.original === '') return;
rect = item.getBoundingClientRect(); //返回元素的大小及其相对于视口的
if(rect.bottom >= 0 && rect.top < viewheight){
!function(){
var img = new Image();
img.src = item.dataset.url;
img.onload = function(){
item.src = img.src
}
item.removeAttribute('data-original');
item.removeAttribute('lazyload');
}()
}
})
}
lazyload()
document.addEventListener('scroll',lazyload)
复制代码
js
和preloadJS
实现<img src="https://user-gold-cdn.xitu.io/2019/2/21/1690d1b216cbfa18" style="display: none"/>
<img src="https://user-gold-cdn.xitu.io/2019/2/21/1690d1b21b70c8d2" style="display: none"/>
<img src="https://user-gold-cdn.xitu.io/2019/2/21/1690d1b216e17e26" style="display: none"/>
<img src="https://user-gold-cdn.xitu.io/2019/2/21/1690d1b217b3ae59" style="display: none"/>
复制代码
image
对象var image = new Image();
image.src = "www.pic26.com/dafdafd/safdas.jpg";
复制代码
xmlhttprequest
var xmlhttprequest = new XMLHttpRequest();
xmlhttprequest.onreadystatechange = callback;
xmlhttprequest.onprogress = progressCallback;
xmlhttprequest.open("GET","http:www.xxx.com",true);
xmlhttprequest.send();
function callback(){
if(xmlhttprequest.readyState == 4 && xmlhttprequest.status == 200){
var responseText = xmlhttprequest.responseText;
}else{
console.log("Request was unsuccessful:" + xmlhttprequest.status);
}
}
function progressCallback(){
e = e || event;
if(e.lengthComputable){
console.log("Received"+e.loaded+"of"+e.total+"bytes")
}
}
复制代码
PreloadJS模块
css
性能让javascript
变慢要把css
相关的外部文件引入放进head
中,加载css
时,整个页面的渲染是阻塞的,一样的执行javascript
代码的时候也是阻塞的,例如javascript
死循环。
一个线程 => javascript解析
一个线程 => UI渲染
复制代码
这两个线程是互斥的,当UI
渲染的时候,javascript
的代码被终止。当javascript
代码执行,UI
线程被冻结。因此css
的性能让javascript
变慢。
频繁触发重绘与回流,会致使UI频繁渲染,最终致使js变慢
render tree
中的一部分(或所有)由于元素的规模尺寸
,布局
,隐藏
等改变而须要从新构建
。这就成为回流(reflow
)页面布
局和几何属性
改变时,就须要回流
render tree
中的一些元素须要更新属性,而这些属性只是影响元素的外观
,风格
,而不影响布局,好比background-color
。就称重绘用到chrome
分析 performance
回流必将引发重绘,可是重绘不必定会引发回流
盒子模型相关属性会触发重布局
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
后分割为多个图层Recalculate style
样式重计算)Layout
回流和重布局)Paint Setup
和Paint
重绘
)gpu
Composite Layers
图层重组)DOM
的过程是这样子的:layer
),将每一个层独立地绘制进位图(bitmap
)中texture
)上传至 GPU
,复合(composite
)多个层来生成最终的屏幕图像left/top/margin
之类的属性会影响到元素在文档中的布局,当对布局(layout
)进行动画时,该元素的布局改变可能会影响到其余元素在文档中的位置,就致使了全部被影响到的元素都要进行从新布局,浏览器须要为整个层进行重绘并从新上传到 GPU
,形成了极大的性能开销。transform
属于合成属性(composite property
),对合成属性进行 transition/animation
动画将会建立一个合成层(composite layer
),这使得被动画元素在一个独立的层中进行动画。texture
)上传到 GPU
,只要该层的内容不发生改变,就不必进行重绘(repaint
),浏览器会经过从新复合(recomposite
)来造成一个新的帧。chrome
建立图层的条件将频繁重绘回流的DOM元素单独做为一个独立图层,那么这个DOM元素的重绘和回流的影响只会在这个图层中
3D
或透视变换CSS
属性使用加速视频解码的 <video>
元素3D
(WebGL
) 上下文或加速的 2D
上下文的 <canvas>
元素Flash
)opacity/transform
动画的元素拥有加速CSS filters
的元素元素有一个包含复合层的后代节点(换句话说,就是一个元素拥有一个子元素,该子元素在本身的层里)z-index
较低且包含一个复合层的兄弟元素(换句话说就是该元素在复合层上面渲染)总结:对布局属性进行动画,浏览器须要为每一帧进行重绘并上传到
GPU
中对合成属性进行动画,浏览器会为元素建立一个独立的复合层,当元素内容没有发生改变,该层就不会被重绘,浏览器会经过从新复合来建立动画帧
gif图
回流
、重绘
的CSS
属性重绘
、回流
的影响范围限制在单独的图层(layers
)以内用translate
替代top
属性
top
会触发layout
,但translate
不会用opacity
代替visibility
opacity
不会触发重绘也不会触发回流,只是改变图层alpha
值,可是必需要将这个图片独立出一个图层visibility
会触发重绘不要一条一条的修改DOM
的样式,预先定义好class
,而后修改DOM
的className
把DOM
离线后修改,好比:先把DOM
给display:none
(有一次reflow
),而后你修改100次,而后再把它显示出来
不要把DOM
节点的属性值放在一个循环里当成循环的变量
offsetHeight
、offsetWidth
每次都要刷新缓冲区,缓冲机制被破坏不要使用table
布局,可能很小的一个小改动会形成整个table
的从新布局
div
只会影响后续样式的布局动画实现的速度的选择
performance
量化性能优化对于动画新建图层
gpu
硬件加速(并行运算),gpu加速
意味着数据须要从cpu
走总线到gpu
传输,须要考虑传输损耗.
transform:translateZ(0)
transform:translate3D(0)
cookies
http
请求无状态,因此须要cookie
去维持客户端状态cookie
的生成方式:
http
-->response header
-->set-cookie
js
中能够经过document.cookie
能够读写cookie
cookie
的使用用处:
expire
:过时时间cookie
的限制:
4kb
左右expire
httponly
不支持js
读写(防止收到模拟请求攻击)cookie
中在相关域名下面
cdn
的流量损耗cdn
的域名和主站域名要分开localStorage
localstorage
HTML5
设计出来专门用于浏览器存储的5M
左右sessionstorage
5M
左右indexedDB
IndexedDB
是一种低级API
,用于客户端存储大量结构化数据。该API
使用索引来实现对该数据的高性能搜索。虽然Web
Storage
对于存储叫少许的数据很管用,但对于存储更大量的结构化数据来讲,这种方法不太有用。IndexedDB
提供了一个解决方案。为应用建立离线版本
cdn
域名不要带cookie
localstorage
存库、图片cookie
种在主站下,二级域名也会携带这个域名,形成流量的浪费
Service Worker
产生的意义PWA
与Service Worker
PWA
(Progressive Web Apps
)是一种Web App
新模型,并非具体指某一种前言的技术或者某一个单一的知识点,咱们从英文缩写来看就能看出来,这是一个渐进式的Web App
,是经过一系列新的Web特性
,配合优秀的UI
交互设计,逐步加强Web App
的用户体验PWA
与Service worker
chrome
插件 lighthouse
检测是否是一个渐进式
web app
特色
Engaging
):应用能够被增长到手机桌面,而且和普通应用同样有全屏、推送等特性service worker
service worker
是一个脚本,浏览器独立于当前页面,将其在后台运行,为实现一些不依赖页面的或者用户交互的特性打开了一扇大门。在将来这些特性将包括消息推送,背景后台同步,geofencing
(地理围栏定位),但他将推出的第一个首要的特性,就是拦截和处理网络请求的能力,包括以编程方式来管理被缓存的响应。
chrome://serviceworker-internals/
chrome://inspect/#service-worker/
service worker
网络拦截能力,存储Cache Storage
,实现离线应用
indexedDB
callback && callback()写法
至关于
if(callback){
callback();
}
复制代码
cookie
、session
、localStorage
、sessionStorage
基本操做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
复制代码
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
})
复制代码
Service Worker
离线应用serviceworker
须要https
协议
ServiceWorker
与主页面之间的通讯指望大规模数据能自动化缓存,而不是手动进行缓存,须要浏览器端和服务器端协商一种缓存机制
- Cache-Control所控制的缓存策略
- last-modified 和 etage以及整个服务端浏览器端的缓存流程
- 基于node实践以上缓存方式
httpheader
可缓存性
public
:代表响应能够被任何对象(包括:发送请求的客户端,代理服务器,等等)缓存。private
:代表响应只能被单个用户缓存,不能做为共享缓存(即代理服务器不能缓存它)。no-cache
:强制全部缓存了该响应的缓存用户,在使用已存储的缓存数据前,发送带验证器的请求到原始服务器only-if-cached
:代表若是缓存存在,只使用缓存,不管原始服务器数据是否有更新到期
max-age=<seconds>
:设置缓存存储的最大周期,超过这个时间缓存被认为过时(单位秒)。与 Expires
相反,时间是相对于请求的时间。s-maxage=<seconds>
:覆盖max-age
或者 Expires
头,可是仅适用于共享缓存(好比各个代理),而且私有缓存中它被忽略。cdn
缓存max-stale[=<seconds>]
代表客户端愿意接收一个已通过期的资源。 可选的设置一个时间(单位秒),表示响应不能超过的过期时间。min-fresh=<seconds>
表示客户端但愿在指定的时间内获取最新的响应。从新验证
和从新加载
从新验证
must-revalidate
:缓存必须在使用以前验证旧资源的状态,而且不可以使用过时资源。proxy-revalidate
:与must-revalidate
做用相同,但它仅适用于共享缓存(例如代理),并被私有缓存忽略。immutable
:表示响应正文不会随时间而改变。资源(若是未过时)在服务器上不发生改变,所以客户端不该发送从新验证请求头(例如If-None-Match
或If-Modified-Since
)来检查更新,即便用户显式地刷新页面。在Firefox
中,immutable
只能被用在 https:// transactions
.从新加载
no-store
:缓存不该存储有关客户端请求或服务器响应的任何内容。no-transform
:不得对资源进行转换或转变。Content-Encoding
,Content-Range
, Content-Type
等HTTP
头不能由代理修改。例如,非透明代理能够对图像格式进行转换,以便节省缓存空间或者减小缓慢链路上的流量。 no-transform
指令不容许这样作。Expires
缓存过时时间,用来指定资源到期的时间,是服务器端的时间点
告诉浏览器在过时时间前浏览器能够直接从浏览器缓存中存取数据,而无需再次请求
expires
是http1.0
的时候的
http1.1
时候,咱们希望cache
的管理统一进行,max-age
优先级高于expires
,当有max-age
在的时候expires
可能就会被忽略。
若是没有设置cache-control
时候会使用expires
Last-modified
和If-Modified-since
last-modified
--> response header
if-modified-since
--> request header
cache-control
共同使用
last-modified
有什么缺点?
Etag
和 If-none-match
etag
-->reponse header
if-none-match
-->request header
cache-control
共同使用好处:
if-modified-since
更加准确etage
更高服务端用的node.js由于和前端用的同一种语言,能够利用服务端运算能力来进行相关的运算而减小前端的运算
vue
渲染遇到的问题vue-ssr
和原理和引用先加载vue.js
=> 执行vue.js代码
=> 生成html
复制代码
之前没有前端框架时,
用jsp/php
在服务端进行数据的填充,发送给客户端就是已经
填充好数据`的html
使用jQuery
异步加载数据
使用React
和Vue
前端框架
构建层的模板编译。runtime
,compile
拆开,构建层作模板编译工做。webpack
构建时候,统一,直接编译成runtime
能够执行的代码
数据无关的prerender
的方式
服务端渲染