前端性能优化 —— 移动端浏览器优化策略

0?wx_fmt=gif&wxfrom=5&wx_lazy=1

摘要: 前端性能优化是一个很宽泛的概念,本书前面的部分也多多少少提到一些前端优化方法,这也是我们一直在关注的一件重要事情。配合各种方式、手段、辅助系统,前端优化的最终目的都是提升用户体验,改善页面性能,我们常常竭尽全力进行前端页面优化,但却忽略了这样做的效果和意义。先不急于探究前端优化具体可以怎样去做,先看看什么是前端性能,应该怎样去了解和评价前端页面的性能。


相对于桌面端浏览器,移动端Web浏览器上有一些较为明显的特点:设备屏幕较小、新特性兼容性较好、支持一些较新的HTML5和CSS3特性、需要与Native应用交互等。但移动端浏览器可用的CPU计算资源和网络资源极为有限,因此要做好移动端Web上的优化往往需要做更多的事情。


首先,在移动端Web的前端页面渲染中,桌面浏览器端上的优化规则同样适用,此外针对移动端也要做一些极致的优化来达到更好的效果。需要注意的是,并不是移动端的优化原则在桌面浏览器端就不适用,而是由于兼容性和差异性的原因,一些优化原则在移动端更具代表性。


一、网络加载类


1.首屏数据请求提前,避免JavaScript文件加载后才请求数据


为了进一步提升页面加载速度,可以考虑将页面的数据请求尽可能提前,避免在JavaScript加载完成后才去请求数据。通常数据请求是页面内容渲染中关键路径最长的部分,而且不能并行,所以如果能将数据请求提前,可以极大程度上缩短页面内容的渲染完成时间。


2.首屏加载和按需加载,非首屏内容滚屏加载,保证首屏内容最小化


由于移动端网络速度相对较慢,网络资源有限,因此为了尽快完成页面内容的加载,需要保证首屏加载资源最小化,非首屏内容使用滚动的方式异步加载。一般推荐移动端页面首屏数据展示延时最长不超过3秒。目前中国联通3G的网络速度为338KB/s(2.71Mb/s),所以推荐首屏所有资源大小不超过1014KB,即大约不超过1MB。


3.模块化资源并行下载


在移动端资源加载中,尽量保证JavaScript资源并行加载,主要指的是模块化JavaScript资源的异步加载,例如AMD的异步模块,使用并行的加载方式能够缩短多个文件资源的加载时间。


4.inline首屏必备的CSS和JavaScript


通常为了在HTML加载完成时能使浏览器中有基本的样式,需要将页面渲染时必备的CSS和JavaScript通过<script>或<style>内联到页面中,避免页面HTML载入完成到页面内容展示这段过程中页面出现空白。


<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <title>样例</title>

    <meta name="viewport" content="width=device-width,minimum-scale=1.0, maximum-scale=1.0,user-scalable=no">

    <style>

    /* 必备的首屏CSS */

    html, body{

        margin: 0;

        padding: 0;

        background-color: #ccc;

    }

    </style>

</head>

<body>

</body>


5.meta dns prefetch设置DNS预解析


设置文件资源的DNS预解析,让浏览器提前解析获取静态资源的主机IP,避免等到请求时才发起DNS解析请求。通常在移动端HTML中可以采用如下方式完成。


<!-- cdn域名预解析 -->

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

<link rel="dns-prefetch" href="//cdn.domain.com">


6.资源预加载


对于移动端首屏加载后可能会被使用的资源,需要在首屏完成加载后尽快进行加载,保证在用户需要浏览时已经加载完成,这时候如果再去异步请求就显得很慢。


7.合理利用MTU策略


通常情况下,我们认为TCP网络传输的最大传输单元(Maximum Transmission Unit,MTU)为1500B,即网络一个RTT(Round-Trip Time,网络请求往返时间)时间内可以传输的数据量最大为1500字节。因此,在前后端分离的开发模式中,尽量保证页面的HTML内容在1KB以内,这样整个HTML的内容请求就可以在一个RTT时间内请求完成,最大限度地提高HTML载入速度。


