当前位置: 首页 > 后端技术 > Node.js

网站性能优化之路——天下武功,惟快

时间:2023-04-03 11:13:08 Node.js

第一屏是面向用户的第一屏,其重要性不言而喻,如何加快加载速度是非常重要的一课。本文说明:笔者对自己搭建的个人博客站点进行速度优化的心得体会。效果体验地址:http://biaochenxuying.cn1。用户期待的极速体验2018年8月,百度搜索资源平台发布《百度移动搜索落地页体验白皮书 4.0 》,提到:页面首屏内容加载1.5秒以内。可能有人会有疑问:为什么是1.5秒以内?有哪些方法可以加快加载速度?下面就为您解答这些问题!移动互联网时代,用户对网页打开速度的要求越来越高。根据百度用户体验部的研究,页面放弃率与页面打开时间的关系如下图所示:根据百度用户体验部的研究结果,普通用户期望和接受的页面加载时间为3秒内。如果页面加载时间太慢,用户就会失去耐心而选择离开,这对用户和站长来说都是很大的损失。百度搜索资源平台由“闪电算法”支撑。为保证用户体验,给优秀站点更多用户机会,2017年10月上旬推出“闪电算法”,闪电算法具体内容如下:2秒,在移动端搜索下提升页面评价优先,获得流量倾斜;同时,手机搜索页首屏加载很慢(3秒以上)会被压制。2.分析题优化前,首屏时间大概7-10秒,不用太担心。开始分析问题,先看网络:主要问题:第一篇文章列表界面耗时4.42秒,其他后台界面速度也不快,jscss等静态文件也很大,而且请求时间也很长。使用Lighthouse测试和分析我的网站。Lighthouse是一个用于提高Web应用程序质量的开源自动化工具。您可以将其作为Chrome扩展程序或从命令行运行。为Lighthouse提供一个URL以供审查,它会对页面运行一系列测试,然后生成关于页面性能的报告。优化前:上栏内容是页面性能、PWA(渐进式网络应用)、可访问性(accessibility)、最佳实践、SEO五个指标的跑分。下栏是各指标的详细绩效评价。看一下Lighthouse对性能问题的可行建议,以及每次优化操作预计能为我们节省的时间:从上面我们可以看出主要问题:图片太大,加载的图片太多了开始知道问题所在的位置就已经成功了一半,接下来就要开始优化之路了。2.优化之路优化网页速度的方法太多了。本文只讲本次优化用到的方法。2.1前端优化本项目前端部分使用了react和antd,但webpack依然使用3.8.X。2.1.1webpack打包优化因为webpack4对打包做了很多优化,比如Tree-Shaking,所以我用最新的react-create-app重构了项目,再次升级了项目。目前所有的依赖包都是最新的稳定版,webpack也升级到了4.28.3。用最新的react-create-app创建的项目,很多配置已经很好了,笔者只修改了两个地方。打包配置修改了webpack.config.js中的这行代码://Sourcemapsareresourceheavyandcancauseoutofmemoryissueforlargesourcefiles.constshouldUseSourceMap=process.env.GENERATE_SOURCEMAP!=='false';//修改以上代码为:constshouldUseSourceMap=process.env.NODE_ENV==='production'?假:真;在生产环境中,如果去掉包中的SourceMap,静态文件会很小,从13M到3M。还修改了图片包大小限制,小于40K的图片会转为base64图片格式。{测试:[/\.bmp$/,/\.gif$/,/\.jpe?g$/,/\.png$/,/\.jpg$/,/\.svg$/],加载器:require.resolve('url-loader'),options:{limit:40000,//将默认的10000更改为40000name:'static/media/[name].[hash:8].[ext]',},}2.1.2删除无用文件。比如之前可能认为有用,后来发现不可用的文件,注释掉或者删除,比如reducer中的home模块。import{combineReducers}from'redux'import{connectRouter}from'connected-react-router'//import{home}from'./module/home'import{user}from'./module/user'import{articles}from'./module/articles'constrootReducer=(history)=>combineReducers({//home,user,articles,router:connectRouter(history)})2.1.3图片处理把一些静态文件改成photoshop格式可能是压缩了一点,比如logo图片,本来是111k,压缩后是23K。首页文章列表图片修改为采用懒加载方式加载。之前因为懒加载的功能不想用插件,想自己实现。在网上看了一些关于图片懒加载的代码,结合这个项目,实现了一个图片的懒加载功能,加入了事件节流(throttle)和debounce。代码如下://fn是事件回调,delay是时间间隔的阈值functionthrottle(fn,delay){//last是上次触发回调的时间,timer是定时器let=0,计时器=空;//将节流处理结果作为函数返回returnfunction(){//调用时保留this上下文letcontext=this;//保留调用时传入的参数letargs=arguments;//记录本次触发回调的时间letnow=+newDate();//判断上次触发时间和本次触发时间的时间差是否小于时间间隔阈值if(now-last{//获取所有图像标签constimgs=document.querySelectorAll('#list.wrap-imgimg');//num用于统计当前显示的是哪张图片,避免每次都从第一张图片开始检查是否曝光letnum=0;for(leti=num;i=100){//写入元素的真实src并显示图像让hasLaySrc=imgs[i]。getAttribute('data-has-lazy-src');如果(hasLaySrc==='false'){imgs[i].src=imgs[i].getAttribute('data-src');图像[我]。setAttribute('data-has-lazy-src',true);//}//前i张图片已经加载完毕,下次从第i+1张图片开始检查是否有num=i+1;}}},1000);注意:将真实src写入元素后,将data-has-lazy-src设置为true,避免回滚时设置真实src时,浏览器会再次请求图片。白白浪费服务器带宽详见文件文章列表2.2后端优化后端使用的技术有node、express、mongodb。后端的主要问题是接口很慢,尤其是文章列表的接口,已经分页请求数据了,为什么还是这么慢?于是查看接口返回的内容后,发现返回了很多列表中没有显示的字段内容,尤其是返回了文章的内容,而且文章的内容非常多,占用了一个大量的资源和带宽,这使得界面消耗的时间更长。从上图可以看出,文章列表接口只需要返回文章的标题、描述、封面、浏览量、评论数、点赞数和时间。所以把不需要显示给前端的字段注释掉或者删掉。//要返回的字段letfields={title:1,//author:1,//keyword:1,//content:1,desc:1,img_url:1,tags:1,category:1,//state:1,//type:1,//origin:1,//comments:1,//like_User_id:1,meta:1,create_time:1,//update_time:1,};对于其他接口也是如此。经过后台处理后,所有界面都提速了,尤其是文章列表界面,只用了0.04-0.05秒左右。与之前的4.3秒相比,速度提升了100倍。这不是太酷。效果如下:此刻的心情如下:2.3服务器优化你是不是觉得前后端都优化了,这篇文章就完了?小兄弟,你太天真了,重头戏在后面!作者服务器使用nginx代理。所做的优化如下:隐藏nginx版本号一般来说,软件漏洞都与版本有关,所以我们需要隐藏或消除web服务访问用户时显示的各种敏感信息。如何查看nginx版本号?看看网络的接口或者静态文件请求的ResponseHeaders就可以了。在设置之前,您可以看到版本号。比如我的网站版本号如下:Server:nginx/1.6.2设置后直接显示nginx,不带版本号,如下:Server:nginxenablesgzipcompressionnginx用于处理static文件的效率比web框架要高很多,因为可以使用gzip压缩协议来减小静态文件的体积来加快静态文件的加载速度,开启缓存和超时来减少对静态文件的请求次数静态文件。笔者开启gzip压缩后,请求的静态文件大小减少了约2/3。gzip上;#此命令用于开启或关闭gzip模块(on/off)gzip_buffers168k;#设置系统获取若干个缓存单元,用于存放gzip压缩后的结果数据流。168k表示8k的单位是8k,安装的原始数据大小是8k单位的16倍。申请内存gzip_comp_level6;#gzip压缩率,取值范围1-9,1压缩率最小但处理速度最快,9压缩率最大但处理速度最慢gzip_http_version1.1;#识别http的协议版本gzip_min_length256;#设置页面允许压缩的最小字节数,页面字节数从header的content-length中获取。默认为0,无论页面有多大都压缩。这里我设置为256gzip_proxiedany;#这里设置不管header是什么,都是无条件开启压缩的gzip_varyon;#AddVary:Accept-Encoding到httpheader,代理服务器的gzip_typestext/xmlapplication/xmlapplication/atom+xmlapplication/rss+xmlapplication/xhtml+xmlimage/svg+xmltext/javascriptapplication/javascriptapplication/x-javascript文本/x-json应用程序/json应用程序/x-web-app-manifest+json文本/css文本/纯文本/x-component字体/opentype字体/ttf应用程序/x-font-ttf应用程序/vnd.ms-字体对象图像/x-图标;#压缩文件类型,特别是添加字体文件类型gzip_disable"MSIE[1-6]\.(?!.*SV1)";#禁用IE6gzip,在nginx配置文件ngixn.conf中的http模块中添加以上内容。设置是否成功取决于文件请求的Content-Encoding是否为gzip。设置过期,设置缓存服务器{listen80;服务器名称本地主机;位置/{root/home/blog/blog-react/build/;索引index.html;try_files$uri$uri/@router;自动索引;7天到期;#缓存7天}}刷新请求的时候是2019年3月16日。设置成功与否可以通过查看以下字段来判断:StausCode中的formmemorycache显示文件是直接从本地浏览器请求到的,没有请求到服务器。Cache-Control的max-age=604800说明过期时间为7天。Express于2019年3月23日过期,同样是7天内过期。注意:查看上方红圈中的Disablecache是??否被勾选,表示:浏览器的每一次请求都是对服务器的一次请求,无论本地文件是否过期。所以你必须取消选中它才能看到缓存的效果。绝招:服务端渲染SSR也是笔者下一步的方向。3.1测试场景凡是偏离实际场景的优化测试结果都是耍流氓,不同时间的网速对测试结果影响很大。所以笔者的测试场景如下:笔者的服务器是阿里的,配置是入门级学生包配置,如下:b.测试网络为10M光纤宽带。3.2优化结果优化后的首屏速度为2.07秒。最终缓存的结果是0.388秒。再来看看Lighthouse的测试结果:与优化前相比,各项指标都有很大的提升。4.终极优化之路漫漫无尽,天下武功唯速成。本次优化的前后端项目均已在github上开源。欢迎收看。前端:https://github.com/biaochenxuying/blog-react后端:https://github.com/biaochenxuying/blog-nodegithub博客地址:https://github.com/biaochenxuying/blog如果文章是对你有好处或者帮助,请点赞或者star,你的点赞是我继续创作的最大动力。对全栈实践感兴趣的朋友可以扫描下方二维码关注公众号。为了长期运营,我会不定期更新有价值的内容。关注公众号,回复福利领取免费学习资料。福利详情请点击:Python,Java,Linux,Go,node,vue,react,javaScript