为了账号安全,请及时绑定邮箱和手机立即绑定

Effective前端--加快页面打开速度

标签:
JavaScript

1.避免head标签JS阻塞

  所有放在head标签里的JS和CSS都会阻塞页面渲染。如果这些CSS和JS需要记在时间比较久,中间页面会存在一个空白期,严重影响到用户体验。

  例如以下代码:在head标签内加载jquery的js文件,

<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 class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="https://code.jquery.com/jquery-3.3.1.js"></script>

</head>

  jquery.js脚本文件加载了1.2s的时间,如下图:

webp

  相比之下,html加载的时间只有2ms,所以这个JS文件至少页面停留了1.2s的空白状态。

  解决方法:1.使用script标签将js脚本文件放在body后面

       2.使用HTML5的新增属性defer,给script标签价上defer属性,一旦加上该属性,script将会异步加载,但不是马上执行,而是等readystatechange变为Interactive后按照顺序执行。

2.减少head标签里的CSS资源

  (1)不要放太多base64放在CSS里面

   放太多base64在CSS里面,会导致CSS急速膨胀,把一张3k的图片转换为base64,体积将变为4k;如果你的css文件中放了10张3k的base64图片,CSS文件的体积将变为40k,可想而知,图片放的越多,越会增大css文件大小,加载时间就会变长。

   如下图:

webp

  从上图可以发现,转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中会是一个不错的选择。

 3.优化图片

  (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说明

webp

    需要注意的是,使用picture标签时必须使用img标签,否则无法显示。对picture的操作最后都是在img标签上体现,例如事件是在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 class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="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配置。接触不深,不做见解

 4.其他优化方式

       (1)升级到HTTP/2

    http2的有点在于对于一个域只建立一次TCP连接,使用多路复用,传输多个资源,这样就不用使用注入雪碧图、合并js/css文件等技术减少请求数,它可以同时加载多个资源,不用进行资源排队。

   (2)DNS预读取

<link rel="dns-prefetch"  href="https://www.google.com/">

  提前解析DNS,多个并行,不会堵塞页面渲染,可以减少资源加载时间

   (3)HTML优化

    remove掉多余注释,删除行前缩进,都会减少HTML的体积

   (4)代码优化



作者:Cherish415
链接:https://www.jianshu.com/p/2da3e95f2530


点击查看更多内容
1人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消