Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Web workerを使ってUXを向上させようとした話
Search
kurisaki kazuma
September 26, 2023
1
460
Web workerを使ってUXを向上させようとした話
We Are JavaScripters! @42nd で発表した資料です。
WeJs
https://wajs.connpass.com/event/293440/
kurisaki kazuma
September 26, 2023
Tweet
Share
More Decks by kurisaki kazuma
See All by kurisaki kazuma
新規開発と並走したリファクタリング戦略.
kult0922
0
19
マインクラフトのコマンド圧縮の効率化を考えたら、40年前の論文のアルゴリズムを実装することになった話
kult0922
1
180
Next13 動的クエリ、 Server component で実装するか?Client component で実装するか?
kult0922
0
220
Featured
See All Featured
Design of three-dimensional binary manipulators for pick-and-place task avoiding obstacles (IECON2024)
konakalab
0
330
Thoughts on Productivity
jonyablonski
73
5k
How to build a perfect <img>
jonoalderson
1
4.8k
SEO Brein meetup: CTRL+C is not how to scale international SEO
lindahogenes
0
2.3k
Balancing Empowerment & Direction
lara
5
840
Leading Effective Engineering Teams in the AI Era
addyosmani
9
1.5k
Rebuilding a faster, lazier Slack
samanthasiow
85
9.3k
Claude Code どこまでも/ Claude Code Everywhere
nwiizo
61
51k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
55
3.2k
Measuring Dark Social's Impact On Conversion and Attribution
stephenakadiri
1
100
Leveraging LLMs for student feedback in introductory data science courses - posit::conf(2025)
minecr
0
110
Measuring & Analyzing Core Web Vitals
bluesmoon
9
730
Transcript
Web worker を使って UX を向上させようとした話 1
自己紹介 栗崎一真 フロントエンドエンジニア 2021 卒 楽天グループ株式会社 AI SHIFT (サイバーエージェント) X:
@KK_sep_TT GitHub: @kult0922 趣味 個人開発 旅行 ポーカー 2
はじめに 写真からマインクラフトのドット絵に変換するサービスを開発しています https://www.minecraft-dot.pictures 3
UX 改善したいところ 変換中に画面が固まらないようにしたい JS で画像処理を行っているので画面をロックしてしまう 変換中はローディングのアニメーションを出したい あったら嬉しい機能 変換の進捗を表示したい 4
なぜ画面がロックされてしまうのか JS は画面の処理をメインスレッドで行う メインスレッドで重い処理を行うと処理中は画面処理にリソースを使えない 5
そこで Web worker を使う Web worker とは メインスレッドとは独立して JS をバックグラウンドで実行できる
Web API メインスレッドのパフォーマンスに影響を与えず、時間のかかる処理ができる。 メインスレッドとは別なので UI をロックしない 6
Worker の使い方 worker を呼び出す側 worker = new Worker("worker.js"); // worker
から結果を受け取る worker.onmessage = function (event) { console.log("Received: ", event.data); }; worker.postMessage(10); // worker に 10 を引数で渡して実行 worker.js self.addEventListener("message", (e) => { const result = e.data * e.data; postMessage(result); }); 7
どこを Worker に切り出すか 時間の掛かっている処理を worker 内で行う 設計図からドット画像を構築するろころで時間がかかっていた 8
作成した Worker const constructImageFromBlueprint = (blueprint: Array<Array<string>>) => { //
設計図からドット画像を構築する処理 ... return result; }; self.addEventListener("message", (e) => { const result = constructImageFromBlueprint(e.data.blueprint); self.postMessage(result); }); 9
カスタムフックで worker の状態を管理 export function useWorker() { const [loading, setLoading]
= useState(true); const run = ( ) => { setLoading(true); const worker = new Worker( new URL("./worker", import.meta.url) ); worker.onmessage = function (e) { // worker 処理完了 setLoading(false); ... }; worker.postMessage({ blueprint, blockImageDataDict }); }; return { loading, run }; } 10
ここまで 画面のロックを防ぎたい ローディングを表示したい 進捗を知りたい 11
worker 側から進捗を伝える worker とメインスレッドの共有方法は基本的には message だけ 進捗も結果と同様 message として送る type
プロパティで進捗地なのか結果なのかを判定 const constructImageFromBlueprint = (blueprint: Array<Array<string>>) => { for (let i = 0; i < rows; i++) { if (i % step === 0) { progress += stepNum; self.postMessage({ type: "loading", payload: progress, }); } ... } self.postMessage({ type: "complete", payload: result, }); }; 12
カスタムフックも進捗を受け取るように修正 export function useImageGeneratorWorker() { const [progress, setProgress] = useState(0);
// 進捗 const [loading, setLoading] = useState(true); const run = (blueprint: string[][]) => { setLoading(true); const worker = new Worker( new URL("../worker/imageGeneratorWorker", import.meta.url) ); worker.onmessage = function (e) { if (e.data.type == "loading") { setProgress(e.data.payload); // <- 進捗を受け取る return; } setLoading(false); }; worker.postMessage({ blueprint, blockImageDataDict }); }; return { progress, loading, run }; // <- 進捗も返す } 13
結果 https://www.minecraft-dot.pictures 14
requestAnimationFrame との比較 同じようなことは requestAnimationFrame をつかってもできる。 worker マルチスレッドなので環境によってはパフォーマンスがいい worker ファイルを作成して message
でメインスレッドとやり取り message のやり取りはコピーなので大きいデータのやり取りでパフォーマンスが落ちる 可能性がある reauestnimationFrame シングルスレッドですべての処理を行う 重い処理を関数に分割して再帰的に実行 15
まとめ Web worker を使用することでメインスレッドをロックせずに重い処理を実行 進捗も message で送ることでプログレスバーを実装 16
17