1. web Worker多线程
1.1 了解web worder
JS单线程的问题
- 一次只能做一件事。会造成阻塞
- 多核 CPU 中,单线程无法发挥计算机的计算能力
Web Worker 的作用,就是为 JavaScript 创造多线程环境,允许主线程创建 Worker 线程,将一些任务分配给后者运行。在主线程运行的同时,Worker 线程在后台运行,两者互不干扰。等到 Worker 线程完成计算任务,再把结果返回给主线程。
worker好处:
- 计算密集型或高延迟的任务被worker现成负担了,不会被阻塞或拖慢
worker的问题:
- Worker 线程一旦新建成功,就会始终运行, 会浪费资源,所以不用要及时关闭
1.2 主线程
1. 创建worker线程
主线程通过new
命令,调用Worker()
构造函数,新建一个 Worker 线程。
var worker = new Worker('work.js');
Worker()
构造函数的参数是一个脚本文件,该文件就是 Worker 线程所要执行的任务。由于 Worker 不能读取本地文件,所以这个脚本必须来自网络。如果下载没有成功(比如404错误),Worker 就会默默地失败。
2. 主线程向Worker线程发布数据
主线程通过调用worker.postMessage()
方法,向 Worker线程 发消息。
worker.postMessage('Hello World');
postMessage()方法的参数:
就是主线程传给 Worker 的数据。它可以是各种数据类型,包括二进制数据。
3. 主线程监听Worker线程发送的信息
主线程通过worker.onmessage
指定监听函数,接收子线程发回来的消息。
worker.onmessage = function (event) {
// 获取worker线程传递过来的数据
console.log(event.data);
}
通过事件对象的data
属性可以获取 Worker 发来的数据。
4. 关闭Worker线程
在Worker 完成任务以后,主线程就可以把它关闭
worker.terminate();
1.3 Worker 线程
1. 监听主线程发布的数据
Worker 线程通过监听message
事件。来获取主线程发布的数据
self.addEventListener('message', function (e) {
self.postMessage( e.data);
},
self
代表子线程自身,即子线程的全局对象。
事件对象的data
属性包含主线程发来的数据。
2. 向主线程发布消息
Worker线程通过self.postMessage()
方法用来向主线程发送消息。
self.postMessage( e.data);
3. 关闭自身线程
Worker 线程 可以通过 close方法关闭Worker线程
self.close();
例子:
两个同步语句,不存在阻塞问题
<body>
<div id="box"></div>
<div id="wrap"></div>
<script>
//两个同步语句,不存在阻塞问题
box.innerHTML='111'
wrap.innerHTML ='222'
</script>
存在阻塞问题的语句,前面同步完成后才能渲染222
<div id="box"></div>
<div id="wrap"></div>
<script>
//存在阻塞问题的语句,前面同步完成后才能渲染222
document.onclick = function () {
let count = 0;
for (let i = 0; i < 1000000; i++) {
count++
}
box.innerHTML = count;
wrap.innerHTML = 222
}
</script>
先打印主线程,再打印子线程(理解子线程)
<div id="box"></div>
<div id="wrap"></div>
<script>
//先打印主线程,再打印子线程(理解子线程)
document.onclick = function () {
// let count = 0;
// for (let i = 0; i < 1000000; i++) {
// count++
// }
// 创建一个子线程
console.log('主线程11')
let work =new Worker('worker.js')//需要创建worker.js文件,写点内容console.log('子线程');console.log(this === self)//this 与 self都表示当前子线程对象。控制台最终结果是子线程最后打印
console.log('主线程work',work)
// box.innerHTML = count;
wrap.innerHTML = 222
}
</script>
主线程将复杂的任务放在子线程中执行,并向子线程发送数据
// index.html(主线程中的代码)
<body>
<div id="box"></div>
<div id="wrap"></div>
<script>
document.onclick = function () {
// 第一步创建一个子线程
let work = new Worker('worker.js')//需要创建worker.js文件,写点内容console.log('子线程');console.log(this === self)//this 与 self都表示当前子线程对象。控制台最终结果是子线程最后打印
//第二步 将复杂的任务放在子线程中执行,并向子线程发送数据
work.postMessage(10000000);
// 第三步 主线程监听事件接收子线程数据
work.addEventListener('message', function (ev) {
console.log('work ev', ev)
box.innerHTML = ev.data; //先渲染222,然后再渲染这里的值1000000。这样就不会阻塞 wrap.innerHTML = 222的执行
this.terminate()//这里执行完了,子线程还是在工作的,所以要通过主线程关闭子线程(外部关闭子线程)。也可在子线程内部关闭self.close()
}, false)
wrap.innerHTML = 222
}
</script>
</body>
//worker.js(子线程中的代码)
//子线程接收数据,监听message事件
this.addEventListener('message', function (ev) {
console.log(ev)//控制台中就能看到事件对象,事件对象中的data就是传过来的数据
let count = 0;
for (let i = 0; i < ev.data; i++) {
count++
}
// console.log(count)
// 子线程通过this 或self把结果传给主线程
this.postMessage(count)
// self.close()//关闭线程
}, false)
1.4 多线程注意点
- 同源限制: Worker线程运行的脚本文件必须与主线程的脚本文件同源
- DOM限制: Worder线程中不能使用document,window,parent的对象
- 文件限制: Worder 线程无法读取本地文件,所加载的必须是网络文件
2. 离线存储 (offline application)
HTML5 中可以让我们构建一个离线缓存的应用, 需要创建cache manifest
什么是离线存储
离线存储是让web应用在离线的情况下继续使用, 通过manifest文件指明需要缓存的资源
2.1 离线缓存的优势
可以配置需要缓存的资源
离线浏览 - 用户可在应用离线时使用它们
速度 - 已缓存资源加载得更快, 增强用户体验
减少请求,缓解服务器负担
2.2 缓存清单
缓存清单就是一个普通的文件,其中列出浏览器应该缓存的资源,以供离线时访问. 推荐使用.appcache为后缀名
2.3 缓存使用
html标签里使用缓存清单
<--离线时也能访问到这个页面,在html标签里加上 manifest="xxxxx.appcache"就可以。将来浏览器就会请求这个文件,这个文件里说明哪些文件需要缓存,哪些文件不需要缓存-->
<html lang = "en" manifest="xxxxx.appcache">
2.4 manifest(appcache) 文件格式
顶行写 CACHE MANIFEST
CACHE: 指定我们需要缓存的静态资源, 入css, image, js等
NETWORK: (可选) 指定需要在线访问的资源, 可以使用通配符
FALLBACK: (可选) 当被缓存的文件找不到时的备用资源
2.5 其他
CACHE 可以省略, 这种情况下需要缓存的资源写在CACHE MANIFESR
可以指定多个CACHE: NETWORK, FALLBACK 无顺序限制
-
表示注释
CACHE MANIFEST
#这是需要缓存资源CACHE:
/index.html/222.jpg/333.jpg
#表示必须在有网络的情况下使用NETWORK:
/index.css*
#如果缓存的资源找不到使用备用资源FALLBACK:
/222.jpg /333.jpg
在个互联网中能区分文件类型,因为所有的文件都有一个MIME( 多用途互联网邮件扩展类型 )