<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Web-Worker on Wayne's blog | 偉恩的部落格 | 技術博客</title><link>https://blog.wayne-project.com/tags/web-worker/</link><description>Recent content in Web-Worker on Wayne's blog | 偉恩的部落格 | 技術博客</description><generator>Hugo -- gohugo.io</generator><language>zh-tw</language><lastBuildDate>Mon, 30 Jan 2023 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.wayne-project.com/tags/web-worker/index.xml" rel="self" type="application/rss+xml"/><item><title>前端效能調校：使用 Partytown 將笨重的 JavaScript 放到 Web Workers 執行</title><link>https://blog.wayne-project.com/2023-01-30/npm-partytown-from-web-worker/</link><pubDate>Mon, 30 Jan 2023 00:00:00 +0000</pubDate><guid>https://blog.wayne-project.com/2023-01-30/npm-partytown-from-web-worker/</guid><description>&lt;img src="https://live.staticflickr.com/65535/52657535787_2ab04e0fac_o.jpg" alt="Featured image of post 前端效能調校：使用 Partytown 將笨重的 JavaScript 放到 Web Workers 執行" /&gt;&lt;style&gt;
.article-content p code {
background-color: #f5f5f5;
color: #ff3860;
}
.focus {
background: #f1e2e2;
color: #d62c2c;
padding: 0 5px;
}
&lt;/style&gt;
&lt;p&gt;&lt;a class="link" href="https://partytown.builder.io/" target="_blank" rel="noopener"
&gt;參考網站&lt;/a&gt;&lt;br&gt;
&lt;a class="link" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics" target="_blank" rel="noopener"
&gt;參考網站&lt;/a&gt;&lt;br&gt;
&lt;a class="link" href="https://developer.mozilla.org/zh-TW/docs/Web/API/Web_Workers_API/Using_web_workers" target="_blank" rel="noopener"
&gt;參考網站&lt;/a&gt;&lt;br&gt;
&lt;a class="link" href="https://blog.miniasp.com/post/2023/01/27/Partytown-Run-Third-Party-Scripts-From-Web-Worker" target="_blank" rel="noopener"
&gt;參考網站&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;前端效能調校的技法多如牛毛，但最明顯的效能殺手不外乎是 JavaScript 佔用 Main Thread 而導致頁面無法回應的狀況了。最近研究 &lt;a class="link" href="https://partytown.builder.io/" target="_blank" rel="noopener"
&gt;Partytown&lt;/a&gt; 這個函式庫，他用了一個非常巧妙的技巧，把部分 JS 自動切換到 &lt;a class="link" href="https://developer.mozilla.org/zh-TW/docs/Web/API/Web_Workers_API/Using_web_workers" target="_blank" rel="noopener"
&gt;Web Workers&lt;/a&gt; 背景執行。這篇文章我就來分享如何將 &lt;a class="link" href="https://partytown.builder.io/" target="_blank" rel="noopener"
&gt;Partytown&lt;/a&gt; 安裝到任意網站中。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="如何安裝-partytown-到任意網站"&gt;如何安裝 Partytown 到任意網站&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;透過 Partytown CLI 下載 Partytown 函式庫&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;以下命令會在當前目錄建立一個 &lt;code&gt;~partytown&lt;/code&gt; 資料夾(建議統一用這個名稱)：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npx &lt;span class="s2"&gt;&amp;#34;@builder.io/partytown&amp;#34;&lt;/span&gt; copylib ~partytown
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ol start="2"&gt;
&lt;li&gt;將 ~partytown 資料夾上傳到網站根目錄&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;如果是 ASP.NET Core 的話，可以上傳到 &lt;code&gt;wwwroot&lt;/code&gt; 目錄下，或是在 ASP.NET Core 專案根目錄輸入以下命令：&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npx &lt;span class="s2"&gt;&amp;#34;@builder.io/partytown&amp;#34;&lt;/span&gt; copylib &lt;span class="s2"&gt;&amp;#34;wwwroot\~partytown&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;如果是 Node.js 的話，可以上傳到 &lt;code&gt;public&lt;/code&gt; 目錄下，或是在 ASP.NET Core 專案根目錄輸入以下命令：&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npx &lt;span class="s2"&gt;&amp;#34;@builder.io/partytown&amp;#34;&lt;/span&gt; copylib &lt;span class="s2"&gt;&amp;#34;public/~partytown&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;你也可以設定好 &lt;code&gt;package.json&lt;/code&gt; 加入到建置流程中：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npm install &lt;span class="s2"&gt;&amp;#34;@builder.io/partytown&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h5 id="packagejson"&gt;package.json&lt;/h5&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;scripts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;build&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;npm run partytown &amp;amp;&amp;amp; ng build&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;partytown&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;partytown copylib public/~partytown&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;總之，上傳到網站根目錄就對了！(詳見 &lt;a class="link" href="https://partytown.builder.io/copy-library-files" target="_blank" rel="noopener"
&gt;Copy Library Files&lt;/a&gt; 有更完整的說明)&lt;/p&gt;
&lt;ol start="3"&gt;
&lt;li&gt;調整網頁中的 &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; 標籤語法&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;請將以下：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;...&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;全部修改為：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;text/partytown&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;...&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;就大功告成！&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="使用的注意事項"&gt;使用的注意事項&lt;/h2&gt;
&lt;p&gt;雖然 &lt;a class="link" href="https://partytown.builder.io/" target="_blank" rel="noopener"
&gt;Partytown&lt;/a&gt; 函式庫的初衷非常理想，就是管理第三方 JS 函式庫(third-party scripts)，徹底降低 JS 佔用 Main Thread 的狀況。但實際上還是有不少 JS 檔案在透過 &lt;a class="link" href="https://partytown.builder.io/" target="_blank" rel="noopener"
&gt;Partytown&lt;/a&gt; 載入到 Web Workers 執行後就掛掉了，所以實際上 &lt;a class="link" href="https://partytown.builder.io/" target="_blank" rel="noopener"
&gt;Partytown&lt;/a&gt; 並不適用於所有 JS 執行，因此&lt;strong&gt;不太建議&lt;/strong&gt;把網站上所有 JS 都改用 &lt;a class="link" href="https://partytown.builder.io/" target="_blank" rel="noopener"
&gt;Partytown&lt;/a&gt; 來載入。&lt;/p&gt;
&lt;p&gt;除此之外，目前 &lt;a class="link" href="https://partytown.builder.io/" target="_blank" rel="noopener"
&gt;Partytown&lt;/a&gt; 因為有用到 &lt;a class="link" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics" target="_blank" rel="noopener"
&gt;Atomics&lt;/a&gt; API 的關係，它的&lt;a class="link" href="https://partytown.builder.io/atomics#browser-atomics-support" target="_blank" rel="noopener"
&gt;相容性&lt;/a&gt;確實有些限制，有些太舊的手機版本是沒有支援的！詳見 &lt;a class="link" href="https://caniuse.com/mdn-javascript_builtins_atomics" target="_blank" rel="noopener"
&gt;JavaScript built-in: Atomics | Can I use&lt;/a&gt; 說明。&lt;/p&gt;
&lt;p&gt;最後要提醒大家的地方，就是使用 &lt;a class="link" href="https://partytown.builder.io/" target="_blank" rel="noopener"
&gt;Partytown&lt;/a&gt; 的 &lt;a class="link" href="https://partytown.builder.io/trade-offs" target="_blank" rel="noopener"
&gt;Trade-Offs&lt;/a&gt; (權衡)。因為這個世界沒有銀子彈，有一好就沒兩好，使用 &lt;a class="link" href="https://partytown.builder.io/" target="_blank" rel="noopener"
&gt;Partytown&lt;/a&gt; 不見得適用所有的網頁開發情境。以下是 &lt;a class="link" href="https://partytown.builder.io/" target="_blank" rel="noopener"
&gt;Partytown&lt;/a&gt; 官方認為不適用的地方：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;大量的 DOM 操作會被節流(Throttled DOM Operations)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;由於在 Web Workers 無法直接存取 DOM，所以 Partytown 會透過 onmessage 事件傳給 Main Thread 來處理，所以 DOM 處理的速度反而會變慢！&lt;/p&gt;
&lt;ol start="2"&gt;
&lt;li&gt;只要是 UI 特別吃重的 JS 函式庫，處理大量 DOM 操作，都不太適合用 Partytown 來管理&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;如果執行實際效果不理想，其實就這個 JS 不要用 Partytown 即可！&lt;/p&gt;
&lt;ol start="3"&gt;
&lt;li&gt;若第三方函式庫在載入時沒有設定 CORS Headers 的話，透過 Partytown 是無法載入的&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;必須透過 &lt;a class="link" href="https://partytown.builder.io/proxying-requests" target="_blank" rel="noopener"
&gt;Proxying Requests&lt;/a&gt; 從**相同來源(Same-origin)**載入！&lt;/p&gt;
&lt;ol start="4"&gt;
&lt;li&gt;事件處理只要用到 &lt;code&gt;event.preventDefault()&lt;/code&gt; 就會失效&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;透過 Web Workers 執行 event callback 會導致 &lt;code&gt;event.preventDefault()&lt;/code&gt; 的行為失效！&lt;/p&gt;
&lt;ol start="5"&gt;
&lt;li&gt;若透過 Partytown 管理的 JS 動態建立 &lt;code&gt;iframe&lt;/code&gt; 的話，&lt;code&gt;document.cookie&lt;/code&gt;、&lt;code&gt;localStorage&lt;/code&gt; 與 &lt;code&gt;sessionStorage&lt;/code&gt; 都會讀不到！&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;基本上程式不會報錯，但就是沒效果，所以使用上要注意！&lt;/p&gt;
&lt;ol start="6"&gt;
&lt;li&gt;透過 &lt;code&gt;setInterval()&lt;/code&gt; 不斷的對 &lt;code&gt;document&lt;/code&gt; 進行 DOM 操作&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;這也會失去使用 Partytown 的價值，因為頻繁的 DOM 操作反而會讓 Web Workers 過於忙碌！&lt;/p&gt;
&lt;p&gt;目前確定很適合用 &lt;a class="link" href="https://partytown.builder.io/" target="_blank" rel="noopener"
&gt;Partytown&lt;/a&gt; 來管理的第三方函式庫，從官網是有整理出來的，大家可以多多利用，照著官網設定即可：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://partytown.builder.io/common-services" target="_blank" rel="noopener"
&gt;Common Services&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://partytown.builder.io/facebook-pixel" target="_blank" rel="noopener"
&gt;Facebook Pixel&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://partytown.builder.io/google-tag-manager" target="_blank" rel="noopener"
&gt;Google Tag Manager&lt;/a&gt; (GTM)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;</description></item></channel></rss>