浏览器性能优化,这一篇就够了

浏览器性能优化

关于浏览器性能优化这方面,也是web开发一个不可避免地重点。下面就分别从几个方面谈一谈如何提高浏览器性能。

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

为了进一步提升页面加载速度,可以考虑将页面的数据请求尽可能提前,避免在 JavaScript 加载完成后才去请求数据。通常数据请求是页面内容渲染中关键路径最长的部分,而且不能并行,所以如果能将数据请求提前,可以极大程度上缩短页面内容的渲染完成时间。那怎么将请求数据提前呢?建议采用首屏数据渐进式预加载的优化思路,具体如下:
1.优化首屏数据加载节点的速度。

2.预先加载首屏数据,使得多个串行节点并行化。

接下来详细介绍优化步骤,第1点会在第一步优化中体现,但核心思路和主要优化收益更多体现在第2点:多个串行节点并行化。
Step1:资源文件下载与首屏数据请求节点并行
为了达到资源下载与数据请求并行的效果,我们充分利用了 HTTP Chunk 传输与浏览器的渐进式渲染特性:
将入口页分为静态片段和数据片段:静态片段包含了各个资源标签 (script,link),静态的导航栏,加载指示器等;数据片段则是包含首屏数据的内联脚本,大至如下:

<script>window.__APP_DATA__ = { /* 相关的首屏数据 */ };</script>

复制代码浏览器请求入口页时,入口页服务器 并行 做以下操作:

HTTP Chunk 方式输出静态片段

请求首屏数据并在所有数据请求完成后将数据片段和应用初始化代码返回给浏览器。

注:http chunk 方式输出在 NodeJS 中及其容易满足,简单的 res.write(chunk) 即可。
Step2:应用初始化,资源文件下载,首屏数据请求节点并行
在 Step1 的基础上继续分析,应用初始化节点耗时也很明显,同时该节点要进行必须等待资源文件下载完毕,但理论上可以不依赖我们的首屏数据,还是可以让其和首屏数据请求并行。这里我们无法在 Step1 方案上直接将应用初始化和数据请求并行化,主要原因在于当首屏数据请求时间大于资源加载+应用初始化完成时间时,应用会在没有数据的情况下进入首屏渲染节点,从而导致异常。
解决方案是将数据片段的输出变成 promise 片段:

pending promise 片段,与静态片段一起输出,大概如下:


```javascript
<script>
window.__APP_DATA__ = {
 RESOLVERS: {}
 userInfo: new Promise((resolve, reject) => {
   // 超时认为失败
   let timer = setTimeout(reject.bind(null, {message: 'timeout'}), 12000);
   window.__APP_DATA__.userInfo = (err, data) => {
     clearTimeout(timer);
     err ? reject(err) : resolve(data)
   }
 })
};
</script>

resolve promise 片段,该片段在数据请求成功返回后输出,大概如下:

```javascript
<script>window.__APP_DATA__.RESOLVERS.userInfo(null, data); </script>

复制代码
reject promise 片段,该片段在数据请求失败后输出,大概如下:

<script>window.__APP_DATA__.RESOLVERS.userInfo(error); </script>

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

3.模块化资源并行下载

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

4.inline 首屏必备的 CSS 和 JavaScript

通常为了在 HTML 加载完成时能使浏览器中有基本的样式,需要将页面渲染时必备的 CSS 和 JavaScript 通过

<!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:#eee;
    }
    </style>
</head>
<body>
</body>
</html>

复制代码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>
(4).尝试使用 PWA 模式

PWA(Progressive Web Apps)是 Google 提出的用前沿的 Web 技术为网页提供 App 使用体验的一系列方案。

图片类
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="https://user-gold-cdn.xitu.io/2017/12/29/160a1604ef450396" alt="webp格式图片" >
4.图片懒加载

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

<img data-src="https://user-gold-cdn.xitu.io/2017/12/29/160a1604f3efd980" alt="懒加载图片" >
5.使用 MediaQuery 或 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 以内。如果用户上传的图片过大,建议设置告警系统,帮助我们观察了解整个网站的图片流量情况,做出进一步的改善。

8.强缓存策略

对于一些 永远不会变 的图片可以使用强缓存的方式缓存在用户的浏览器上。

JavaScript 脚本类
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 代替连接符+,推荐使用 ECMAScript6 的字符串模板

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

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

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

渲染类
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 图形处理加速,让动画过程更加流畅,但需要注意的是,在 Native WebView 下 GPU 加速有几率产生 App Crash。

-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 声明会增加字体的大小计算,而且也没有必要的。

8.做好脚本容错

脚本容错可以避免非正常环境的执行错误影响页面的加载和不相关功能的使用

架构协议类

1.尝试使用 SPDY 和 HTTP2

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

2.使用后端数据渲染

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

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

可以尝试使用 NativeView 的 MNV* 开发模式来避免 HTML DOM 性能慢的问题,目前使用 MNV* 的开发模式已经可以将页面内容渲染体验做到接近客户端 Native 应用的体验了。但需要避免 js Framework 和 native Framework 的频繁交互。

  • 3
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
学习CSS3是非常重要的,因为它是网页设计中不可或缺的一部分。CSS3CSS的最新版本,引入了许多新的特性和功能,使得我们可以更加灵活地设计和样式化网页。 首先,学习CSS3可以帮助我们实现更多样化的网页设计。它提供了丰富的选择器和样式属性,可以创建出各种不同风格的页面布局和样式。比如,我们可以使用CSS3中的渐变背景、阴影效果和过渡动画等功能,使得网页更加生动、吸引人。 其次,学习CSS3还可以提高网页的响应式设计能力。CSS3引入了媒体查询功能,可以根据用户设备的不同来调整网页的样式和布局。这样,我们可以为不同的设备(如手机、平板电脑和桌面电脑)设计出最优的用户体验,提高网页的可用性和易用性。 此外,学习CSS3还可以提高网页的性能和加载速度。CSS3中引入了一些优化技术,如CSS精灵、动画效果硬件加速和过渡效果缓存等,可以减少浏览器对网页的解析时间,提升网页的加载速度和性能。 最后,学习CSS3有助于提升我们的职业竞争力。作为一门常用的前端技术,熟练掌握CSS3可以为我们在网页设计和开发领域找到更多的就业机会。无论是企业招聘要求还是个人项目需求,对CSS3的掌握都是非常重要的。 综上所述,学习CSS3是非常必要的。不仅可以帮助我们实现更多样化的网页设计,提高网页的响应式设计能力,还可以提升网页的性能和加载速度,提升我们的职业竞争力。因此,我强烈建议大家将重点放在学习CSS3上。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值