高性能 JavaScriptの五 -- 快響應用戶界面

{"type":"doc","content":[{"type":"heading","attrs":{"align":"center","level":1},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#40A9FF","name":"blue"}}],"text":"快速響應的用戶界面","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#FF7021","name":"orange"}}],"text":"瀏覽器UI線程","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"用於執行JavaScript和更新用戶界面的進程通常被稱爲","attrs":{}},{"type":"text","marks":[{"type":"color","attrs":{"color":"#9254DE","name":"purple"}},{"type":"strong","attrs":{}}],"text":"“瀏覽器UI線程”","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"UI線程的工作基於一個簡單的隊列系統,任務會被保存到隊列中直到進程空閒。 一旦空閒,隊列中下一個任務就被重新提取出來並運行。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"例子分析:","attrs":{}}]},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"\n\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這是一個點擊按鈕,觸發handleClick方法的例子","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"當按鈕被點擊時,會觸發UI線程來創建兩個任務並添加到隊列當中兩個任務:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"numberedlist","attrs":{"start":1,"normalizeStart":1},"content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","text":"更新按鈕樣式,表示被點擊的UI","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","text":"執行JavaScript,包含handleClick方法中的代碼","attrs":{}}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"實際上,handleClick方法執行中,會添加一個新的div元素到末尾,這又引發了一次UI變化","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"大多數瀏覽器在JavaScript運行時會停止把新任務加入UI線程的隊列中,所以JavaScript任務必須儘快結束,以避免對用戶體驗造成不良影響","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#FF7021","name":"orange"}}],"text":"瀏覽器限制","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"瀏覽器會限制JavaScript任務的運行時間","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這種限制是必須的,爲了確保某些惡意代碼不能通過永不停止的密集操作鎖住用戶的瀏覽器或計算機","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這種限制分爲兩種:","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"調用棧大小限制","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"長時間運行(long-running)腳本限制","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"長時間運行腳本限制也會被稱爲失控腳本定時器","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"原理","attrs":{}},{"type":"text","text":"是瀏覽器會記錄一個腳本的運行時間,並在達到一定限度時終止它,瀏覽器向用戶顯示一個長時間無響應對話框。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"horizontalrule","attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"chrome瀏覽器:","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/b6/b6dccc2fb02b25964036948428d18557.png","alt":null,"title":"chrome無響應彈窗","style":[{"key":"width","value":"50%"},{"key":"bordertype","value":"boxShadow"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/91/91940687db8919a824c89f543c6f0b73.png","alt":null,"title":"退出,網頁崩潰","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"boxShadow"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"horizontalrule","attrs":{}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#FF827B","name":"pink"}}],"text":"定時器","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"JavaScript 定時器可以和UI線程進行交互,有助於把運行耗時較長的腳本拆分爲較短的片段","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#FF827B","name":"pink"}}],"text":"定時器的精度","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"JavaScript定時器的延時通常不會特別精確,相差大約幾毫秒,因此定時器不可用於測量實際時間","attrs":{}},{"type":"text","text":"。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在Windows系統中定時器分辨率爲15.6毫秒,這是微軟故意設置的,它覺得設置精度更低對資源消耗過大,所以一個延時15.6毫秒的定時器將根據最後一次系統時間刷新而轉換爲0 或 15.","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"設置定時器延時小於15將會導致IE瀏覽器鎖定,所以延遲的最小值建議設置爲25以確保至少有15毫秒延遲。 ———— 這就是在寫","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"setTimeout","attrs":{}}],"attrs":{}},{"type":"text","text":"和","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"setInterval","attrs":{}}],"attrs":{}},{"type":"text","text":"定時方法時,幾乎都會把延時時間寫的超過一定毫秒以上的原因。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#FF7021","name":"orange"}}],"text":"Web Workers","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"自JavaScript誕生以來,一直是單線程的方式。 但是其實JavaScript也有","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"多線程 ","attrs":{}}],"attrs":{}},{"type":"text","text":"存在了,這就是Web Workers的功勞啦!","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"參考鏈接來嘍:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Workers_API","title":"","type":null},"content":[{"type":"text","text":"MDN中Web Workers API介紹","attrs":{}}]}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://developer.mozilla.org/zh-CN/docs/Web/API/Worker","title":"","type":null},"content":[{"type":"text","text":"MDN中 Worker 的介紹","attrs":{}}]}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"http://www.ruanyifeng.com/blog/2018/07/web-worker.html","title":"","type":null},"content":[{"type":"text","text":"阮一峯大神的博客","attrs":{}}]}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通過使用Web Workers,Web應用程序可以在獨立於主線程的後臺線程中,運行一個腳本操作。","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/7f/7f907df89813613851f0140c89d007c1.png","alt":null,"title":"理解了","style":[{"key":"width","value":"25%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"好處想必大家也都可以理解,Web Workers API引入了一個接口,能使代碼運行且不佔用瀏覽器UI線程的時間。每個新的worker都在自己的線程中運行代碼,這意味着Worker運行代碼不僅不會影響瀏覽器UI,也不會影響其他Worker中運行的代碼。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#FF827B","name":"pink"}}],"text":"Worker運行環境","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Worker 接口是 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Web Workers API","attrs":{}}],"attrs":{}},{"type":"text","text":" 的一部分,指的是一種可由腳本創建的後臺任務,任務執行中可以向其創建者收發信息。要創建一個 Worker ,只須調用 Worker(URL) 構造函數,函數參數 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"URL","attrs":{}}],"attrs":{}},{"type":"text","text":" 爲指定的腳本。Worker 也可以創建新的 Worker,當然,所有 Worker 必須與其創建者","attrs":{}},{"type":"link","attrs":{"href":"https://wiki.developer.mozilla.org/zh-CN/docs/Web/Security/Same-origin_policy","title":"","type":null},"content":[{"type":"text","text":"同源","attrs":{}}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"由於 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Web Workers","attrs":{}}],"attrs":{}},{"type":"text","text":"沒有綁定UI線程,這也就意味這它們不餓能訪問瀏覽器的許多資源了","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"JavaScript和UI共享同一進程的","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"部分原因","attrs":{}},{"type":"text","text":"是它們之間互相頻繁的訪問,因此任務失控會導致糟糕的用戶體驗","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Web Workers","attrs":{}}],"attrs":{}},{"type":"text","text":"從外部線程修改DOM會導致用戶界面出錯,但是每個","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":" Web Workers","attrs":{}}],"attrs":{}},{"type":"text","text":"都有自己的全局運行環境","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"一個navigator對象,只包括四個屬性:appName、appVersion、userAgent和platform","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"一個location對象(","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"與window.location相同,不過所有屬性都是隻讀","attrs":{}},{"type":"text","text":")","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"一個self對象,指向全局worker對象","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"一個importScripts() 方法,用來加載Worker所用到的外部JavaScript文件","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"所有的ECMAScript對象,諸如:Object、Array、Date等","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"XMLHttpRequest構造器","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"setTimeout()和setInterval()方法","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"一個close()方法,能夠立刻停止Worker運行","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"由於 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Web Workers","attrs":{}}],"attrs":{}},{"type":"text","text":"是不同的全局運行環境,所以需要我們創建一個完全獨立的js文件,裏面是在Worker中運行的代碼。然後在主流程中 new Worker(","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Web Workers","attrs":{}}],"attrs":{}},{"type":"text","text":"代碼路徑)","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":" var worker = new Worker('code.js')\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"此代碼一旦執行,將創建一個新的線程和一個新的Worker運行環境。該文件會被異步下載,知道文件下載並執行完成後才啓動此worker","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#FF827B","name":"pink"}}],"text":"示例","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"基礎示例:","attrs":{}},{"type":"text","text":"結構","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/bf/bf1a1010e790550f192f6b99bf578c23.png","alt":null,"title":"文件結構","style":[{"key":"width","value":"50%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"HTML中","attrs":{}}]},{"type":"codeblock","attrs":{"lang":"html"},"content":[{"type":"text","text":"\n \n \n\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"code.js中","attrs":{}}]},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"console.log(\"worker啓動了!\")\n// 接收傳送的數據\nonmessage = function(e) {\n console.log(e)\n}\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"達到的效果","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/e1/e11f8183f221db21c484efe23e94293a.gif","alt":null,"title":"","style":[{"key":"width","value":"50%"},{"key":"bordertype","value":"boxShadow"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"注意","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這裏我使用的軟件是vs code,如果大家直接這樣打開HTML是會找不到web worker的js文件,這是因爲上面提到的","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"同源策略","attrs":{}},{"type":"text","text":"的影響。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"可能會報下面的錯誤","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/0e/0ec38d182243372be900f4257a5f7b91.png","alt":null,"title":"同源策略錯誤","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"boxShadow"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"所以需要使其運行在服務器中,這裏爲了方便簡化,我推薦使用一款叫做","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"Live Server","attrs":{}},{"type":"text","text":"的插件。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這款插件具有實時加載功能的小型服務器,可以使用它來破解html/css/javascript,但是不能用於部署最終站點。","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/49/4989cfb2ab8fe8547ea8d91c2139dc15.png","alt":null,"title":"vs code商店","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"boxShadow"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"運行index.html文件時","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/df/df991245ca05c3741f36a119334f95a1.png","alt":null,"title":"運行Live Server","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"boxShadow"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#FF827B","name":"pink"}}],"text":"實際應用","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Web Workers","attrs":{}}],"attrs":{}},{"type":"text","text":"適用於哪些處理純數據,或者與瀏覽器UI無關的長時間運行腳本。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"一些可以受益與","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Web Workers","attrs":{}}],"attrs":{}},{"type":"text","text":"的任務:","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"編碼/解碼大字符串","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"複雜數學運算(包括圖像或視頻處理)","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"大數組排序","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#FF7021","name":"orange"}}],"text":"小節","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"JavaScript的任務最好不要超過100毫秒,過長的運行時間會導致UI更新出現明顯的延遲","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"定時器可以幫助你拆分長時間運行腳本爲一系列的小任務","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Web Workers","attrs":{}}],"attrs":{}},{"type":"text","text":"是新版瀏覽器支持的特性,是JavaScript的多線程解決方案","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}}],"text":"Web應用越複雜,管理UI線程就越重要","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"color","attrs":{"color":"#F5222D","name":"red"}}],"text":"即使JavaScript再重要,也不應該影響用戶體驗","attrs":{}}]}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章