二、缓存类


1.合理利用浏览器缓存


除了上面说到的使用Cache-Control、Expires、Etag和Last-Modified来设置HTTP缓存外,在移动端还可以使用localStorage等来保存AJAX返回的数据,或者使用localStorage保存CSS或JavaScript静态资源内容,实现移动端的离线应用,尽可能减少网络请求,保证静态资源内容的快速加载。


2.静态资源离线方案


对于移动端或Hybrid应用,可以设置离线文件或离线包机制让静态资源请求从本地读取,加快资源载入速度,并实现离线更新。关于这块内容,我们会在后面的章节中重点讲解。


3.尝试使用AMP HTML


AMP HTML可以作为优化前端页面性能的一个解决方案,使用AMP Component中的元素来代替原始的页面元素进行直接渲染。


<!-- 不推荐 -->

<video width="400" height="300" src="http://www.domain.com/videos/myvideo.mp4" poster="path/poster.jpg">

    <div fallback>

        <p>Your browser doesn’t support HTML5 video</p>

    </div>

    <source type="video/mp4" src="foo.mp4">

    <source type="video/webm" src="foo.webm">

</video>



<!-- 推荐 -->

<amp-video width="400" height="300" src="http://www.domain.com/videos/myvideo.mp4" poster= "path/poster.jpg">

    <div fallback>

        <p>Your browser doesn’t support HTML5 video</p>

    </div>

    <source type="video/mp4" src="foo.mp4">

    <source type="video/webm" src="foo.webm">

</amp-video>


三、图片类


1.图片压缩处理


在移动端,通常要保证页面中一切用到的图片都是经过压缩优化处理的,而不是以原图的形式直接使用的,因为那样很消耗流量,而且加载时间更长。


2.使用较小的图片,合理使用base64内嵌图片


在页面使用的背景图片不多且较小的情况下,可以将图片转化成base64编码嵌入到HTML页面或CSS文件中,这样可以减少页面的HTTP请求数。需要注意的是,要保证图片较小,一般图片大小超过2KB就不推荐使用base64嵌入显示了。


.class-name {

       background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAALCAMAAABxsOwqAAAAYFBMVEWnxwusyQukxQudwQyZvgyhxAyfwgyxzAsUHQGOuA0aJAERGAFIXwSTugyEqgtqhghQZgUwQQIpOQKbuguVtQuKrAuCowp2kQlheghTbQZHWQU7SwVAVgQ6TgQlLwMeKwFOemyQAAAAVElEQVQI1y3JVRaAIAAF0UconXbvf5ei8HfPDIQQhBAAFE10iKig3SLRNN4SP/p+N08VC0YnfIlNWtqIkhg/TPYbCvhqdHAWRXPZSp3g3CWZvVLXC6OJA3ukv0AaAAAAAElFTkSuQmCC');

}


3.使用更高压缩比格式的图片


使用具有较高压缩比格式的图片,如webp等。在同等图片画质的情况下,高压缩比格式的图片体积更小,能够更快完成文件传输,节省网络流量。


<img src="//cdn.domain.com/path/photo.webp" alt="webp格式图片">


4.图片懒加载


为了保证页面内容的最小化,加速页面的渲染,尽可能节省移动端网络流量,页面中的图片资源推荐使用懒加载实现,在页面滚动时动态载入图片。


<img data-src="//cdn.domain.com/path/photo.jpg" alt="懒加载图片">


5.使用Media Query或srcset根据不同屏幕加载不同大小图片


在介绍响应式的章节中我们了解到,针对不同的移动端屏幕尺寸和分辨率,输出不同大小的图片或背景图能保证在用户体验不降低的前提下节省网络流量,加快部分机型的图片加载速度,这在移动端非常值得推荐。


