前端性能优化策略

注意: 最好是在修改以后进行先后对比,在使用了优化方法以后和没使用的时候,由于就算使用了优化方式,也不必定会起到性能优化的效果,须要据场景而定。css

http 请求过程中潜在的性能优化点

  • 静态资源通常放到 cdn 加快静态资源的得到,可是当咱们 cdn 的域名和页面的域名相同的时候,请求会带上不准不须要的 cookies ,因此二者的域名不能同样。
  • dns 缓存, 下降访问 dns 的时间。
  • 对于接口,咱们能够减小 http 请求的次数和大小。
  • 浏览器缓存。
  • 页面渲染过程优化。
  • 使用服务端渲染。

资源压缩与合并

在真实的开发中都是使用构建工具(webpack、gulp等)来完成下面的事情html

html 压缩

去掉空格、注释、回车、换行。html5

  • 使用在线网网站进行压缩(实际公司中不适用)。
  • 使用 nodejs 提供的 html-minifier
  • 后端模板引擎渲染压缩。

css 压缩

去掉空格、注释、回车、换行无效代码删除语义合并。node

  • 使用在线网网站进行压缩(实际公司中不适用)。
  • 使用 nodejs 提供的 html-minifier
  • 使用clean-cscss进行压缩。

js压缩与混乱

无效字符的删除、剔除注释、代码语义的缩减和优化(如变量名缩短)、代码保护(将Js代码混乱,使其不可读)。webpack

  • 使用在线网站进行压缩。
  • 使用html-minifier
  • 使用uglifyjs2js进行压缩 。

文件合并

文件合并能够减小网络请求, 并且浏览器可以同时并发的请求数量有限,当请求过多的时候可能须要等待,文件合并能够减小请求次数,减小等待。可是存在首屏渲染问题(第一次请求时间长)、缓存失效(单个文件的缓存失效会致使合并当中其余文件的缓存失效)的问题。因此有以下的合并建议。ios

  • 公共库合并: 公共库通常不会变,咱们能够将它们进行合并。
  • 不一样页面的合并: 针对单页应用,只有当咱们跳转到那个页面的时候,才去请求这个页面的资源,将这个页面涉及的资源进行合并。

那么怎么进行文件合并呢?以下:web

  • 使用在线网站进行文件合并。
  • 使用nodejs实现文件合并。

图片优化

每种图片格式都有本身的特色,针对不一样的业务场景选择不一样的图片格式很重要gulp

  • jgp有损压缩
  • png: 颜色类型丰富的图片,应该选择位数高的pngsegmentfault

    • png8: 256色,支持透明
    • png24: 2^24色 不支持透明
    • png32: 2^24色 支持透明

不一样格式图片经常使用的业务场景

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

图片压缩

  • 可以使用tinypng这个网站来压缩

css 雪碧图

把网站上用到的一些图片整合到一张单独的图片当中,从而减小大量的 http 请求的数量。缺点是图片会变大后端

  • 第一步是将图片合并到一张图片上
  • 第二步是使用在线网站,上传图片,选中指定的图片,而后会有相应的css

Image inline

将图片内嵌到html当中, 减小网站的 http 请求数量, 如使用 base6 的方式插入图片, 通常网站当中一些小的图标能够用它,实际根具状况而定

使用矢量图

使用 svg 进行矢量图的绘制,图片的质量和速度都特别好,使用得也比较多。

寄予页面渲染过程的优化

https://segmentfault.com/a/11...

并发

浏览器对于一个域名的并发请求数量是有限的,因此咱们须要设置多个域名,好比 cdn 设置多个域名

懒加载和预加载

懒加载

  • 通常都是对于图片来讲,当图片进入可视区域的时候再加载图片
  • url 地址放置到 img 标签当中,当进入可视区的时候,将其取出来设置

预加载

  • 图片等静态资源在使用以前的提早请求
  • 资源使用到的时候从缓存当中加载

有三种方式:

  • 直接在页面上把 img 标签放到前面, 而后 display: none;
  • var image = new Image(); image.src = xxxx; 使其下载下来,后面使用的时候后会直接去缓存拿
  • 使用XMLHttpRequset, urlimage.srcurl, 可使用它更加精细的对预加载的过程进行控制
  • 使用preload.js

客户端存储

Cookie

