WEB前端性能优化

请求过程当中一些潜在的性能优化点

深刻理解http请求的过程是前端性能优化的核心! css

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

DNS解析过程

clipboard.png

服务器端请求处理

clipboard.png

HTTP状态码

clipboard.png

注意: html

一、文件合并存在的问题。前端

  • 首屏渲染问题(公共库合并)
  • 缓存失效问题(不一样页面的合并)

二、资源的合并与压缩(html,css,js压缩和混乱,文件合并,开启gzip)。vue

  • 目的1:减小请求http请求大小
  • 目的2:减小http请求数量

图片相关的优化的核心概念

png8/png24/png32之间的区别?ios

  • png8 --- 2^8(256)色 + 支持透明
  • png24 --- 2^24色 + 不支持透明
  • png32 --- 2^24色 + 支持透明

不一样格式图片的特色和经常使用的业务场景?web

  • jpg有损压缩,压缩率高,不支持透明(不须要透明图片的的业务场景)
  • png支持透明,浏览器兼容性好(须要透明图片的业务场景)
  • webp压缩程度更好,在ios webview中有兼容性问题(安卓所有)
  • svg矢量图,代码内嵌,相对较小(图片样式相对简单的场景)

对图片的优化有哪些?canvas

  • 对图片进行压缩png24->png8(可使用:https://tinypng.com/
  • CSS雪碧图(可使用用这个网站生成雪碧图相关的css代码:http://www.spritecow.com
  • Image inline(base64编码)
  • 使用矢量图

css、js加载与执行(考虑优化点)

clipboard.png

HTMLParser解析器自上而下解析,生成DOM树。
外部资源link、script,浏览器会发起请求。
解析CSS生成CSS规则树,进而构建渲染树(计算element位置,布局layout)。
接着调用操做系统NativeGUI的API进行绘制。segmentfault

浏览器渲染页面

clipboard.png

HTML渲染过程的一些特色

  • 顺序执行、并发加载

外部资源并发请求,一个域名下的并发请求数是有上限的。
因此通常将网站的静态资源托管在多个CDN下。跨域

  • css阻塞

css在head中能够阻塞页面渲染、css能够阻塞js执行,可是css不阻塞外部脚本的加载。promise

  • js阻塞

直接引入的js阻塞页面的渲染(asyn[异步下载、当即执行]、differ[并行下载、顺序执行]这两种方式加载js例外)

js不阻塞资源的加载(预资源加载器)

js顺序执行,阻塞后续js逻辑的执行(单线程)

懒加载、预加载

懒加载:图片进入可视区域以后请求图片资源。
懒加载的实现:
1.JS判断图片是否进入可视区域。
2.当进入时,修改img的src属性为实际图片地址。

预加载:图片等静态资源在使用以前提早请求。
预加载实现:
1.使用标签(<img src="xxx" style="display:none">)
2.使用Image对象(new Image();)
3.使用XMLHTTPRequest对象(资源跨域问题)

回流与重绘

UI线程和js线程互斥。
css性能能让JavaScript变慢。
频繁触发重绘回流,会致使UI频繁渲染,最终致使js变慢。

回流: render tree中的一部分(或所有)由于元素的规模尺寸,布局,隐藏等改变而须要从新构建,
这就称为回流(reflow)。

  • 页面渲染初始化
  • 盒子模型相关属性变化
  • 窗口resize事件触发
  • DOM结构变化,好比删除了某个节点
  • 获取某些属性,引起回流 不少浏览器会对回流作优化,他会等到足够数量的变化发生,在作一次批处理回流。 可是除了render树的直接变化。

获取如下属性时会引起回流
width,height
offsetTop/Left/Width/Height
scrollTop/Left/Width/Height
clientTop/Left/Width/Height
调用了getComputedStyle(), 或者 IE的 currentStyle

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

Chrome中知足如下任意状况就会建立图层:

video、canvas都是一个独立的图层。

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

经常使用的会独立为一个图层的属性:
transform:translateZ(0);
will-change:transform;

怎么优化呢?

  • 将频繁重绘回流的DOM元素单独做为一个独立图层,那么这个DOM元素重绘和回流的影响只会在这个图层中。(可是:浏览器图层合成也会花比较多的时间,因此,是否新建图层得看实际状况,具体问题,具体分析。)
  • translate(改变不会触发浏览器从新布局,可是元素仍会占据原始位置)替代top(会触发从新布局)改变。
  • opacity(不会触发重绘)替代visibility(会触发重绘)。
  • 不要一条一条地修改DOM的样式,预先定义好class,而后修改DOM的className
  • 把DOM离线后修改。(eg:先把DOM给display:none,而后修改100次,再把它显示出来。)
  • 不要把DOM节点的属性值放在一个循环里当成循环里的变量(offsetHeight、offsetWidth)
  • 不要使用table布局,一个小的改动会形成整个table的从新布局。
  • 对动画新建图层。
  • 启用GPU硬件加速。(transform:translate3d(0,0,0)、transform:translateZ(0))

浏览器存储

Cookie相关

Cookie 由于HTTP请求无状态,因此须要cookie去维护客户端状态。

cookie的生成方式:

  • 1.http response header中的 set-cookie(服务端生成,客户端保存)
  • 2.js中能够经过document.cookie能够读写cookie(客户端自身数据的存储)

cookie存储的限制:

  • 1.做为浏览器端存储,大小4kb左右
  • 2.须要设置过时时间`expire

对于cookie的优化:

cookie中在相关域名下面--cdn的流量损耗
解决方法:__ cdn的域名和主站的域名要分开 __

对于cookie的读写操做:

// 写入
document.cookie = "username=hello";
// 读取
let cookie = document.cookie;
/**
  * param [String] cookie
  * return [Object] object
  */
function getCookie(cookie){
    if(!cookie){ return null; }
    let reg = /\s*([^;]+)\s*=\s*([^;]+)\s*/g;
    let obj = {};
    cookie.replace(reg,($0,$1,$2) => {
        if($1&&$2){
            obj[$1] = $2;
        }
    });
    return obj;
}

cookie存储数据能力被localstorage替代。
httponly :不容许js读写。(防止盗用cookie)

LocalStorage相关

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

对于LocalStorage的读写操做:

// 写入
localStorage.setItem('username','hello')
undefined
// 读取
localStorage.getItem('username')
"hello"

SessionStorage相关

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

对于 SessionStorage的读写操做:

// 写入
 SessionStorage.setItem('username','hello')
undefined
// 读取
 SessionStorage.getItem('username')
"hello"

IndexedDB(用的比较少)

  • IndexedDB是一种低级API,用于客户端存储大量结构化数据。
  • 为应用建立离线版本

PWA相关

  • 可靠:在没有网络的环境下也能提供基本的页面访问,而不会出现“未链接到互联网”的页面。
  • 快速:针对网页渲染及网络数据访问有较好优化。
  • 融入(Engaging):应用能够被增长到手机桌面,而且和普通应用同样有全屏、推送等特性。

具体内容查看笔记:

ServiceWorker探索
ServiceWorker和cacheStorage缓存及离线开发

利用ServiceWorker进行多页面通讯:

// 主页面发送信息
navigator.serviceWorker.controller.postMessage(value);
// 主页面监听消息
navigator.serviceWorker.addEventListener('message',event => {
    // console.log(event.data);
});

// ServiceWorker接收信息(对其余页面消息分发)
self.addEventListener('message',event => {
    let promise = self.clients.matchAll().then(clientList => {
        let senderID = event.source ? event.source : 'unknown';
        clientList.forEach(client => {
            if(client.id === senderID){
                return;
            }
            client.postMessage({
                client: senderID,
                message: event.data
            });
        });
    });
    event.waitUntil(promise);    
});

浏览器缓存

Cache-Control

clipboard.png

  • max-age 当小于缓存时间时,直接加载本地资源(from memory cache),expires(到期时间http/1.0)和max-age相比,max-age具备更高的优先级。
  • s-maxage 共享缓存,public相关的缓存设备例如CDN,优先级高于max-age,若是客户端访问到的是CDN服务器缓存中的数据切未更改则返回304状态码。(Cache-control:max-age=3600, s-maxage=31536000,就算在max-age时间内,也不直接加载本地文件,而是访问CDN缓存。缓存中的文件若是没有更改,则直接通知客户端304,加载本地文件。感受和no-cache很像呀)
  • no-cache (例如:Cache-Control:private, max-age=0, no-cache),不是不缓存的意思,它实际上的机制是,仍然对资源使用缓存,但每一次在使用缓存以前必须(MUST)向服务器对缓存资源进行验证。
  • no-store 对该文件不适用任何缓存策略。
  • public 资源将被客户端和代理服务器缓存。
  • private 资源仅被客户端缓存,代理服务器不缓存。
  • public VS private 要知道从服务器到浏览器之间并不是只有浏览器可以对资源进行缓存,服务器的返回可能会通过一些中间(intermediate)服务器甚至甚至专业的中间缓存服务器,还有CDN。而有些请求返回是用户级别、是私人的,因此你可能不但愿这些中间服务器缓存返回。此时你须要将Cache-Control设置为private以免暴露。

Expires

Expires是http/1.0中定义的浏览器缓存策略。(expires: Wed, 24 Jan 2018 12:19:34 GMT

  • 用来指定资源到期的时间,是服务器端的具体的时间点。
  • 告诉浏览器在过时时间前能够直接从缓存取数据,而无需再次请求。

Last-Modified/If-Modified-Since

  • 基于客户端和服务端协商的缓存机制
  • last-modified —— response header
  • if-modified-since —— request header
  • 须要与cache-control共同使用

可是last-modified是有缺点的。

  • 1.某些服务器不能获取精确的修改时间
  • 文件修改时间改了,单文件内容却没有变

Etag/If-None-Match

此缓存策略优先级高于Last-Modified/If-Modified-Since
clipboard.png

  • 文件内容的hash值
  • etag —— response header
  • if-none-Match —— request header
  • 须要与cache-controlgongt使用

整体缓存流程图

clipboard.png

服务器端性能

vue渲染遇到的问题

vue执行过程:
下载vue.js ==> 执行vue.js代码 ==> 生成HTML页面

随着前端浏览器的性能的提高,大量的运算在前端执行。
使用vue框架出现了首屏性能、渲染问题。

优化方案?

  • 构建层模板编译(在构建层作模板编译工做,将模板语法编译成在vueruntime中能够直接执行的js代码)
  • 数据无关的prerender的方式(将vue渲染完成的静态页面返回)
  • 服务端渲染
相关文章
相关标签/搜索