6.使用iconfont代替图片图标


在页面中尽可能使用iconfont来代替图片图标,这样做的好处有以下几个:使用iconfont体积较小,而且是矢量图,因此缩放时不会失真;可以方便地修改图片大小尺寸和呈现颜色。但是需要注意的是,iconfont引用不同webfont格式时的兼容性写法,根据经验推荐尽量按照以下顺序书写,否则不容易兼容到所有的浏览器上。


@font-face {

    font-family: iconfont;

    src: url("./iconfont.eot");

    src: url("./iconfont.eot?#iefix") format("eot"),

         url("./iconfont.woff") format("woff"),

         url("./iconfont.ttf") format("truetype");

}


7.定义图片大小限制


加载的单张图片一般建议不超过30KB,避免大图片加载时间长而阻塞页面其他资源的下载,因此推荐在10KB以内。如果用户上传的图片过大,建议设置告警系统,帮助我们观察了解整个网站的图片流量情况,做出进一步的改善。


四、脚本类


1.尽量使用id选择器


选择页面DOM元素时尽量使用id选择器,因为id选择器速度最快。


2.合理缓存DOM对象


对于需要重复使用的DOM对象,要优先设置缓存变量,避免每次使用时都要从整个DOM树中重新查找。


// 不推荐

$('#mod .active').remove('active');

$('#mod .not-active').addClass('active');


// 推荐

let $mod = $('#mod');

$mod.find('.active').remove('active');

$mod.find('.not-active').addClass('active');


3.页面元素尽量使用事件代理,避免直接事件绑定


使用事件代理可以避免对每个元素都进行绑定,并且可以避免出现内存泄露及需要动态添加元素的事件绑定问题,所以尽量不要直接使用事件绑定。


// 不推荐

$('.btn').on('click', function(e){

    console.log(this);

});


// 推荐

$('body').on('click', '.btn', function(e){

    console.log(this);

});


4.使用touchstart代替click


由于移动端屏幕的设计,touchstart事件和click事件触发时间之间存在300毫秒的延时,所以在页面中没有实现touchmove滚动处理的情况下,可以使用touchstart事件来代替元素的click事件,加快页面点击的响应速度,提高用户体验。但同时我们也要注意页面重叠元素touch动作的点击穿透问题。


// 不推荐

$('body').on('click', '.btn', function(e){

    console.log(this);

});


// 推荐

$('body').on('touchstart', '.btn', function(e){

    console.log(this);

});


5.避免touchmove、scroll连续事件处理


需要对touchmove、scroll这类可能连续触发回调的事件设置事件节流,例如设置每隔16ms(60帧的帧间隔为16.7ms,因此可以合理地设置为16ms)才进行一次事件处理,避免频繁的事件调用导致移动端页面卡顿。


// 不推荐

$('.scroller').on('touchmove', '.btn', function(e){

    console.log(this);

});


// 推荐

$('.scroller').on('touchmove', '.btn', function(e){

    let self = this;

    setTimeout(function(){

        console.log(self);

    }, 16);

});


6.避免使用eval、with,使用join代替连接符+,推荐使用ECMAScript 6的字符串模板


这些都是一些基础的安全脚本编写问题,尽可能使用较高效率的特性来完成这些操作,避免不规范或不安全的写法。


7.尽量使用ECMAScript 6+的特性来编程


ECMAScript 6+一定程度上更加安全高效,而且部分特性执行速度更快,也是未来规范的需要,所以推荐使用ECMAScript 6+的新特性来完成后面的开发。


五、渲染类


1.使用Viewport固定屏幕渲染,可以加速页面渲染内容


一般认为,在移动端设置Viewport可以加速页面的渲染,同时可以避免缩放导致页面重排重绘。在移动端固定Viewport设置的方法如下。


<!-- 设置viewport不缩放 -->

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">


2.避免各种形式重排重绘


