一、什么是前端工程化
1.目标
在前端领域,利用技术不断进步和经验逐步积累带来的各种方案,来解决在项目的开发、测试、维护阶段中遇到的低效和繁琐的问题。
2.技术
技术是一种实践,不同时期会有不同的技术来承载工程化思想。
3.原因
在项目的开发、测试、维护阶段提高效率
二、规范化
1.版本管理和开发流程规范
2.编写的规范:脚本、样式、目录结构
git 和gitflow
代码提交:
git pull
git commit
git push
git checkout//切换分支
三、模块化
1.css模块化解决
通过样式生成规则,避免冲突
scoped、css in js、css modules、BEM
个人思考:使用css预处理语言模块化
2.js模块化解决
node.js、common.js、es modules-loader
require('http')
module.exports=x
import {} from ' ./a.js'
export function M(){return 1}
3.组件化
是Web的趋势、核心思想是分治。
高内聚、低耦合
3.1 UI为主
页面上的UI块可以封装成一个组件
3.2 逻辑为主
某一个功能逻辑也可以封装成一个组件
组件内也可以包含组件
4.自动化
核心:能让机器做的事,不让人做。
4.1自动化测试
4.2自动化部署
4.3自动化初始化
4.4自动化构建
总结:带着工程化的思想去思考
一、动画的原理与实现
1.定时器改变对象的属性
2.根据新的属性重新渲染动画
动画种类:js动画、css动画、svg动画
二、js动画
优点:灵活度、可控性、性能
缺点:易用性差
1.方块旋转
class Timing {
constructor({duration, easing} = {}) {
this.startTime = Date.now();
this.duration = duration;
this.easing = easing || function(p){return p};
}
get time() {
return Date.now() - this.startTime;
}
get p() {
return this.easing(Math.min(this.time / this.duration, 1.0));
}
}
class Ticker {
tick(update, context, timing) {
let count = 0;
timing = new Timing(timing);
requestAnimationFrame(function next() {
count++;
if(update(context, {count, timing}) !== false) {
requestAnimationFrame(next);
}
});
}
}
function update({target}, {timing}) {
target.style.transform = `translate(${200 * timing.p}px, 0)`;
}
const ticker = new Ticker();
ticker.tick(update,
{target: block},
{duration: 2000}
);
2.匀速运动
function update({target}, {timing}) {
target.style.transform = `translate(${200 * timing.p}px, 0)`;
}
const ticker = new Ticker();
ticker.tick(update,
{target: block},
{duration: 2000}
);
3.平抛运动
function update({target}, {timing}) {
target.style.transform = `translate(0, ${200 * timing.p}px)`;
}
const ticker = new Ticker();
ticker.tick(update, {target: block}, {
duration: 2000,
easing: p => p ** 2,
});
4.平抛
class Timing {
constructor({duration, easing} = {}) {
this.startTime = Date.now();
this.duration = duration;
this.easing = easing || function(p){return p};
}
get time() {
return Date.now() - this.startTime;
}
get op() {
return Math.min(this.time / this.duration, 1.0);
}
get p() {
return this.easing(this.op);
}
}
function update({target}, {timing}) {
target.style.transform =
`translate(${200 * timing.op}px, ${200 * timing.p}px)`;
}
5.贝塞尔轨迹
function bezierPath(x1, y1, x2, y2, p) {
const x = 3 * x1 * p * (1 - p) ** 2 + 3 * x2 * p ** 2 * (1 - p) + p ** 3;
const y = 3 * y1 * p * (1 - p) ** 2 + 3 * y2 * p ** 2 * (1 - p) + p ** 3;
return [x, y];
}
function update({target}, {timing}) {
const [px, py] = bezierPath(0.2, 0.6, 0.8, 0.2, timing.p);
target.style.transform = `translate(${100 * px}px, ${100 * py}px)`;
}
const ticker = new Ticker();
ticker.tick(update, {target: block}, {
duration: 2000,
easing: p => p * (2 - p),
});
一、RAL模型
以用户为中心
1.response
100~300ms:轻微察觉
大于10000ms:用户会离开
目标:
在100ms内响应用户输入
2.animation
目标:10ms一帧,要平滑
不要在动画高压点处理逻辑
3.idle
目标:增加页面在100ms以内响应用户输入的几率
4.load
目标:
首屏加载连接3G缓慢的中档移动设备5s内呈现可交互内容
非首屏加载应该在2s内完成
影响因素:
网络速度
硬件
解析javascript
以用户为中心
二、工具篇
1.lighthouse
2.WebPageTest
3.chorme DevTools
三、实战篇
1.浏览器的渲染场景
js/css>计算样式>布局(可选)>绘制(可选)>渲染层合并
2.浏览器的运行机制
①构建DOM树:渲染引擎解析HTML文档,首先将标签转换成DOM树中的DOM 节点(包括js生成的标签)生成内容树;
②构建渲染树:解析对应的CSS样式文件信息(包括js生成的样式和外部css文件),和这些文件信息以及HTML中可见的指令来构建渲染树;
③布局渲染树:从根节点递归调用,计算每一个元素的大小、位置等,给出每个节点所应该在屏幕上出现的精确坐标;
④绘制渲染树:遍历渲染树,使用UI后端层来绘制每个节点。
3.性能优化方向
加载:资源效率、图片字体、关键渲染路径
渲染:js执行优化、避免大型复杂的布局、渲染层合并