缓慢的开始
一次偶然中,我发现我的个人站打开需要长达半分多种的时间,吓得我赶紧打开Network看一下到底是什么问题导致的。
Name | Size | Time |
---|---|---|
time.gif | 83.7kb | 3.87s |
main.js | 1.68mb | 31s |
事实上问题再简单不过了,资源过大了。自己自费的服务器仅仅有1M的带宽,意味着传输的每秒的极限值只能达到100kb。在硬件配置无法提升的情况下,只能通过软件的调整来进行对应的优化了。
优化
大体思路
web的优化一直是不存在标准答案的,是因为 web 在不同的应用场景下,优化的思路是不同的。但大体上思路可以归纳为预加载和懒加载两个。
比如单页应用/hash路由的技术,将多个页面打包成一个资源,在用户进行web应用操作的时候实际上网页已经加载完毕了,用户切换页面时不会进行对应资源的请求,只会进行一些页面数据请求和局部的更新,保证用户操作的流畅。实际上这是预加载的思路。
在诸如淘宝等商城首页经常会用到懒加载的优化思路。即不加载全量的资源,仅仅加载用户当前所需要的资源。在用户进行诸如滚动列表操作的时候,再去请求剩下的资源,与上一种优化思路相反。这种优化思路强调的是首屏时间,即把资源快速展现给用户,留住用户的眼球。
虽然文章开头陈述的场景毫无疑问的需要进行懒加载的优化思路,但在实际项目过程中,经常会把两种思路相结合,以针对不同的路径。
交互上
在我的理解概念中,前端应该是最贴近用户的程序员。用户行为交互上的优化不失为一个很好的办法。
试想一下,当你打开一个网站,如果是一个空白的页面没有任何提示信息时,你能耐心等待几秒。如果是一个量化加载情况进度条,你的耐心值是不是会上升很多呢。实际上可以更进一步,在大型游戏场景加载中,屏幕中间经常会轮番滚动一些场景介绍或者提示文案,让用户有事可做,以此来间接掩盖加载的冗长时间。
在服务器1M带宽的情况下,我尝试在html中加入一个loading图标(一个滚动的小章鱼),并把html和图片资源控制在100kb以内,以便实现首屏的秒现。然后加载完毕的 html 再会去拉取诸如js、css的资源。
资源的转移
媒体
在自身硬件条件有限的情况下,利用别人的硬件来实现功能,未尝不是一个明智的选择。一个网站中,大型的资源文件往往不是代码,而是图片视频等媒体文件。这些媒体资源文件有一个特征,就是不会受到跨域的限制,可以随意引入。
虽然资源可以随意引入,但这就意味着你把资源的控制权转交到了别人的手上。如果你引入资源的服务器不可靠,很可能会给你带来难以想象的灾难。因此这边推荐媒体的文件引入使用大型官网或者图床来进行解决。
大型官网的特征就是公司维度,公开,每天需要面对万级别的资源访问。这样的情况决定了大型官网的资源变动和调整及其的谨慎规范。因此去大型官网上面扒一些资源的链接来直接引入不失为一个好办法。
图床实际上就是一个静态资源服务器站,它能够上传资源,生成对应的连接,供给来使用。简单来说,就是把资源放到别人的服务器上面去管,需要的时候去别人那里拿。但是对应的好用的图床大多数都需要收费,免费的图床都对功能做了诸如访问量访问速度的诸多限制。但是对一个小型的个人网站来说,已经足够使用了。
在我的个人站中,兴趣使然上做了很多平时游戏相关的小工具。对应的背景图片,视频等资源,都是直接通过上对应的游戏官网,或者对应的游戏微博官方运营号来进行连接的扒取和使用。
代码cdn
cdn是一种静态资源部署的技术,当访问者获取某个资源的时候,能够找到离访问者最近的服务器返回对应的资源给访问者。而把代码中官方的库和框架抽出来使用cdn的方式剥离,对服务器进行减压。
webpack 的 externals 配置就是典型的优化方式。你可以在webpack的配置文件中,指定前端的代码依赖从外部获取。
module.exports = {
externals: {
'react': 'React',
},
}
进行这个配置项之后,代码中存在import xx from 'react'
部分,webpack将不会从node_modules
中引用react
进行打包,而是会去全局
找React
的变量进行引入。你可以在对应的index.html
中使用<script src="引入资源" />
来直接进行react.js
的代码引入。前端的官方库的cdn大多都可以在cdnjs.com
这个网站上找到。
结束
通过把react/react-dom/echart
等大型的官方库转移到cdn,网站的js体积缩小了一倍,加载时间也变为一半。并且在页面加载时会有可爱的章鱼在告诉你页面是 loading 状态。顺便把对应的大型图片转移到了免费的图床上面,虽然免费受限图床的加载速度会很慢。我在首页加载完成之后变回去预加载请求这些图片资源,利用浏览器缓存特性把资源缓存下来,这样在后续切换页面加载图片时就不会产生卡顿的感觉。