页面的重排重绘很耗性能,所以一定要尽可能减少页面的重排重绘,例如页面图片大小变化、元素位置变化等这些情况都会导致重排重绘。


3.使用CSS3动画,开启GPU加速


使用CSS3动画时可以设置transform: translateZ(0)来开启移动设备浏览器的GPU图形处理加速,让动画过程更加流畅。


-webkit-transform: translateZ(0);

-ms-transform: translateZ(0);

-o-transform: translateZ(0);

transform: translateZ(0);


4.合理使用Canvas和requestAnimationFrame


选择Canvas或requestAnimationFrame等更高效的动画实现方式,尽量避免使用setTimeout、setInterval等方式来直接处理连续动画。


5.SVG代替图片


部分情况下可以考虑使用SVG代替图片实现动画,因为使用SVG格式内容更小,而且SVG DOM结构方便调整。


6.不滥用float


在DOM渲染树生成后的布局渲染阶段,使用float的元素布局计算比较耗性能,所以尽量减少float的使用,推荐使用固定布局或flex-box弹性布局的方式来实现页面元素布局。


7.不滥用web字体或过多font-size声明


过多的font-size声明会增加字体的大小计算,而且也没有必要的。


六、架构协议类


1.尝试使用SPDY和HTTP 2


在条件允许的情况下可以考虑使用SPDY协议来进行文件资源传输,利用连接复用加快传输过程,缩短资源加载时间。HTTP 2在未来也是可以考虑尝试的。


2.使用后端数据渲染


使用后端数据渲染的方式可以加快页面内容的渲染展示,避免空白页面的出现,同时可以解决移动端页面SEO的问题。如果条件允许,后端数据渲染是一个很不错的实践思路。后面的章节会详细介绍后端数据渲染的相关内容。


3.使用Native View代替DOM的性能劣势


可以尝试使用Native View的MNV开发模式来避免HTML DOM性能慢的问题,目前使用MNV的开发模式已经可以将页面内容渲染体验做到接近客户端Native应用的体验了。


关于页面优化的常用技术手段和思路主要包括以上这些,尽管列举出很多,但仍可能有少数遗漏,可见前端性能优化不是一件简简单单的事情,其涉及的内容很多。大家可以根据实际情况将这些方法应用到自己的项目当中,要想全部做到几乎是不可能的,但做到用户可接受的原则还是很容易实现的。


于此同时我们要清楚的是,在我们做到了极致优化的同时也付出了很大的代价,这也是前端优化的一个问题。理论上这些优化都是可以实现的,但是作为工程师我们也要明白懂得权衡。优化提升了用户体验,使数据加载更快,但是项目代码却可能打乱,异步内容要拆分出来,首屏的一个雪碧图可能要分成两个,页面项目代码维护成本成倍增加,项目结构也可能变得混乱。


所以前期在设计构建、组件的解决方案时要解决好异步的自动处理问题。任何一部分优化都可以做得很深入,但不一定都值得,在优化的同时也要尽量考虑性价比,这才是我们作为一名前端工程师处理前端优化时应该具有的正确思维。


系列文章:


前端性能优化(一) 前端性能分析:

  •  https://my.oschina.net/zhangstephen/blog/1601380


前端性能优化(二) 桌面浏览器前端优化策略:

  •  https://my.oschina.net/zhangstephen/blog/1601382


前端性能优化(三) 移动端浏览器前端优化策略:

  •  https://my.oschina.net/zhangstephen/blog/1601383


本文摘自书籍《现代前端技术解析》

0?wx_fmt=png


MySQL数据库从入门实战课

