浏览器渲染机制
- 浏览器使用流式布局模型
- 会将HTML解析成DOM,将CSS解析成CSSOM,DOM与CSSOM合并形成了RenderTree。
- 有了RenderTree我们就可以知道节点的样式,根据节点样式计算他们在页面上的大小和位置等
- 最后将他们绘制在页面上。
重绘
因为样式的更改引起的页面重新绘制。
回流
因为布局的更改引起的改变叫做回流。
减少重绘及回流的操作
-
css
- 使用transform代替top
- 使用visibility: hidden代替display: none;前者引起重绘,后者引起回流
- 避免使用特别具体的css选择器,尽量使结构层级扁平化。
-
js
- 避免频繁操作DOM和样式
- 尽量避免读取 offsetTop, clientTop, scrollTop, height, width等属性的值。
web worker
js运行在浏览器中,是单线程的;每个window一个js线程;但是浏览器不是单线程的,如:Webkit或是Gecko引擎,都可能有如下线程:
js引擎线程
页面渲染线程
浏览器事件触发线程
http请求线程
特别注意:js仍然是单线程的,web worker只是浏览器(宿主环境)提供的一个能力/api。
- web worker的特点
(1) 文件限制 worker线程无法读取本地文件(file://),他所加载的文件必须来自于网络(http://)
(2) 同源限制 分配给 Worker 线程运行的脚本文件,必须与主线程的脚本文件同源。
(3) DOM限制 无法读取主线程DOM对象,无法使用document、window、parent这些对象,可以使用navigator对象和location对象
(4) 通信限制 Worker线程和主线程不在同一个上下文环境,它们必须通过消息完成通信。
(5) 脚本限制 Worker线程不能执行alert()方法和confirm()方法,但可以使用 XMLHttpRequest 对象发出 AJAX 请求。
- react中应用 专用线程dedicated web worker
index.js
tnpm i worker-loader --save
const myWorker = require("worker-loader!./worker.js");
doTestWorker(params) {
// 1. 创建 worker
let worker = new myWorker();
// 2. 向worker子进程推送消息
worker.postMessage({params});
// 5. 监听worker子进程来的消息
worker.onmessage = function(event) {
console.log(event.data);
};
}
worker.js
onmessage = function(event) {
console.log('3. 监听主进程来的消息:', event);
for (let i = 0; i < 6; i++) {
let req = new XMLHttpRequest();
req.open('GET', '/api/user/commodity/getAllSpecNames', true);
req.onreadystatechange = () => {
if (req.readyState == 4) {
// 4. 向主进程推送消息
postMessage(req.response);
}
}
req.send(null);
}
}
- 例子 共享线程shared web worker
// main.js
var myWorker = new SharedWorker("worker.js");
myWorker.port.start();
myWorker.port.postMessage("hello, I'm main");
myWorker.port.onmessage = function(e) {
console.log('Message received from worker');
}
// worker.js
onconnect = function(e) {
var port = e.ports[0];
port.addEventListener('message', function(e) {
var workerResult = 'Result: ' + (e.data[0]);
port.postMessage(workerResult);
});
port.start();
}