全部放在head标签里的JS和CSS都会阻塞页面渲染。若是这些CSS和JS须要记在时间比较久,中间页面会存在一个空白期,严重影响到用户体验。javascript
例如如下代码:在head标签内加载jquery的js文件,css
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>demo</title> <script src="https://code.jquery.com/jquery-3.3.1.js"></script> </head>
jquery.js脚本文件加载了1.2s的时间,以下图:html
相比之下,html加载的时间只有2ms,因此这个JS文件至少页面停留了1.2s的空白状态。java
解决方法:1.使用script标签将js脚本文件放在body后面jquery
2.使用HTML5的新增属性defer,给script标签价上defer属性,一旦加上该属性,script将会异步加载,但不是立刻执行,而是等readystatechange变为Interactive后按照顺序执行。web
(1)不要放太多base64放在CSS里面浏览器
放太多base64在CSS里面,会致使CSS急速膨胀,把一张3k的图片转换为base64,体积将变为4k;若是你的css文件中放了10张3k的base64图片,CSS文件的体积将变为40k,可想而知,图片放的越多,越会增大css文件大小,加载时间就会变长。缓存
以下图:服务器
从上图能够发现,转base64后,图片体积增大了接近1/3,咱们的目的是为了减少CSS、JS加载时间的,而非增长时间(不考虑不一样网速环境)。异步
(2)把CSS写成内联的
为何这样说呢,咱们写CSS的时候,老是被告诫少些内联样式,易于维护。可是若是你的CSS只有10K或者30-40k,把它写成内联的何尝不可,吧项目的CSS文件gzip以后若是很小,彻底能够把全部的CSS都写成style标签放到HTML里面。
若是你把CSS放到CDN上,浏览器为了获得这个CSS文件,须要进行域名解析,而后创建http/https连接,其次才是下载此文件。而用来作域名解析和创建链接的时间早已经把CSS下载下来了。
为了不时间开销,更好的用户浏览速度,能够把CSS直接嵌到HTML里面。
若是你的CSS文件不是太大,加上gzip压缩,放到HTML中会是一个不错的选择。
(1)使用响应式图片
响应式图片的优势就是可以根据浏览器的屏幕大小、设备像素比dpr、横竖屏自动加载合适的图片
<img srcset='phtoto_w350.jpg 1x,photo_w640.jpg 2x' src='photo_w350.jpg' alt=''>
上述代码实现若是屏幕的dpr=1的话加载1倍图,而dpr=2则加载2倍图。而且,若是浏览器不支持srcset属性,会默认加载src里面的图片。
网上说,在MAC上的CHorme会加载srcset里面的2x图片的同时,还会去加载src里面的那张,加载两张图片。哈哈,因为本人比较穷,无mac,不能验证了。有的小伙伴能够验证下
另外HTML5新增的picture标签,对实现响应式图片作了不少扩展。不想敲了,借用MDN说明
须要注意的是,使用picture标签时必须使用img标签,不然没法显示。对picture的操做最后都是在img标签上体现,例如onload事件是在img标签出发的,picture和source是不会被浏览器layout的,他们的宽和高都是0.
在栗子2中,可使用type=‘image/webp’,从而使用webp格式的图片,webp图片在保持同等清晰度的状况下,体积能够减小一半,可是兼容性不太好,目前只有chorme支持。可是若是检查到不支持此格式,会默认选择img标签内的图片。
(2)延迟加载图片
这个是大众常谈的,基本上都很熟悉,简单说一下
页面内图片过多的状况下,若是一口气加载完,会致使页面的loaded时间较长,而且因为下载并行的资源有限制的,图片太多会致使放在body后的JS解析会比较慢,页面会较长时间处在不可交互的状态。
懒加载图片这时就排上用场了,初始加载的时候只加载首屏图片,不在视口内的图片,只有在用户下滑至相应位置才去加载。
具体作法:渲染图片的时候 把图片地址放到标签的一个data属性上,别放到src上。以下:
<picture> <source data-srcset="mdn-logo.svg" type="image/svg+xml"> <img src="about:blank" data-src='mdn-logo.png' alt="MDN"> </picture
src里不能写一个不存在的地址,不然浏览器控制台会报错。加载失败,若是写成空或者不写,那么src会默认当前页面。写成about:blank,不会报错,浏览器兼容性也很好。
监听scroll事件,回调函数以下:
showImage(leftSpace = 500){ var scrollTop = $window.scrollTop(); var $containers = this.$imgContainers, scrollPosition = $window.scrollTop() + $window.height(); for(var i =0;i<$containers.length;i++){ var $container = $containers.eq(i); if($container.ofset().top() - scrollPosition < leftSpace){ this.ensureImgSrc($container) } } }
使用ensureImgSrc函数把图片放出来
ensureImgSrc($container){ var $source = $cotainer.find("source"); if($source.length && !$source.attr('srcset')){ $source.attr('srcset',$source.data('srcset')); } var $img= $cotainer.find("img:not(.loading)"); if($img.length && !$img.attr('src').indexOf('//')<0》){ $img.attr('src',$source.data('src')); this.shownCount++; } }
另外当图片被加载完毕后,要清楚监听事件,不然会形成内存泄漏。
int(){ //初始化 var leftSpace = 0; this.showImage(leftSpace); //监听事件 $window.on("scroll",this,this.throttleShow); } ensureImgSrc($container){
//若是所有显示,off掉scroll if(this.showCount>=this.allCount){ $window.off("scroll",this.throttleShow) } }
(3) 压缩和缓存
gzip压缩和服务器设置缓存。须要后台Nginx配置。接触不深,不作看法
(1)升级到HTTP/2
http2的有点在于对于一个域只创建一次TCP链接,使用多路复用,传输多个资源,这样就不用使用注入雪碧图、合并js/css文件等技术减小请求数,它能够同时加载多个资源,不用进行资源排队。
(2)DNS预读取
<link rel="dns-prefetch" href="https://www.google.com/">
提早解析DNS,多个并行,不会堵塞页面渲染,能够减小资源加载时间
(3)HTML优化
remove掉多余注释,删除行前缩进,都会减小HTML的体积
(4)代码优化