12-31
限时福利1:购课进答疑群专享柳峰(刘运强)老师答疑服务。 限时福利2:购课后添加学习助手(微信号:csdn590),按消息提示即可领取编程大礼包! 注意:原价129的课程,最后2天限时秒杀仅需49元!! 为什么说每一个程序员都应该学习MySQL? 根据《2019-2020年中国开发者调查报告》显示,超83%的开发者都在使用MySQL数据库。 使用量大同时,掌握MySQL早已是运维、DBA的必备技能,甚至部分IT开发岗位也要求对数据库使用和原理有深入的了解和掌握。 学习编程,你可能会犹豫选择 C++ 还是 Java;入门数据科学,你可能会纠结于选择 Python 还是 R;但无论如何, MySQL 都是 IT 从业人员不可或缺的技能! 【课程设计】 在本课程中,刘运强老师会结合自己十多年来对MySQL的心得体会,通过课程给你分享一条高效的MySQL入门捷径,让学员少走弯路,彻底搞懂MySQL。 本课程包含3大模块:  一、基础篇: 主要以最新的MySQL8.0安装为例帮助学员解决安装与配置MySQL的问题,并对MySQL8.0的新特性做一定介绍,为后续的课程展开做好环境部署。 二、SQL语言篇: 本篇主要讲解SQL语言的四大部分数据查询语言DQL,数据操纵语言DML,数据定义语言DDL,数据控制语言DCL,学会熟练对库表进行增删改查等必备技能。 三、MySQL进阶篇: 本篇可以帮助学员更加高效的管理线上的MySQL数据库;具备MySQL的日常运维能力,语句调优、备份恢复等思路。  

Python入门到实战一卡通

06-09
<span><span><span><span> <p class="ql-long-24357476"> <span> </span> </p> <p class="ql-long-24357476"> 【课程特色】 </p> <p class="ql-long-24357476"> <span class="ql-author-24357476">1、超强师资+体系全面+ 1 对 1 答疑+离线缓存+永久有效,无限回放</span> </p> <p class="ql-long-24357476"> 2、知识全面系统,从Python入门到逐步进阶到爬虫、数据分析、Web框架、人工智能应用 </p> <p class="ql-long-24357476"> <br> </p> <p class="ql-long-24357476"> <span class="ql-author-24357476">【优惠说明】</span> </p> <p class="ql-long-24357476"> <span class="ql-author-24357476">1、8大课程,250余节视频课,原价998元,今日联报立减800,仅需198元</span> </p> <p class="ql-long-24357476"> <span class="ql-author-24357476">2、</span>现在购课,就送价值800元的编程大礼包! </p> <p class="ql-long-24357476"> 备注:请添加微信:itxy41,按提示获取讲师答疑服务。 </p> <p> <br> </p> <p class="ql-long-24357476"> 讲师介绍:裴帅帅,前百度资深架构师,现爱奇艺算法架构师全程亲自授课。 </p> <p> <br> </p> <p class="ql-long-24357476"> 【为什么要学习这门套餐课?】 </p> <p class="ql-long-24357476"> Python无论是在web/爬虫/人工智能/大数据/机器学习/测试/运维/数据分析等等领域都有大量的应用,但是作为小白来讲,很难确定最适合自己的应用方向。 </p> <p> <br> </p> <p class="ql-long-24357476"> 在这门课程中,将带你从零入门Python,并向你讲授实战 Python 各个应用方向的核心知识点,同时应用于实战项目。 </p> <p> <br> </p> <p class="ql-long-24357476"> 【学完后我将达到什么水平?】 </p> <p class="ql-long-24357476"> 你将能够熟练掌握 Python 在人工智能时代的多种技能,具备使用 Python 编写代码完成 Web 后台开发、网络爬虫、数据分析、机器学习、推荐系统等多种项目实战的能力,掌握 Python 全栈工程师的核心能力。 </p> <p> <br> </p> <p class="ql-long-24357476"> 【课程学习路径】 </p> <p class="ql-long-24357476"> 本套课以市场就业和职位需求为核心,从 Python 入门到多领域实战,并结合 Python 全栈工程师的进阶路线,共分为八大模块,分别是:Python 基础、Python Web 开发、Python 爬虫、Numpy 数据计算、Pandas 数据分析、Python数据可视化、Tensorflow 深度学习、推荐系统实战应用模块。 </p> <p> <br> </p> <p class="ql-long-24357476"> 套餐中一共包含8门Python课程(共246讲)助你从零进阶Python全栈工程师! </p> <p class="ql-long-24357476"> 课程1:《Python零基础入门视频教程》 </p> <p class="ql-long-24357476"> 课程2:《Python爬虫从入门到实战》 </p> <p class="ql-long-24357476"> 课程3:《Python使用Flask开发Web服务》 </p> <p class="ql-long-24357476"> 课程4:《Python使用Numpy入门数据计算》 </p> <p class="ql-long-24357476"> 课程5:《Python使用Pandas入门数据分析》 </p> <p class="ql-long-24357476"> 课程6:《Python数据图表可视化》 </p> <p class="ql-long-24357476"> 课程7:《Tensorflow深度学习从入门到实战》 </p> <p class="ql-long-24357476"> 课程8:《推荐系统技术入门到实战》 </p> <p> <br> </p> <p class="ql-long-24357476"> 【面向人群】 </p> <p class="ql-long-24357476"> 1、在校计算机专业或者对软件编程感兴趣的学生; </p> <p class="ql-long-24357476"> 2、想要使用数据分析、网络爬虫提升职场竞争力升职加薪的各行各业的企业白领; </p> <p class="ql-long-24357476"> 3、想要转方向成为数据分析师、大数据开发、机器学习算法、推荐系统工程师的职场码农; </p> <p class="ql-long-24357476"> 4、准备从事人工智能、Python开发的程序员。 </p> </span> <p> <br> </p> <p class="ql-long-24357476"> <br> </p> <p> <br> </p> <p class="ql-long-24357476"> 【课程知识体系图】 </p> </span></span></span> <p> <img src="https://img-bss.csdnimg.cn/202006100818561687.png" alt=""> </p>

