课程名称: 前端工程师2022版
课程章节:移动web开发性能优化
主讲老师:Alex
课程内容:
今天学习的内容包括:
三、HTML,CSS 和 JS 中的性能优化
3-1 图片优化
1、减少HTTP请求数量
①使用CSS图画(动画)代替简单的图片CSS 画图 : https://www.webhek.com/post/40-css-shapes.html
②合并小图标(CSS Sprites)
③将小图标内嵌到HTML中 (将图片转成base64位格式,然后将base64位图标引入到页面中)
2、减少请求资源的大小
①使用图标字体代替简单的图标
②压缩图片
③选择合适的图片大小
④选择合适的图片类型
jpg:有损压缩,压缩率高,不支持透明 ;适用于色彩丰富、渐变色且不需要透明图片的场景
png: png-8 256色+支持透明;
png-24 2^24色+不支持透明度;
png-32 2^24色+支持透明度;
适用于大部分需要透明图片的场景;
webp:与png、jpg相比,相同的视觉体验下,图像更小;
支持有损压缩、无损压缩、透明和动画;
理论上完全可以替代png\jpg\gif等图片格式;
存在一定的兼容性;
3-2 动画优化
1、优先使用css3过渡和动画(transition\animation) ,
然后才是js动画(优先requestAnimationFrame,其次setInterval\setTimeout)
requestAnimationFrame:请求下一帧,用法和setTimeout类似,不需要时间间隔,浏览器自己渲染,16.7ms:大多数屏幕渲染的时间间隔是每秒60帧。
3-3 CSS优化
1、选择器优化
①不要使用嵌套过多过于复杂的选择器,可以通过样式直接选择
②保持简单,不要画蛇添足
③避免过多的通配符选择器,少量完全可以
④移除无匹配的样式
例如:.list{}
2、其他优化
①提取公用部分
②避免使用 CSS @import 导入 CSS
因为会发送多余的 HTTP 请求
注意: less sass 不会发送多余请求
例如:@import './reset.css';
3-4 DOM优化
1.渲染优化
①减少 DOM 元素数量和嵌套层级(一般影响不大)
②尽量避免使用 table 布局,用其他标签代替
table 是作为一个整体解析的,要等整个表格都解析完成才显示
可能很小的一点改动,也会造成整个 table 的重新布局
2、选择器优化
①优先使用 id 来获取单个元素
②获取多个元素时,尽量直接通过元素本身的 className 获取
3、减少 DOM 操作次数
①总是将选择器的选择结果缓存起来
②避免在循环中多次使用 innerHTML,在循环结束后使用一次
③使用 DocumentFragment 优化多次的 appendChild
const $liFragment = document.createDocumentFragment();
for (const item of todoDatas) {
const $li = document.createElement('li');
$li.className = 'item';
$li.innerHTML = item;
$liFragment.appendChild($li);
}
$list.appendChild($liFragment);④新创建的元素,完成必要操作后再添加到页面中
⑤不要直接通过 JS 修改元素的 style,通过添加移除 class 修改元素样式
⑥注意强制回流
当获取的属性值包括但不限于 offsetTop、offsetLeft、scrollTop、clientTop 这些“全局属性”时,需要此时页面上的其他元素的布局和样式处于最新状态,这会引起多次的回流和重绘。这样的操作称为强制回流
https://gist.github.com/paulirish/5d52fb081b3570c81e3a
可以将其结果缓存起来,需要更新的时候再更新
3-5 事件代理
1.什么是事件代理
也叫事件委托,把原本在子元素上监听的事件委托给父元素,让父元素监听
2.事件代理的实现
<input type="text" id="input" class="input" placeholder="请输入待办事项" />
<ul class="list" id="list">
<li class="item">洗衣服<a href="javascript:;" class="del">x</a></li>
<li class="item">做饭<a href="javascript:;" class="del">x</a></li>
<li class="item">写代码<a href="javascript:;" class="del">x</a></li>
</ul>
// 2.事件代理的实现
const $input = document.getElementById('input');
const $list = document.getElementById('list');
// 原理:冒泡
$list.addEventListener(
'click',
evt => {
// console.log('click');
// console.log(evt.target);
if (evt.target.classList.contains('del')) {
$list.removeChild(evt.target.parentNode);
}
},
false
);
$input.addEventListener(
'keypress',
evt => {
// console.log(evt);
if (evt.keyCode === 13) {
// 回车
if (!$input.value) return;
const $item = document.createElement('li');
const $del = document.createElement('a');
$item.className = 'item';
$del.className = 'del';
$del.href = 'javascript:;';
$item.innerHTML = $input.value;
$del.innerHTML = 'x';
// $del.addEventListener(
// 'click',
// () => {
// $list.removeChild($item);
// },
// false
// );
$item.appendChild($del);
$list.appendChild($item);
$input.value = '';
}
},
false
);3-6 事件稀释
<body style="height: 2000px">
<a href="#" id="backtop" class="backtop none">↑</a>
// 1.什么是事件稀释
// 有些事件在一段时间内会多次触发,事件稀释就是减少这些事件的触发频率
// 比如 scroll resize mousemove touchmove 等
window.addEventListener('scroll', throttle(scrollHandler), false);
const $backtop = document.getElementById('backtop');
let winHeight = window.innerHeight;
window.addEventListener(
'resize',
debounce(() => {
winHeight = window.innerHeight;
console.log(winHeight);
}),
false
);
function scrollHandler() {
console.log('scroll');
if (document.documentElement.scrollTop >= winHeight) {
$backtop.classList.remove('none');
} else {
$backtop.classList.add('none');
}
}
// 2.防抖 debounce
// 在某个时间期限内,事件处理函数只执行一次
function debounce(fn, miliseconds = 250, context) {
let timer = null;
return function (...args) {
const self = context || this;
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
fn.apply(self, args);
timer = null;
}, miliseconds);
};
}
// 3.节流 throttle
// 事件处理函数执行一次后,在某个时间期限内不再工作
function throttle(fn, miliseconds = 250, context) {
let lastEventTimestamp = null;
return function (...args) {
const self = context || this;
const now = Date.now();
if (!lastEventTimestamp || now - lastEventTimestamp >= miliseconds) {
lastEventTimestamp = now;
fn.apply(self, args);
}
};
}3-8 图片懒加载
图片懒加载时一定要设置高度否则显示不了
使用了getBoundingClientRect方法判断他的高和底部的值大小
function lazy(el){
const rect = el.getBoundingClientRect()
log(rect)
return rect.top < window.innerHeight && rect.bottom >0
}3-9 图片预加载

课程收获:
学习了移动web开发的性能优化,大概听了一下有点印象,以后用到再查,现在业务都实现不了
今天学习课程共用了2小时20分钟,复习昨天知识点10分钟

今日共计学习2小时40分钟,今天又有点懒惰了,明天加油,希望学习效率能再提高点,早点结束,早点找工作
随时随地看视频