注:本文是纯技术探讨文,无图无笑点,但愿您喜欢 #####一.前言 软件行业极其缺少前端人才这是圈内的共识了,某种程度上讲,同等水平前端的工资都要比后端高上很多,而圈内的另外一项共识则是——网页是公司的脸面!css
几年前,谷歌的一项统计代表,若是亚马逊页面加载每慢 100ms,将影响他们 1% 的收入;若是谷歌页面加载慢 500ms,流量将锐减 20%,这个数据如今必将更加恐怖!html
在前端高性能优化(一)、(二)中,笔者介绍了一些关于前端优化的技术,这些技术都依赖于前人的辛苦努力,但咱们仍要明白的是,前端的状况十分复杂,优化前端性能是必须因地制宜、因时制宜。前端
在本篇文章中,主要介绍的就是在一些条件下,传统优化 JavaScript 的技术并不像咱们认为的那样适用。 #####二.JavaScript 模块化误区 加快 JavaScript 加载和执行的速度,一直是前端优化的一个热点。所以咱们先来讲下 JavaScript 模块化技术的相关知识,但愿经过实践来体现模块化技术在使用时的注意事项,避免滥用。web
为何会有模块化技术?后端
长久以来,编写 JavaScript 一直以文件为单位,通常一个类型的 JavaScript 功能代码会被放在同一个文件里。在一个页面里,引用的文件通常是写死的,也就是无论页面用不用,只要你引入了这个文件,这个文件就会被加载。浏览器
举个例子,咱们开发了一个内容复杂、功能强大的页面,JavaScript 文件大到 500K,当页面费劲的把这 500K 加载下来,然而用户真正只使用了这 500K 里极少的一部分功能,但咱们又不得不把这 500K 加载下来,由于不一样的用户使用的功能点可能不同,咱们必须知足全部需求。性能优化
而模块化技术提出 按需加载,也就是当用户触发该功能的时候,那个功能才真正的被加载。比如 500K 被拆成了 50 个模块,每一个模块 10K,当用户触发一个功能时,加载 10K,再触发再加载,以这样懒加载的方式来加载模块,能够很大的提升响应速度。这样,管理模块懒加载的技术也随之诞生。服务器
模块化技术并不是处处靠谱!!微信
以前笔者在网上搜索到了一个模块化技术:SeaJS。它是一个遵循 CommonJS 规范的 JavaScript 模块加载框架,能够实现 JavaScript 的模块化开发及加载机制。与 JQuery 等 JavaScript 框架不一样,SeaJS 不会扩展封装语言特性,而只是实现 JavaScript 的模块化及按模块加载。网络
SeaJS 的主要目的是令 JavaScript 开发模块化并能够轻松愉悦进行加载,将前端工程师从繁重的 JavaScript 文件及对象依赖处理中解放出来,能够专一于代码自己的逻辑。说白了就是有 Lazy Load 的特性,用到某模块时,SeaJS 才会去加载模块的 JS 文件。咱们能够按功能划分多个模块,触发模块功能时,SeaJS 先加载功能模块的文件,而后执行相应的功能。
这个 SeaJS 拥有的特性,初看很是吸引人,它能够说是新定义了一种开发和管理 JavaScript 文件的模式。遵循这个模式,你会享受起 JavaScript 的开发。
实践证实,它也的确可使 JavaScript 模块化,根据功能划分模块,每一个模块对应一个 JavaScript 文件,当执行到模块的功能,或者你须要加载模块时,模块才会被下载,同时不会形成重复下载。这一切看起来如此的合理,如此的顺畅。。。。。
可是在使用后发现了一些 问题:因为当时开发的网站功能相对简单,JavaScript 文件并非很是大,过多的模块,反而会致使总加载的时间变多了。
因为是 Lazy Load 特性,不适合的模块划分致使网站出现反应慢的现象,缘由是得先加载模块的文件,才能执行模块的功能。当网络状况很差时,该现象表现的更为严重!!!
能够说,问题出在了对新技术的不了解上,从而出现了问题,预期是 SeaJS 能够处理 JavaScript 优化的问题,由于它具备避免加载没必要要模块的功能,结果反而南辕北辙。
总结
虽然尝试出现了问题,可是,收获也是巨大的,简单来讲就是如下两点:
1)因地制宜,根据实际须要使用模块化技术,切勿跟风技术,在本身没有彻底掌握时,谨慎用于产品中。
2)模块若是是懒加载的,粒度不能过小,也就是模块不能过小。
根据 大功能来划分模块 也是一个不错的尝试。
笔者尝试将全部模块划分为 基础模块 和 功能模块 ,基础模块包括页面头部,尾部相关的公共部分,功能模块则根据先后台划分,前台部分,又根据具体的页面来划分,能合并到一块儿的,就合并成一个模块,增长粒度。结果 JavaScript 文件减小,也达到了预期的效果。
从实际体验来看,对于流量不大的网站来讲,没有必要使用懒加载 JavaScript 的相关技术,由于自己 JavaScript 文件就不是很是大。所以在网页加载时,就能够先加载所须要的模块。避免没必要要的延迟。
#####三.JavaScript 的位置问题
这一部分,咱们来讲说 JavaScript 的位置问题对网页网站性能的影响。
为何要考虑位置问题?
其实无论是 CSS 仍是 JavaScript,都须要考虑位置的问题,由于 HTML 的渲染和加载顺序是从上往下,也就是若是前面插入了 JavaScript 的引用,那么必须等到这个 JavaScript 下载完毕才会渲染后续的部分。
所以 JavaScript 的插入位置就成为一个值得考虑的问题,由于不适合的位置可能引发渲染的延迟等,形成很差的用户体验。
传统方案带来的问题和思考
CSS 放在头部,JavaScript 放在尾部,这是传统的经验,它的好处是可让页面优先渲染, 从而页面能够快速显示。
但有事实每每没有咱们预想的那么美好。
有的时候会出现这么一种状况:当页面已经渲染完毕时,咱们马上去使用网站的功能,但不少时候 功能按钮会没有反应。缘由也很简单,就是 JavaScript 放在页面的尾部,还没来得及加载。。。。
这就纠结了。。。。
两种 JavaScript 放置方式,一种放在头部,一种放在尾部(暂时忽略部分放在头部,部分放在尾部的方式),一个牺牲了渲染速度,一个牺牲了用户体验。因此不少时候 js 的问题咱们须要作权衡。
对通常的小型网站来讲,用户体验问题要远远大于页面渲染的问题,就好比上文提到的那种功能按钮不可用的状况。并且,若是 JavaScript 不是很大的话,放在头部就很好,既不会有过久的页面空白,也能让其优先加载,两者获得了很好的平衡。
所以,不少经验上的东西并非绝对的,必定要根据实际的状况,包括功能特色、服务器网络状况等来综合考虑。
为此,笔者写下一个自认为较为合理的位置选择方案,仅供参考。
图 1. 判断 JavaScript 放置位置决策表
从上面的分类介绍,咱们也能够看出,将功能代码按类型归类到不一样的 JavaScript 文件是多么的重要,好比应该放头部和应该放尾部的代码,最好不要合并在一块儿,不要等到出问题要优化的时候再去整理和重构,这样会增长不少没必要要的工做量。
这不只仅是为本身工做负责,也是为后面要读你代码的新人负责。养成好的设计编码习惯,也是技术积累的一部分。最后再根据 JavaScript 文件的功能类型,来决定是放在页面的头部仍是尾部。
#####四.怎样肯定是否是 JavaScript 的问题? 这个问题在以前的前端高性能优化(一)、(二)中也都简单的说过,之因此在这再次说起是由于确实以为这个工具用着很舒服。
没错,就是舒服。
随着信息爆炸时代的到来,网站自己性能也深入影响着公司的形象、利益等问题。可是大多数前端测试工具都太碎片化,没有办法针对多个使用场景,并且不少都是像 yslow 这样简单打个分,也不是真实的用户体验。前一段时间在网上找到了一款前端性能优化分析工具——Browser Insight,里面的功能至关全面,并且能够针对多个使用场景,包括:PC端,移动微信,移动浏览器,移动webview,仍是 真实的用户体验,也就是说,用户访问你的网页是什么样的,从这个工具中体现出的就是什么样子的。
基于 JavaScript 这个维度 Bi 作的也是至关丰富了。
首先是 脚本错误 板块。Bi 里面能够从不一样的时间维度查看被监控页面出现过的脚本错误,具体信息包括:发生时间、设备类型、报错的浏览器及其版本号、错误堆栈信息均可以看到,不管是 线上仍是线下测试或者页面维护 都是够用了。
不但能看到时间、系统、浏览器等,还能够具体定位到出错的代码行,这个确实很方便。
图 2.Bi 脚本错误
其次是页面响应时间板块,这个算是意外的收获了。经过响应时间板块里面的慢加载追踪,能够看到本次慢加载的页面资源加载状况,而后咱们就知道该优化哪一个页面的哪些 js 、css、img等。
图 3.Bi 资源列表-时序图 #####五.前端优化?用户体验? 各位看客,若是你真能坚持看到这里,是否会以为这篇更像解决用户体验问题的文章?可是讲内心话,前端优化的最终目的,难道不是为了改善用户体验吗?
任何基于用户体验的方案,均可以叫前端优化技术。
无论使用多么好的机器、多么高的技术,响应速度问题老是避免不了的,所以纠结于什么技术来解决是不实际的。可是有一款好的工具,使用一些小技巧,也能够改善用户等待的体验。
好比,咱们为每一个非 _target 的超连接或者表单的点击,添加点击事件处理,处理逻辑也很简单,就是设置 3 秒超时,显示等待对话框。若是在 3 秒内页面发生跳转,那么这个等待对话框就不会出现,不然会弹出提示用户等待,从而及时的将响应反馈给用户,减小用户空白等待时间。
这并非什么高深的技术,可是运用这个技巧,却能够大大的改善用户体验。
各位,咱们优化的目的,就是不要让用户一直得不到响应,避免空白等待,让用户体验愈来愈好。