你不知道的 Web 性能优化 | 原力计划-重拳出击

你遇到过打开一个网站需要10秒以上的吗?这种网页响应非常缓慢,占用大量的CPU和内存,浏览起来常常有卡顿,页面的动画效果也不流畅。你会有什么反应?我猜想,大多数用户会关闭这个页面,改为访问其他网站。作为一个开发者,肯定不愿意看到这种情况,那么怎样才能提高性能呢?

有兴趣的同学可以去我的GitHub,里面有我的分享的学习过程和blog:github.com/193Eric。

使用Web Worker

Web Worker 是HTML5 提供的一个Javascript多线程解决方案,运行在浏览器后台。如我们所知js是个单线程的,js引擎在运行js的时候,不能干其他事。不过在使用中需要注意以下几点:

它是一种JavaScript 工作线程,不能直接访问DOM

能发送网络请求。

它在不用时会被中止,并在下次有需要时重启

在开发过程中,可以通过 localhost 使用服务工作线程,但如果要在网站上部署服务工作线程,需要在服务器上设置 HTTPS。

Worker 线程无法读取本地文件,即不能打开本机的文件系统(file://),它所加载的脚本,必须来自网络,这样做主要是为了安全,因为是可以通讯的,如果被别人修改了文件,引入了本地的js,进行通讯就会出现问题,所以只能访问同源的网络文件。(重点,所以本地调试的时候需要开启服务,用node或者后台语言启动

web Worker 与主线程的交互速度

我们用代码来看下从主线程 --> web worker --> 主线程 最简单的需要多长时间。

webWorker

var worker = new Worker("worker.js");

console.log(new Date().getTime()) // 开始时间

worker.postMessage("123456")

worker.onmessage = function (e) {

console.log(new Date().getTime()) // 接收时间

}

</script>

</body>

<html>


//webWorker.js

onmessage=function(evt){

vard=evt.data//通过evt.data获得发送来的数据

postMessage(d)//将获取到的数据发送会主线程

}

经过几次测试,大概的事件在30-50ms之间(当然这个值会随着机器性能问题有大有小),正常的传输速度是很快的。

web Worker 优化策略与实践

案例:大量的js计算(fibonacci数列计算)

varworker=newWorker("worker.js");

letbeginTime=newDate().getTime()

console.log(beginTime)

letfibonacci=(n)=>{

returnn<2?n:fibonacci(n-1)+fibonacci(n-2);

};

fibonacci(45)

letendTime=newDate().getTime()

console.log(`${endTime}---------历时${(endTime-beginTime)/1000}s`)

我们在主线程计算fibonacci(45)看看需要多少时间,在计算的时候页面是卡主的,会非常影响用户体验。

然后我们看看放在web worker里面是什么情况。

//index.htmlvarworker=newWorker("worker.js");letbeginTime=newDate().getTime()console.log(beginTime)worker.postMessage("fibonacci");worker.onmessage=function(e){letendTime=newDate().getTime()console.log(e,`${endTime}---------历时${(endTime-beginTime)/1000}s`)};console.log("working")console.log("working")console.log("working")

//worker.jsonmessage=function(evt){vard=evt.data;//通过evt.data获得发送来的数据letfibonacci=(n)=>{returnn<2?n:fibonacci(n-1)+fibonacci(n-2);};letdata=fibonacci(45)postMessage(data);//将获取到的数据发送会主线程}

可以看到,计算的时间是差不多的,但是并没有阻碍页面的运行。所以,一些高计算耗费时间的功能,可以放到web worker中计算完成后再返回回来。

SPA项目首页白屏问题

现在三大框架(vue,react,angular)的兴起,越来越多的项目采用SPA这种接近原生app体验的架构方式。采用SPA模式,就意味着,首页或者main.js过大,首屏加载的速度会受到很大的限制。会存在一定时间的白屏。

SPA项目因为html都是js去生成的(虚拟Dom原理),所以在js没有执行加载完之前,dom是不会有的。一开始客户端从服务端获取到html只是一个空壳,所以会显示白屏。

下面列出一些解决方案:

1.服务端渲染SSR(加快首屏加载和SEO)

SSR是一个可以有效的提高首屏渲染速度的方法,之后我会开单张去单独实践服务端渲染。

2.预渲染

预渲染是一个方案,使用爬虫技术。由于我们打包过后的都是一些js文件,使用一些技术(puppeteer)可以爬取到项目在chrome浏览器展示的页面,然后把它写入js,和打包文件一起。类似prerender-spa-plugin

不过这种技术的缺点也很明显,我们在打包过程中,所展示的页面是当时环境下的数据,也就是说如果首页有很多的动态获取的数据(比如说实时的股票价格),那如果采用这种方案,用户第一眼看到并不是当时数据,会认为是个错误信息。

3.骨架屏(占位块和图片)

骨架屏可以说现在比较实用的首屏优化技术了,方便也不是很复杂。骨架屏类似于app的启动页,一般我们进入app都会有宣传的启动页,然后才看到首页。骨架屏就是这样,用户进来首先看到的是骨架屏,然后首页渲染完之后,再把骨架屏干掉。

骨架屏主要有两种方式可以完成:

通过编译的时候自动生成还是puppeteer(上面说了预渲染也用,它主要是能在代码里面唤起chrome浏览器,或者后台唤起,也就是没有弹出浏览器,但是可以获取到真实浏览器中渲染的内容),有了它我们就能获取到浏览器里面的dom元素,然后通过对页面中元素进行删减或增添,对已有元素进行修改生成我们想要的骨架,然后将修改后的 HTML 和 CSS 样式提取出来,这样就是骨架屏了。当然遇到了图片的话,还是需要转成svg的形式,或者base64这样就不需要网络请求了。

通过设计图+布局这是一种直接重新写一个页面的方式,图片的话采用svg和base64的形式,生成一个dom,解析注入到服务器返回的index.html里面(ssr render注入)。

现在网络上的项目,最能提现的就是饿了么的h5了,我们可以通过手机浏览器打开饿了么。

我们首先看到是骨架屏,然后过一会才会看到首屏,这就是饿了么用了这种技术,很大的提高了用户的体验。page-skeleton-webpack-plugin项目地址:https://github.com/ElemeFE/page-skeleton-webpack-plugin

SSL延迟有多大?

我们知道http是经过TCP三次握手就可以成功通讯 。再来看Https链接,它也采用TCP协议发送数据,所以它也需要上面的这三步握手过程。而且,在这三步结束以后,它还有一个SSL握手。

HTTP耗时 = TCP握手 ; HTTPS耗时 = TCP握手 + SSL握手

在研究ssl延迟之前,我们先来学一个命令行工具curl,-w,–write-out参数。顾名思义,write-out的作用就是输出点什么。curl的-w参数用于在一次完整且成功的操作后输出指定格式的内容到标准输出。

主要了解下几个参数:

http_code http状态码

time_total 总时间,按秒计。

time_namelookup DNS解析时间,从请求开始到DNS解析完毕所用时间

time_connect 连接时间,从开始到建立TCP连接完成所用时间,

time_appconnect 连接建立完成时间,如SSL/SSH等建立连接或者完成三次握手时间。

我们主要用time_connect(TCP握手的耗时),time_appconnect(SSL握手的耗时)

终端输入curl -w "TCP握手的耗时: %{time_connect}, SSL握手的耗时: %{time_appconnect}\n" -so /dev/null https://www.taobao.com

我们可以看到ssl耗时是tcp的三倍左右,具体数字取决于CPU的快慢和网络状况。

所以,如果是对安全性要求不高的场合,为了提高网页性能,建议不要采用保密强度很高的数字证书。

防抖节流那些事

在开发过程中我们很多时候会碰到需要防抖和节流去解决问题。不要小看它们,没有它们的话,特定情况下的会造成很大的性能阻塞。

防抖(当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次)防抖我们可以理解为,存在一个scroll事件,只要滚动就会触发handler回调函数,防抖的处理是,等scroll事件完全停下来1000ms(这个值自行设定)之后,再出触发handler函数。

节流(当持续触发事件时,保证一定时间段内只调用一次事件处理函数)节流顾名思义,触发scroll事件的时候,并不立即执行handle函数,每隔1000ms(这个值自行设定)才会执行一次handle函数

区别:节流是每一个时间段之后就会触发一次,存在间隙的连续触发,而防抖不一样,只会在最后才触发一次。

重排与重绘的相爱相杀

从前面的文章(浏览器渲染过程剖析)已经学到了网页的生成过程。

HTML代码转化成DOM

CSS代码转化成CSSOM(CSS Object Model)

结合DOM和CSSOM,生成一棵渲染树(包含每个节点的视觉信息)

生成布局(layout),即将所有渲染树的所有节点进行平面合成

将布局绘制(paint)在屏幕上

1-3步都很快,耗时的是第四步和第五步。这两步合称”渲染“,在网上生成的过程中,网页至少会渲染一次。

有三种情况会导致浏览器重新渲染:

1.修改DOM

2.修改样式表

3.用户事件(比如鼠标悬停、页面滚动、输入框键入文字、改变窗口大小等等)

重新渲染,就需要重新生成布局和重新绘制。前者叫做"重排"(reflow),后者叫做"重绘"(repaint)。

重排和重绘不断的触发,是影响网页性能低下的根本原因。提高网页性能,就是要降低"重排"和"重绘"的频率和成本,尽量少触发重新渲染。重排必定会重绘,而重绘不一定重排。

最后

喜欢小编的可以点个赞关注小编哦,小编每天都会给大家分享文章。

我自己是一名从事了多年的前端老程序员,小编为大家准备了新出的前端编程学习资料,免费分享给大家!

如果你也想学习前端,加入此Q群:950919261

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,607评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,047评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,496评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,405评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,400评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,479评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,883评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,535评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,743评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,544评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,612评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,309评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,881评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,891评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,136评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,783评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,316评论 2 342

推荐阅读更多精彩内容

  • 你害怕与人交际吗?你是那个碰见人就会躲的人吗?在与人交流的过程中,你是否常常会尴尬到不知道说什么。 其实,没有人喜...
    译耳阅读 1,478评论 1 29
  • 喜欢最近的八点钟 夕阳西下
    zxy我在等你阅读 156评论 0 0
  • 一个普通人,怎么做对社会有价值。小文的话让我一下子清晰了。 做好自己,用自己的身体力行,影响身边的人。取得一定的成...
    56东南西阅读 244评论 0 0