Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Web workerを使ってUXを向上させようとした話
Search
kurisaki kazuma
September 26, 2023
520
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Web workerを使ってUXを向上させようとした話
We Are JavaScripters! @42nd で発表した資料です。
WeJs
https://wajs.connpass.com/event/293440/
kurisaki kazuma
September 26, 2023
More Decks by kurisaki kazuma
See All by kurisaki kazuma
新規開発と並走したリファクタリング戦略.
kult0922
0
29
マインクラフトのコマンド圧縮の効率化を考えたら、40年前の論文のアルゴリズムを実装することになった話
kult0922
1
230
Next13 動的クエリ、 Server component で実装するか?Client component で実装するか?
kult0922
0
240
Featured
See All Featured
The browser strikes back
jonoalderson
0
1.9k
Reflections from 52 weeks, 52 projects
jeffersonlam
356
22k
Being A Developer After 40
akosma
PRO
92
590k
Tell your own story through comics
letsgokoyo
1
1.1k
The State of eCommerce SEO: How to Win in Today's Products SERPs - #SEOweek
aleyda
2
12k
Why Mistakes Are the Best Teachers: Turning Failure into a Pathway for Growth
auna
0
330
Site-Speed That Sticks
csswizardry
13
1.6k
Prompt Engineering for Job Search
mfonobong
0
550
The AI Search Optimization Roadmap by Aleyda Solis
aleyda
2
6.3k
世界の人気アプリ100個を分析して見えたペイウォール設計の心得
akihiro_kokubo
PRO
74
43k
Reality Check: Gamification 10 Years Later
codingconduct
0
2.4k
It's Worth the Effort
3n
188
29k
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