【前端优化】常见前端性能优化

资源压缩 减小HTTP请求

静态资源压缩

  • html:压缩空格、换行、注释等字符 Webapack — html-webpack-plugin
  • css:无效代码删除,语义合并(相一样式代码) Webpack css-loader
  • js:无效字符删除、剔除注释代码语义的缩减和优化 Webpack — UglifyJSPlugin
  • 图片优化方案:css

    • 雪碧图
    • 小文件 使用base64 webpack base64-inline-loader
    • 图片压缩网站
    • svg

资源合并

  • 弊端:html

    • 首屏渲染问题,合并文件太大,形成慢。
    • 缓存失效问题 标记 md5戳 只要有一个变更 则失效 a,b,c三个js合并
  • 规则:公共库合并,不一样页面的各自合并。异步加载组件,不一样页面单独打包,监听路由变化,自动下载
  • 实现:gulp插件梳理工做流/webpack配置loader和plugin

非核心代码异步加载

正常网页的加载流程:java

  1. 浏览器一边下载 HTML 网页,一边开始解析。也就是说,不等到下载完,就开始解析。
  2. 解析过程当中,浏览器发现<script>元素,就暂停解析,把网页渲染的控制权转交给 JavaScript 引擎。
  3. 若是<script>元素引用了外部脚本,就下载该脚本再执行,不然就直接执行代码。
  4. JavaScript 引擎执行完毕,控制权交还渲染引擎,恢复解析 HTML 网页。

上述加载方式为同步加载,会阻塞浏览器的解析html文档。故而咱们常将script元素放置于body的底部webpack

三种实现方式:动态脚本、async、deferweb

动态脚本

动态建立script标签gulp

var scriptEle = document.createElement("script");
scriptEle.type = "text/javasctipt";
scriptEle.async = true;
scriptEle.src = "http://xxxxxxx";
var x = document.getElementsByTagName("head")[0];
x.insertBefore(scriptEle, x.firstChild);

async

async属性和defer属性相似,也是会开启一个线程去下载js文件,但和defer不一样的时,它会在下载完成后马上执行,而不是会等到DOM加载完成以后再执行,因此仍是有可能会形成阻塞。后端

且不会按照顺序执行,哪一个js文件先下载完就先执行哪一个浏览器

对于内联脚本无做用 (即没有src属性的脚本)。缓存

defer

当浏览器遇到带有defer属性的<script>标签时,再开启一个线程去下载js文件,同时继续解析HTML文档,等等HTML所有解析完毕DOM加载完成以后,再按照出现顺序依次执行加载好的js文件。服务器

对于内联脚本无做用 (即没有src属性的脚本)。

使用场景

通常来讲,是看脚本之间是否有依赖关系,有依赖的话应当要保证执行顺序,应当使用defer没有依赖的话使用async,同时使用的话defer失效。要注意的是二者都不该该使用document.write,这个致使整个页面被清除。

利用浏览器缓存

https://juejin.im/post/5c4179...

优势:

  • 减小了冗余的数据传输,节省网费
  • 减小服务器的负担,提高网站性能
  • 加快了客户端加载网页的速度

浏览器缓存分为强缓存和协商缓存

强缓存

若是资源没过时,就取缓存,若是过时了,则请求服务器。

  • cache-control:max-age = xxx

    声明该资源在加载后的xxx秒内都直接使用缓存 使用的是相对时间 即加载文件本机的时间

    • Cache-Control 的几个取值含义:

      • private:仅浏览器能够缓存
      • public:浏览器和代理服务器均可以缓存
      • max-age=xxx:过时时间
      • no-cache:不进行强缓存
      • no-store:不强缓存,也不协商缓存
    • 规则能够同时多个 cache-control:public,max-age=0
  • expires: 绝对时间,服务器基于本身的时间返回一个文件过时时间

    若是在Cache-Control响应头设置了 "max-age" 或者 "s-max-age" 指令,那么 Expires 头会被忽略。

强缓存步骤

  1. 第一次请求 a.js ,缓存表中没该信息,直接请求后端服务器。
  2. 后端服务器返回了 a.js ,且 http response header 中 cache-control 为 max-age=xxxx,因此是强缓存规则,存入缓存表中。
  3. 第二次请求 a.js ,缓存表中是 max-age, 那么命中强缓存,而后判断是否过时,若是没过时,直接读缓存的a.js,若是过时了,则执行协商缓存的步骤了。

协商缓存

触发条件

  1. Cache-Control 的值为 no-cache (不强缓存)
  2. 或者 max-age 过时了 (强缓存,但总有过时的时候)

也就是说,无论怎样,均可能最后要进行协商缓存(no-store除外)

ETag:每一个文件有一个,改动文件了就变了,能够看似md5

Last-Modified:文件的修改时间

每次http返回来 responseheader 中的 ETag和 Last-Modified,在下次请求时在 requestheader 就把这两个带上(可是名字变了ETag-->If-None-Match,Last-Modified-->If-Modified-Since ),服务端把你带过来的标识,资源目前的标识,进行对比,而后判断资源是否更改了。

协商缓存步骤总结

  1. 请求资源时,把用户本地该资源的 ETag 同时带到服务端,服务端和最新资源作对比。
  2. 若是资源没更改,返回304,浏览器读取本地缓存。
  3. 若是资源有更改,返回200,返回最新的资源。

DNS预解析

预解析的实现:

  1. 用meta信息来告知浏览器, 当前页面要作DNS预解析:

    <meta http-equiv="x-dns-prefetch-control" content="on" />
  2. 在页面header中使用link标签来强制对DNS预解析:

    <link rel="dns-prefetch" href="http://bdimg.share.baidu.com" />

注:dns-prefetch需慎用,多页面重复DNS预解析会增长重复DNS查询次数。

若是须要禁止隐式的 DNS Prefetch,可使用如下的标签:

<meta http-equiv="x-dns-prefetch-control" content="off">

在浏览器中a标签默认打开DNS预解析,可是在HTTPS中默认关闭

CDN 内容分发网络

img

网络请求的过程走最近的网络环境,解决网络拥堵。

相关文章
相关标签/搜索