当前位置:网站首页>Web messaging and woker classification: talking about the cross thread and cross page communication of PostMessage

Web messaging and woker classification: talking about the cross thread and cross page communication of PostMessage

2022-06-24 07:10:00 Army Zhou

web messaging

  • Communicate across documents (cross-document messaging): Cross is what we are more familiar with in China HTML5 window.postMessage() The kind of communication used ;
  • Communication channel (channel messaging):  With server-sent Events and web sockets, Cross document communication and channel communication become HTML5 communication interface “ Kit ” A useful part of .

window.postMessage

window.postMessage() Method can realize cross source communication safely .

iframe_contentWindow.postMessage(message, targetOrigin, [transfer]);

  • message Data sent , It will be Structured cloning algorithm serialize . Fu string , The structure of the object 、 Data objects ( Such as :File and ArrayBuffer) Or arrays .
  • targetOrigin: Receiving party . windowed origin Property to specify which Windows can receive message events , character string "*"( Means unlimited ) Or designate URI.
  • transfer:Transferable  object . Ownership of these objects is transferred to the recipient of the message , The sender will no longer retain ownership .

other window You can listen to distributed message:window.addEventListener("message", callback, false);

window.postMessage safety problem

If you Do not want to receive... From other websites message, Please don't do it for message Event add any event listener . It's a completely safe way to avoid security issues .

If you really want Receive... From other websites message, Please always use origin and source Property to verify the identity of the sender . Can't check origin and source Property can lead to cross site scripting attacks .——  Any window can send messages to any other window , And you can't guarantee that unknown senders won't send malicious messages . however , After authentication , You still However, you should always verify the syntax of the received message . otherwise , A security vulnerability in a website that you trust to send only trusted messages may open a cross site scripting vulnerability in your website .

Use postMessage When sending data to other windows , Always specify precise goals origin, instead of *.

Can't check origin and source Property can lead to cross site scripting attacks .

worker.postMessage

Worker  Interface is Web Workers API  Part of , Represents a background task , Create a dedicated Web worker, It only performs URL The specified script , And execute in the worker thread . The master-slave thread passes through  postMessage Send messages and  onmessage  onmessage  Receive a message

worker  Will run at the same time as the current  window In a different global context , This context is represented by an object , The standard case is DedicatedWorkerGlobalScope ( standard  workers Used by a single script ; share workers Use SharedWorkerGlobalScope).

Except that it cannot be read DOM object ( Include :document、window、parent)、 Local files 、 Dialog box (alert/confirm/prompt), Most of the window Object methods and properties are available , Such as :  WebSocketsIndexedDB、 XMLHttpRequest  etc. , Specific to see Functions and classes available to workers