150讲轻松搞定Python网络爬虫

05-16
【为什么学爬虫?】        1、爬虫入手容易,但是深入较难,如何写出高效率的爬虫,如何写出灵活性高可扩展的爬虫都是一项技术活。另外在爬虫过程中,经常容易遇到被反爬虫,比如字体反爬、IP识别、验证码等,如何层层攻克难点拿到想要的数据,这门课程,你都能学到!        2、如果是作为一个其他行业的开发者,比如app开发,web开发,学习爬虫能让你加强对技术的认知,能够开发出更加安全的软件和网站 【课程设计】 一个完整的爬虫程序,无论大小,总体来说可以分成三个步骤,分别是: 网络请求:模拟浏览器的行为从网上抓取数据。 数据解析:将请求下来的数据进行过滤,提取我们想要的数据。 数据存储:将提取到的数据存储到硬盘或者内存中。比如用mysql数据库或者redis等。 那么本课程也是按照这几个步骤循序渐进的进行讲解,带领学生完整的掌握每个步骤的技术。另外,因为爬虫的多样性,在爬取的过程中可能会发生被反爬、效率低下等。因此我们又增加了两个章节用来提高爬虫程序的灵活性,分别是: 爬虫进阶:包括IP代理,多线程爬虫,图形验证码识别、JS加密解密、动态网页爬虫、字体反爬识别等。 Scrapy和分布式爬虫:Scrapy框架、Scrapy-redis组件、分布式爬虫等。 通过爬虫进阶的知识点我们能应付大量的反爬网站,而Scrapy框架作为一个专业的爬虫框架,使用他可以快速提高我们编写爬虫程序的效率和速度。另外如果一台机器不能满足你的需求,我们可以用分布式爬虫让多台机器帮助你快速爬取数据。   从基础爬虫到商业化应用爬虫,本套课程满足您的所有需求! 【课程服务】 专属付费社群+每周三讨论会+1v1答疑
©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值