用来维护用户状态

  • Cookie的生成方式: 服务端的response.header使用set-cookie, 或者使用document.cookie进行读写
  • 浏览器端在相应的域名下保存

cdn的静态资源不须要cookie, 可是在相同域名下面,http请求会自动带上cookie, 解决办法是cdn的域名和主站的域名要不相同。

localstorage

对于不会常常变得数据,能够存在里面

  • html5当中设计出来专门用于浏览器存储的
  • 大小为5M左右
  • 浏览器缓存方案

sessionStorage

  • 会话级别的浏览器存储(一个tab)
  • 大小为5M左右
  • 如使用它进行表单信息的维护(提高用户体验)

IndexedDB

  • 用于客户端存储大量结构化数据
  • 为应用建立离线版本

Service Workers

能够启动一个其余的线程来进行运算, 防止阻塞。

  • 使用拦截和处理网络请求的能力去实现离线应用
  • 使用那个Service worker在后台运行同时能和页面通讯的能力。
  • 存储对应于浏览器当中的cache

PWA

是一个 web app 新模型

浏览器自动缓存

须要response-headerrequest-header进行配合,每一个文件在进行缓存存储的时候,都会将response-header一块儿存,方便下一次判断缓存状况时使用response-header当中和缓存相关的头字段。并且若是是直接从缓存当中读取。

命中max-age、expire缓存策略的状态码为200, 命中etag、last-modified、s-maxage缓存策略的时候状态码为304
响应头当中的和缓存相关的头字段以及状态码,都须要咱们在服务端判断是否为响应的状况后,手动设置

Cache-Control

可存在于requset-headerresponse-header

  • max-age : 再这个时间以内,再次请求相同资源的时候,浏览器会直接从缓存中取,不会发起请求,状态码为200
  • s-maxage: 优先级高于max-age, 用来设置public的缓存。状态码为 304, 注意这里是去公共的缓存区域取数据,如 cdn, 不是在浏览器本地区数据。
  • private: 在浏览器上的缓存。对应max-age
  • public: 如cnd, 你们均可以访问。对应s-maxage
  • no-cache: 设置了这个属性,不会像max-age同样,若是没有过时,那么直接去缓存取数据,而是会先发起一次请求,这个时候会带上 If-None-Match 或者 if-Modified-since 去服务端询问缓存是否过时,若是没有过时服务端返回304, 而后去缓存区取数据,否者返回200, 并返回新的内容。
  • no-store: 当设置了这个属性,就不会使用缓存策略

Expires

缓存过时时间,比max-age的优先级低

Last-Modified/If-Modified-Since

前面两个头部,能够解决在指定的时间内在缓存当中去取数据,可是当咱们的服务端将数据更改以后,客户端并不知道。

服务端返回一个文件最后修改时间Last-Modified, 在请求的时候带上If-Modified-Since,在服务端进行比对,若是客户端传过来的时间小于服务器上文件的最后修改时间,那么就返回200,并将相应的最新内容和Last-Modified给返回。否者返回304,文件内容未被修改。

须要注意的是,当设置了Max-age的时候,仍然走缓存,只有当Max-age过时了以后,这两个字段才会起做用

Etag / If-None-Match

前面的 Last-Modified/If-Modified-Since,存在一个缺点,那就是当服务端Last-Modified修改以后,可能文件内容并无发生改变,这个时候,其实并无必要去从新返回内容。因此咱们可使用文件的hash值,只有文件的hash值发生改变以后,文件内容才发生改变。

一样须要注意的是,只有在Max-age或者Expire失效以后,Etag / If-None-Match才有效。到服务端进行比对,未改变返回304,改变了返回200

Etag / If-None-Match的优先级比Last-Modified / If-Modified-Since优先级高。

服务端性能优化

用服务端的运算能力,来减轻浏览器端的运算压力。

咱们以React为例来讲: 当咱们访问觉得用React写的网站时,首先会下载咱们的代码,可是因为React是基于数据驱动的,因此它还要进行一步渲染的过程,会将咱们的JSX转换成virtualdom, 而后再转换成html代码,这一过程是须要时间的。

解决方案在服务端将React代码渲染成html以后再返回浏览器端

  • 构建层模板编译
  • 数据无关的prerender方式
  • 服务端渲染
相关文章
相关标签/搜索