Woker classification

  • Shared Workers  One Shared Workers Can be used by multiple scripts —— Even though these scripts are being written differently window、iframe perhaps worker visit ., As long as these workers In the same primary domain . share worker More than dedicated worker A little more complicated — Scripts must communicate through the active port (MessageChannel Of port1 And port2 Inter transmission ). For details, please see SharedWorker.
  • Broadcast Channel: Can achieve the same   Source   Different windows under the browser ,Tab page ,frame perhaps iframe Under the   Browser context  ( Usually different pages under the same website ) Simple communication between . On any page new BroadcastChannel('mychannel') and postMessage, Of other pages BroadcastChannel example onmessage Can receive messages It is associated with postMessage The difference is that :BroadcastChannel It can only be used for communication between pages of the same origin , and postMessage But it can be used for any communication between pages , let me put it another way ,BroadcastChannel Think of it as postMessage An example of , It takes on postMessage The function of one aspect of .
  • Service Workers  As a general web Applications 、 Browsers and the web ( If available ) Proxy services between . They aim to ( Among other things ) Create an effective offline experience , Block network requests , And take appropriate actions based on whether the network is available , Update resources residing on the server . They will also allow access to push notifications and background synchronization API.
    • Service worker Running on the worker Context , So it can't access DOM. Relative to the main driver of the application JavaScript Threads , It runs in other threads , So it won't block . It's designed to be completely asynchronous , Sync API( Such as XHR and localStorage) Can't be in service worker Use in .
    • Different from ordinary Worker,Service Worker Is a process in a browser Not the threads under the browser kernel (Service Worker It's another thread to go , It can be understood as a thread running silently behind the browser , Or it is a script running in the browser background process independent of the current page .) So after it is registered and installed , Can be used in multiple pages , It will not be destroyed because the page is closed .
    • For the sake of safety ,Service Worker Can only be used in https Or local localhost In the environment .
  • subworker: worker Can generate more worker. That's what's called subworker( still Woker), They must be hosted in the same parent page . and ,subworker analysis URI Will be relative to the father worker The address of Instead of the address of your own page . This makes worker It's easier to record their dependencies .
  • Chrome Workers: It works exactly like a standard Worker,you can do so by using ChromeWorker instead of the standard Worker object. My understanding is that It's just chrome Running worker . For details, please see ChromeWorker

Woker effect

Worker It works on 《 Optimize front-end performance at the browser level (1):Chrom Components and processes / Thread model analysis 》 It says

  • Try to avoid JS Execution time is too long , This causes the page to render inconsistently , The feeling of blocking page rendering load .Web Worker  Asynchronous optimization 》
    • establish Worker when ,JS The engine applies to the browser to open a sub thread ( The child thread is opened by the browser , Completely controlled by the main thread , And it doesn't work DOM)
    • JS Engine threads and worker Threads communicate in a specific way (postMessage API, You need to serialize objects to interact with threads for specific data ) JS The engine is single-threaded , The nature of this remains unchanged ,Worker It's understandable that the browser gives JS The plug-in with the engine on , It's designed to solve a lot of computing problems .
  • SharedWorker It's shared by all pages in the browser , Can't be used with Worker In the same way , Because it doesn't belong to some Render process , Can be for more than one Render Process sharing uses . therefore Chrome The browser is SharedWorker Create a separate process to run JavaScript Program , In the browser, each of the same JavaScript There is only one SharedWorker process , No matter how many times it was created .
    • page A Send data to worker:window.worker.port.postMessage('get'), Then open the page B, call window.worker.port.postMessage('get'), You will receive the page A Send to worker The data of .

worker Properties and methods

postMessage(data, transferList);

  • data: Data sent , Will be   Structured cloning ( structured clone)
  • transferList:Transferable An array of objects , Used to transfer ownership . If the ownership of an object is transferred , It will become unavailable in the context of sending it ( suspend ), And only when it's sent to worker Available in the .
  • Such is the transferable object ArrayBuffer,MessagePort or ImageBitmap Instance object of .transferList The array can be defaulted to not be transferred , However, it is not allowed to transfer null. It's usually MessageChannel port

terminate()

Immediately terminate Worker act . This method does not wait worker To complete the rest of its operations ;worker Will be stopped immediately

onmessage(event)  

Worker Interface onmessage Property represents a EventHandler Event handler , When message Event time , The function is called . These events belong to MessageEvent type , And when Worker Called when a child thread returns a message

  • event: event object   event.data by   structured clone data

onerror()  onmessageerror 

  • onerror A feature is an event handle , stay  Worker Of error When the event triggers and bubbles
  • onmessageerror  The event handler interface is a EventListener, stay  MessageEvent  Type of event  messageerror  Called when triggered  — in other words , The message it receives cannot be serialized  deserialized.

Woker performance optimization

worker.terminate()

After use , In order to save system resources , Must close Worker.

//  The main thread 
worker.terminate();
// Worker  Threads 
self.close();

worker.postMessage(arrayBuffer, [arrayBuffer])

Main thread and Worker The content of communication between , It can be text , It could be an object . It should be noted that , such Communication is a copy relationship , That is, value transmission, not address transmission ,Worker Modification of communication content , It doesn't affect the main thread . in fact , The operating mechanism inside the browser is , First, serialize the communication content , Then send the serialized string to Worker, The latter restores it . This can cause performance problems ! To solve this problem ,JavaScript Allows the main thread to transfer binary data directly to the child thread , But once transferred , The main thread can no longer use the binary data , This is to prevent the troublesome situation of multiple threads modifying data at the same time . This method of transferring data , be called Transferable Objects.

var ab = new ArrayBuffer(1);
worker.postMessage(ab, [ab]);

For large data processing , No performance burden .

On the same page Web Worker

Worker What is loaded is a separate JavaScript Script files , But you can also load code on the same web page as the main thread . Reduce network load time

<script id="worker" type="app/worker">
  addEventListener('message', function () {
    postMessage('some message');
  }, false);
</script>
<script>
  var blob = new Blob([document.querySelector('#worker').textContent]);
  var url = window.URL.createObjectURL(blob);
  var worker = new Worker(url);
  worker.onmessage = function (e) {
    // e.data === 'some message'
  };
</script>

First embed the script code of the web page ( Note that... Must be specified <script> Labeled type Property is a value that the browser does not recognize ), Into a binary object , Then generate... For this binary object URL, let Worker Load this URL.

woker Execute sequence in time loop

worker because JavaScript Open a new thread , perform worker Code .shareWoker Because it's different tab( One tab A process ), So a new process .

//  The main thread 
let woker = new Worker('./test2.js');
woker.onmessage = (res) => {
  console.log(res.data);
};
setTimeout(()=>{
  console.log('main')
  setTimeout(()=>{
    console.log('main2')
    setTimeout(()=>{
      console.log('main3')
    },0)
  },0)
},0)
// woker  Threads ,test2.js
setTimeout(() => {
  self.postMessage('woker1');
}, 0);
self.postMessage('woker2');

  The output order is , It's different every time , I thought there was a network request

main main2 woker2 main3 woker1

main main2 woker2 woker1 main3

main main2 main3 woker2 woker1

If it is in the bucket page , The order will not change

<script id="worker" type="app/worker">
setTimeout(() => {
  self.postMessage('woker1');
}, 0);
self.postMessage('woker2');
</script>

<script>
// let woker = new Worker('./test2.js');
var blob = new Blob([document.querySelector('#worker').textContent]);
var url = window.URL.createObjectURL(blob);
var worker = new Worker(url);
worker.onmessage = (res) => {
  console.log(res.data);
};
setTimeout(()=>{
  console.log('main')
  setTimeout(()=>{
    console.log('main2')
    setTimeout(()=>{
      console.log('main3')
    },0)
  },0)
},0)

</script>

This , still JavaScript Of event loop The event mechanism feels , Recommended reading 《 Understand javascript Implementation mechanism of : Event polling | Micro tasks and macro tasks

In the browser environment , common macro task Yes setTimeout、MessageChannel、postMessage、setImmediate. And common micro task Yes MutationObsever and Promise.then. One thing to keep in mind is that :

MessageChannel

Vue For in the macro task The implementation of the , First check whether it supports native setImmediate, This is a higher version IE and Edge Only supported features , If it is not supported, then check whether it supports native MessageChannel, If it doesn't support it, it will be downgraded to setTimeout 0.

MessageChannel usage

MessageChannel Created a communication pipeline , This pipe has two ports [port1,port2], You can go through postMessage Communicate with each other .

const channel = new MessageChannel();
let port1 = channel.port1;
let port2 = channel.port2;
port1.onmessage = function (event) {
  console.log("port1 Received from port2 The data of :" + event.data);
};
port2.onmessage = function (event) {
  console.log("port2 Received from port1 The data of :" + event.data);
};
port1.postMessage(" Send to port2");
port2.postMessage(" Send to port1");

MessageChannel It's easy to use , But the function cannot be underestimated .

MessageChannel effect

web worker Inter communication

Multiple web worker And want to web worker When communication is realized between ,MessageChannel It can be used :

var w1 = new Worker("worker1.js");
var w2 = new Worker("worker2.js");
var ch = new MessageChannel();
w1.postMessage("initial port",[ch.port1]);
w2.postMessage("initial port",[ch.port2]);
w2.onmessage = function(e){
      console.log(e.data);
}

adopt web worker Of postMessage How to put two MessageChannel Of port Pass to two web woker, Then you can go through each port Of postMessage Method passes data .

iframe Brother to brother

Tradition iframe Father son communication :

var iframe1 = document.getElementById('iframe1');
iframe1.postMessage(message, '*');

Use MessagePort.postMessage Method combines a message with MessageChannel.port2 Pass to iframe.

var iframe1 = document.getElementById('iframe1');
var iframe2 = document.getElementById('iframe2');
iframe1.contentWindow.postMessage('main','*',[port1]);
iframe2.contentWindow.postMessage('main','*',[port2]);

Code address :channel messaging basic demo

worker_threads Brother thread communication

nodejs Of MessageChannel Although with the browser , Different ways of implementation , But the usage is the same , Is a model . List here , Explain this idea .

const {isMainThread, parentPort, threadId, MessageChannel, Worker} = require('worker_threads');

Communication event message Event object

Message For the definition of events, see here

data

Contains arbitrary string data , Sent by the original script

origin

A string , Scheme containing original document 、 Domain name and port ( Such as :http://domain.example:80)

lastEventId

A string , Contains the unique identifier of the current message event .

source

Reference to the window of the original file . To be more exact , It's a WindowProxy object .

ports

An array , Include any MessagePort Object to send a message .

In cross document communication and channel communication ,lastEventId The value of is usually an empty string ;lastEventId It is used to send events on the server . If there is no... In the sending message ports, be ports The attribute value is a length of 0 Array of .

MessageEvent Inherit DOM Event interface , And attribute sharing . However , Communication events did not bubble , Can't cancel , There is no default behavior .

Service Worker

Front end cache analysis

Front end cache It can be roughly divided into http cache And Browser cache

http Cache recommended reading 《 browser http Analysis of caching mechanism : Mechanism analysis of storage policy and expiration policy 》, Let's analyze   Browser cache

storage

cookie、localStorage、sessionStorage

cookie The maximum is about 4k, Each domain has the most 50kcookie—— Different browsers have different restrictions , Generally used to store key data ( Such as user login information )

localStorage/sessionStorage Usually there are 5MB Storage space , For example, wechat articles Resources that do not need to be changed ( Such as css/js) Basically stored in localStorage Inside

Recommended reading 《 Login status control :cookies contrast sessionStorage Keep the information analyzed

Front end database :

WebSql and IndexDB, among WebSql Be abandoned by regulations , They all have about 50MB Maximum capacity of , commonly When the page store The data can be stored directly in it .

manifest cache

Has been abandoned , Because there's something unreasonable about his design , He's caching static files at the same time , It also defaults to caching html file . This leads to page updates only through manifest The version number in the document determines . therefore , The application cache is only suitable for the static website that does not change all the year round . It's so inconvenient , It's also an important reason for being abandoned .

Recommended reading 《html5 Offline caching manifest Detailed explanation 》、《HTML5 Offline storage practice manifest The pits of 》

Service Worker

Service Worker In essence, it is also used by browser cache resources , It's just that he's not just cache, through worker To further optimize .

He was based on h5 Of web worker, So it's absolutely not going to get in the way of the present js Thread execution ,sw The most important working principle is

  • Background thread : Independent of the current web thread ;
  • Network proxy : Proxy when a web page initiates a request , To cache files ;

No more details here , Open another article 《ServiceWorker Working mechanism and life cycle : Resource caching and cooperative communication processing

Reference article :

MessageChannel What is it? , How do you use it? ? https://www.jianshu.com/p/4f07ef18b5d7

HTML5 postMessage iframe Cross domain web Brief introduction of communication  https://www.zhangxinxu.com/wordpress/2012/02/html5-web-messaging-cross-document-messaging-channel-messaging/

Web Worker Use the tutorial www.ruanyifeng.com/blog/2018/07/web-worker.html

Reprint This station article 《web messaging And Woker classification : A talk postMessage Cross thread and cross page communication 》, Please indicate the source :https://www.zhoulujun.cn/html/webfront/SGML/html5/2020_0615_8465.html

原网站

版权声明
本文为[Army Zhou]所创,转载请带上原文链接,感谢
https://yzsam.com/2021/07/20210703175208541v.html