Warning: Illegal offset type in isset or empty in /www/wwwroot/www.moyuseo.com/wp-content/themes/justnews/themer/core/wpcom.php on line 263
Warning: Illegal offset type in isset or empty in /www/wwwroot/www.moyuseo.com/wp-content/themes/justnews/themer/core/wpcom.php on line 264
Warning: Illegal offset type in isset or empty in /www/wwwroot/www.moyuseo.com/wp-content/themes/justnews/themer/core/wpcom.php on line 290
Warning: Illegal offset type in isset or empty in /www/wwwroot/www.moyuseo.com/wp-content/themes/justnews/themer/core/wpcom.php on line 291
Warning: Illegal offset type in isset or empty in /www/wwwroot/www.moyuseo.com/wp-content/themes/justnews/themer/core/wpcom.php on line 263
Warning: Illegal offset type in isset or empty in /www/wwwroot/www.moyuseo.com/wp-content/themes/justnews/themer/core/wpcom.php on line 264
Warning: Illegal offset type in isset or empty in /www/wwwroot/www.moyuseo.com/wp-content/themes/justnews/themer/core/wpcom.php on line 290
Warning: Illegal offset type in isset or empty in /www/wwwroot/www.moyuseo.com/wp-content/themes/justnews/themer/core/wpcom.php on line 291
作为面向用户的第一屏,第一屏的重要性不言而喻。如何加快加载速度是一个非常重要的课程。
本文解释了作者优化个人博客网站速度的经验。
效果体验地址:http://biaochenxuying.cn
1. 用户期待的速度体验
2018 8月,百度搜索资源平台发布的百度移动搜索登陆页体验白皮书 4.0 :页面首屏内容应在 1.5 秒内加载完成。
也许有些人有疑问:为什么是 1.5 秒内?哪些方式可加快加载速度?以下将为您解答这些疑问!
在移动互联网时代,用户对网页开放速度的要求越来越高。百度用户体验部的研究表明,页面放弃率与页面开放时间的关系如下图所示:
根据百度用户体验部的研究结果,普通用户希望和可接受的页面加载时间在 3 秒内。如果页面加载时间太慢,用户会失去耐心,选择离开,这对用户和站长来说是一个很大的损失。
百度搜索资源平台支持 闪电算法 。为了保证用户体验,为优秀网站提供更多的用户机会,闪电算法于2017年 10 月初推出。
具体内容如下:
如果移动网页的主屏幕在 2 秒内打开,将在移动搜索下获得优惠待遇,以提高页面评估和流量倾斜;同时,在移动搜索页面的主屏幕上加载非常慢(3 秒或以上)的网页将被压制。
2. 分析问题
在优化之前,第一个屏幕的时间大约是 7 - 10 秒,不要太担心。
开始分析问题,先来看下 network :
主要问题:
第一篇文章的列表界面使用 4.42 秒其他后端接口也不快另外 js css 等静态文件也很大,请求时间也很长
我还用了 Lighthouse 测试和分析我的网站。
Lighthouse 是开源自动化工具,用于提高网络应用的质量。你可以把它当作 Chrome 扩展程序运行,或从命令行运行。为 Lighthouse 提供一个需要审查的网站,它将对页面进行一系列测试,然后生成一份关于页面性能的报告。
优化前:
上栏内容分别是页面性能。PWA(渐进式 Web 应用)、可访问性(无障碍)、最佳实践SEO 跑分五项指标。
下栏是每个指标的详细性能评估。
再看下 Lighthouse 对性能问题提出了可行的建议,每一个优化操作预期都将帮助我们节省时间:
主要问题从上面可以看出:
图片太大一开始,图片加载了太多
知道问题已经成功了一半,然后开始优化。
2. 优化之路
网页速度优化的方法实在太多,本文只说本次优化用到的方法。
2.1 前端优化
项目前端部分使用 react 和 antd,但是 webpack 用的还是 3.8.X 。
2.1.1 webpack 打包优化
因为 webpack4 对包装做了很多优化,比如 Tree-Shaking ,所以我用最新的 react-create-app 重建项目,升级项目,所有依赖包都是目前最新的稳定版,webpack 也升级到 4.28.3 。
用最新 react-create-app 创建的许多项目配置都很好。作者只修改了两个地方。
对包装配置进行了修改webpack.config.js 这一行代码:// Source maps are resource heavy and can cause out of memory issue for large source files.
const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== false;
将上述代码修改为:
const shouldUseSourceMap = process.env.NODE_ENV === production ? false : true;
在生产环境下,打包去掉 SourceMap,静态文件就很小了,从 13M 变成了 3M 。
还修改了图片包装尺寸的限制,小于 40K 图片会变成 base64 图片格式。{
test:[/\\.bmp$/,/\\.gif$/,/\\.jpe?g$/,/\\.png$/,/\\.jpg$/,/\\.svg$/],
loader: require.resolve(url-loader),
options:{
limit: 4万,/ 将默认 1万 修改为 40000
name: static/media/[name].[hash:8].[ext],
},
}
2.1.2 删除无用文件
比如之前可能觉得有用的文件,后来发现不用了,注释或者删除,比如 reducers 里面的 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
const rootReducer = (history) => combineReducers({
// home,
user,
articles,
router: connectRouter(history)
})
2.1.3 图片处理
再次使用一些静态文件photoshop 改变格式或压缩,如 logo 图片,原来 111k,压缩后是 23K。主页文章列表图片修改为懒加载。
以前,我想自己实现它,因为我不想引用一个插件来实现一个懒惰的加载功能。我在网上阅读了一些关于图片懒惰加载的代码,然后结合本项目实现了图片懒惰加载功能,并添加了事件的节流(throttle)与防抖(debounce)。
代码如下:
// fn 是事件回调,delay 是时间间隔的阈值
function throttle(fn,delay){
// last 是上次触发回调的时候,timer 是定时器
let last = 0,
timer = null;
// 将throttle处理结果作为函数返回
return function(){
// 调用时保留 this 上下文
let context = this;
/ 保留调用时传入的参数
let args = arguments;
// 记录触发回调的时间
let now = new Date();
// 判断上次触发的时间和时间差是否小于时间间隔的阈值
if (now - last < delay){
// 如果时间间隔小于我们设定的时间间隔阈值,则为触发操作设置新的定时器
clearTimeout(timer);
timer = setTimeout(function(){
last = now;
fn.apply(context,args);
},delay);
}else{
// 如果时间间隔超过我们设定的时间间隔阈值,那就不等了。无论如何,反馈给用户一个响应
last = now;
fn.apply(context,args);
}
};
}
// 获取可视区域的高度
const viewHeight = window.innerHeight || document.documentElement.clientHeight;
/用新的 throttle 包装 scroll 的回调
const lazyload = throttle(() =>{
/ 获取所有图片标签
const imgs = document.querySelectorAll(#list .wrap-img img);
// num 用于统计当前显示的图片,避免每次都从第一张图开始检查是否暴露
let num = 0;
for (let i = num; i < imgs.length; i ){
/ 用可视区域的高度减去元素顶部与可视区域顶部的高度
let distance = viewHeight - imgs[i].getBoundingClientRect().top;
// 如果可视区域高度大于或等于元素顶部与可视区域顶部的高度,则表示元素暴露
if (distance >= 100){
/ 把元素写成真实的 src,展示图片
let hasLaySrc = imgs[i].getAttribute(data-has-lazy-src);
if (hasLaySrc === false){
imgs[i].src = imgs[i].getAttribute(data-src);
imgs[i].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。
后端的主要问题是接口速度很慢,尤其是文章列表的接口,已经是分页请求数据了。为什么还这么慢?
所以查看了接口返回内容之后,发现返回了很多列表不展示的字段内容,特别是文章内容已经返回,文章内容非常大,占用了大量的资源和带宽,从而延长接口消耗的时间。
从上图可以看出,文章列表的接口只需返回文章的 标题、描述、封面、查看、评论、喜欢和时间。
因此,注释或删除不需要显示到前端的字段。
// 待返回的字段
let fields ={
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,{n} };{n}
同样对其他的接口都做了这个处理。
后端做了处理之后,所有的接口速度都加快了,特别是文章列表接口,只用了 0.04 - 0.05 秒左右,相比之前的 4.3 秒,速度提高了 100 倍,简直不要太爽, 效果如下:
此刻心情如下:
2.3 服务器优化
原创文章,作者:墨羽SEO,如若转载,请注明出处:https://www.moyuseo.com/tutorials/wzyh/21750.html