一次网站的性能优化之路 -- 天下武功,唯快不破 (2)

打包配置修改了 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: 40000, // 把默认的 10000 修改为 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。

后端主要问题是接口速度很慢,特别是文章列表的接口,已经是分页请求数据了,为什么还那么慢呢 ?

所以查看了接口返回内容之后,发现返回了很多列表不展示的字段内容,特别是文章内容都返回了,而文章内容是很大的,占用了很多资源与带宽,从而使接口消耗的时间加长

列表

从上图可以看出文章列表接口只要返回文章的 标题、描述、封面、查看数,评论数、点赞数和时间即可。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zydgxp.html