SlideShare a Scribd company logo
Why we replaceTypeScript with Dart
JumperChen
About Me
• 名字: 陳威亨 – Jumper Chen
• 公司: 普奇科技 - ZK (Potix Corporation)
• 職位: R&D Director
• 負責: KeikaiTeam, QuireTeam, and ZK FrameworkTeam
• 學歷: III Java養成班 EEIT 24期 – (14 years ago)
• Personal Events:
• EnglishCareer 雜誌專訪 2019 - 藍領幹部轉職程式設計師
• 30 (遠見) 雜誌專訪 2016 - 黑手,Debug自己的人生
• iThome 雜誌專訪 2009 - 從機車行黑手變成程式開發的黑手
• iThome 雜誌專訪 2009 - IE 8有機會讓網頁開發走向標準化的時代
故事主角: (2016年的背景)
(web spreadsheet component)
Demo
2016年的春天,選新產品的語言
• Running onWeb
• Same code base for Browser and Server
• Modern Programming Language for Developers
• Static typing analysis
選了TypeScript 1.8 當作新產品的語言
• Types
• Boolean, Number, String, Array,Tuple, and so on
• Union types
• String|number
• Classes
• Public, Private, and Protected modifiers
• Interfaces
• Namespaces and Modules
• Generics
當年開發TS需要用到的3rd-party libraries
• TypeScript - tsconfig.json
• Typings - typings.json
• Node.js - package.json
• SystemJS - system-config.js
• Webpack - webpack-config.js
• ts-loader (customized)
• json-loader
• uglify-js
• babel
• ts-node
• Gulp - gulpfile.js
• TSLint - tslint.json
• JSDoc - jsdoc.json
• Mocha – (testing tool)
• … (嘎拉嘎拉)
2016冬天,一陣寒風(不是韓流)吹來,突
然間,發現了一個不好解的問題?
Circular reference issue (JS 通病)
Module A
Module BModule C
Circular reference issue (JS 通病)
Licensed under CC
選邊站? (不是 Blue vs Green)
1. Face it
• Use tools to check (unreliable)
• Lazy import modules (very easy to forget)
2. Migrate to another Lang. (Dart) but …
• 1450+ ts files already
• 350,870 lines of code (87%, 28~30w lines)
• (3~4 工人智慧)
媽祖說
叫我們酸”大的”
Dart 1 - 2016 Nov.
• Pros.
• Types
• Number, String, Boolean, List, Map, and so on.
• Classes
• No public, protected, and private
• (but If an identifier starts with an underscore (_), it’s private to its library)
• Interfaces (implicit)
• Generics
• Asynchronous functions
• async and await
• Dartium (without compiling to JS)
• Transforms (like AOP)
宅男心中的女神
Powered by JumperChen
Dart 1
• Cons.
• Not friendly to integrate with JS world
• 一個Browser,各自表述 
• Less Library
• Game-loop, R-Tree, RB-Tree, IntervalTree, BNF Parser Generator, Socket.io, Socket.io-client,
Dquery, Bootstrap, StAX XML parser …
• Small Ecosystem
• Performance issue
• String Operations (Dart String operation much slower than Java)
• https://github.com/dart-lang/sdk/issues/29131
• Map I/O (the Map implementation in dart2js is 3 times slower than JS version)
• https://github.com/dart-lang/sdk/issues/28210
• async/await syntax too slow
• Implement a fake future (calls Sync())
• https://github.com/dart-lang/sdk/issues/29189
Dart 1
• String Operations (Dart String operation much slower than Java)
FileSize Java Dart
20 MB
File Length: 20,375,011
Parsing time: 572ms
Object creation times: 3,395,835
File Length: 20,375,011
Parsing time: 938ms
Object creation times: 3,395,835
163 MB
File Length: 163,000,011
Parsing time: 4,060ms
Object creation times: 27,166,668
File Length: 163,000,011
Parsing time: 6,223ms
Object creation times: 27,166,668
326 MB
File Length: 326,000,011
Parsing time: 7,202ms
Object creation times: 54,333,335
File Length: 326,000,011
Parsing time: 11,871ms
Object creation times: 54,333,335
Dart 1
• Async await syntax (run 10,000 times)
// case 1
foo() async {
return 1;
}
// case 2
Future<int> bar() {
return new Future.value(2);
}
// case 3
baz() {
return 3;
}
Case 1 - Async and Await: 130ms
Case 2 - Future: 79ms
Case 3 - Sync: 0ms
main() async {
var f = await foo();
// change to ->
bar().then((b) {
// b ...
});
}
用到的地方全部要改寫用
bar().then()…
當初的女神…
Photo by Damir Spanic on Unsplash
Dart 2 – 2018 Aug.
• Pros.
• Performance boost
• Type system (will cause runtime error)
• 而且 (7400+ errors need to be fixed) - 純工人智慧
• Cons.
• Drop Dartium
• DropTransforms
• Workaround: conditional exports
• Chrome or DartDevC (DDC)
• 目前測到的感覺,DDC沒問題不代表JS不會有問題 (老症狀)
• Dart2JS 的stacktrace (火星文)
Dart 2
• Dart2JS 的stacktrace (火星文)
Dart 2
• Source map 反推 (依舊是火星文)
都是Dart自
己的async
stracktrace
發大財
祝大家寫Web

More Related Content

PPTX
Go: What's Different ?
PPTX
Rust meetup delhi nov 18
PPTX
ECS2018 PnP Training Day - Branding
PDF
Backdoors with the MS Office file encryption master key and a proposal for a ...
PPTX
T4T Training day - NodeJS
PDF
cadec-2017-golang
KEY
Torquebox rubyhoedown-2012
PPTX
Dart presentation
Go: What's Different ?
Rust meetup delhi nov 18
ECS2018 PnP Training Day - Branding
Backdoors with the MS Office file encryption master key and a proposal for a ...
T4T Training day - NodeJS
cadec-2017-golang
Torquebox rubyhoedown-2012
Dart presentation

Similar to ModernWeb 2019: Why we replace TypeScript with Dart (20)

PDF
Angular 2 overview
PPSX
Introduction to Java
PDF
Stackato v2
PDF
A guide to hiring a great developer to build your first app (redacted version)
PPTX
Introduction to Java Part-2
PDF
Scylla Summit 2022: Learning Rust the Hard Way for a Production Kafka+ScyllaD...
PDF
"Source Code Abstracts Classification Using CNN", Vadim Markovtsev, Lead Soft...
PDF
Web Leaps Forward
PPTX
Webdevcon Keynote hh-2012-09-18
PPTX
Be faster then rabbits
PPTX
Getting started with Vue.js - CodeMash 2020
PPTX
Session 01 - Introduction to Java
PDF
PyData Texas 2015 Keynote
PDF
Angular (v2 and up) - Morning to understand - Linagora
PDF
Stackato v3
PDF
Stackato
PDF
Критика "библиотечного" подхода в разработке под Android. UA Mobile 2016.
PDF
Stackato v5
PDF
PyData Frankfurt - (Efficient) Data Exchange with "Foreign" Ecosystems
PPTX
Kiss.ts - The Keep It Simple Software Stack for 2017++
Angular 2 overview
Introduction to Java
Stackato v2
A guide to hiring a great developer to build your first app (redacted version)
Introduction to Java Part-2
Scylla Summit 2022: Learning Rust the Hard Way for a Production Kafka+ScyllaD...
"Source Code Abstracts Classification Using CNN", Vadim Markovtsev, Lead Soft...
Web Leaps Forward
Webdevcon Keynote hh-2012-09-18
Be faster then rabbits
Getting started with Vue.js - CodeMash 2020
Session 01 - Introduction to Java
PyData Texas 2015 Keynote
Angular (v2 and up) - Morning to understand - Linagora
Stackato v3
Stackato
Критика "библиотечного" подхода в разработке под Android. UA Mobile 2016.
Stackato v5
PyData Frankfurt - (Efficient) Data Exchange with "Foreign" Ecosystems
Kiss.ts - The Keep It Simple Software Stack for 2017++
Ad

Recently uploaded (20)

PPTX
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
PDF
How to Migrate SBCGlobal Email to Yahoo Easily
PPTX
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
PDF
medical staffing services at VALiNTRY
PPTX
L1 - Introduction to python Backend.pptx
PPTX
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
PPT
Introduction Database Management System for Course Database
PDF
System and Network Administration Chapter 2
PDF
How Creative Agencies Leverage Project Management Software.pdf
PDF
Which alternative to Crystal Reports is best for small or large businesses.pdf
PDF
Navsoft: AI-Powered Business Solutions & Custom Software Development
PPTX
CHAPTER 2 - PM Management and IT Context
PPTX
Online Work Permit System for Fast Permit Processing
PDF
System and Network Administraation Chapter 3
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
PDF
top salesforce developer skills in 2025.pdf
PDF
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
PDF
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
PDF
Digital Strategies for Manufacturing Companies
PDF
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
How to Migrate SBCGlobal Email to Yahoo Easily
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
medical staffing services at VALiNTRY
L1 - Introduction to python Backend.pptx
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
Introduction Database Management System for Course Database
System and Network Administration Chapter 2
How Creative Agencies Leverage Project Management Software.pdf
Which alternative to Crystal Reports is best for small or large businesses.pdf
Navsoft: AI-Powered Business Solutions & Custom Software Development
CHAPTER 2 - PM Management and IT Context
Online Work Permit System for Fast Permit Processing
System and Network Administraation Chapter 3
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
top salesforce developer skills in 2025.pdf
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
Digital Strategies for Manufacturing Companies
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
Ad

ModernWeb 2019: Why we replace TypeScript with Dart

  • 1. Why we replaceTypeScript with Dart JumperChen
  • 2. About Me • 名字: 陳威亨 – Jumper Chen • 公司: 普奇科技 - ZK (Potix Corporation) • 職位: R&D Director • 負責: KeikaiTeam, QuireTeam, and ZK FrameworkTeam • 學歷: III Java養成班 EEIT 24期 – (14 years ago) • Personal Events: • EnglishCareer 雜誌專訪 2019 - 藍領幹部轉職程式設計師 • 30 (遠見) 雜誌專訪 2016 - 黑手,Debug自己的人生 • iThome 雜誌專訪 2009 - 從機車行黑手變成程式開發的黑手 • iThome 雜誌專訪 2009 - IE 8有機會讓網頁開發走向標準化的時代
  • 4. 2016年的春天,選新產品的語言 • Running onWeb • Same code base for Browser and Server • Modern Programming Language for Developers • Static typing analysis
  • 5. 選了TypeScript 1.8 當作新產品的語言 • Types • Boolean, Number, String, Array,Tuple, and so on • Union types • String|number • Classes • Public, Private, and Protected modifiers • Interfaces • Namespaces and Modules • Generics
  • 6. 當年開發TS需要用到的3rd-party libraries • TypeScript - tsconfig.json • Typings - typings.json • Node.js - package.json • SystemJS - system-config.js • Webpack - webpack-config.js • ts-loader (customized) • json-loader • uglify-js • babel • ts-node • Gulp - gulpfile.js • TSLint - tslint.json • JSDoc - jsdoc.json • Mocha – (testing tool) • … (嘎拉嘎拉)
  • 8. Circular reference issue (JS 通病) Module A Module BModule C
  • 9. Circular reference issue (JS 通病) Licensed under CC
  • 10. 選邊站? (不是 Blue vs Green) 1. Face it • Use tools to check (unreliable) • Lazy import modules (very easy to forget) 2. Migrate to another Lang. (Dart) but … • 1450+ ts files already • 350,870 lines of code (87%, 28~30w lines) • (3~4 工人智慧)
  • 12. Dart 1 - 2016 Nov. • Pros. • Types • Number, String, Boolean, List, Map, and so on. • Classes • No public, protected, and private • (but If an identifier starts with an underscore (_), it’s private to its library) • Interfaces (implicit) • Generics • Asynchronous functions • async and await • Dartium (without compiling to JS) • Transforms (like AOP)
  • 14. Dart 1 • Cons. • Not friendly to integrate with JS world • 一個Browser,各自表述  • Less Library • Game-loop, R-Tree, RB-Tree, IntervalTree, BNF Parser Generator, Socket.io, Socket.io-client, Dquery, Bootstrap, StAX XML parser … • Small Ecosystem • Performance issue • String Operations (Dart String operation much slower than Java) • https://github.com/dart-lang/sdk/issues/29131 • Map I/O (the Map implementation in dart2js is 3 times slower than JS version) • https://github.com/dart-lang/sdk/issues/28210 • async/await syntax too slow • Implement a fake future (calls Sync()) • https://github.com/dart-lang/sdk/issues/29189
  • 15. Dart 1 • String Operations (Dart String operation much slower than Java) FileSize Java Dart 20 MB File Length: 20,375,011 Parsing time: 572ms Object creation times: 3,395,835 File Length: 20,375,011 Parsing time: 938ms Object creation times: 3,395,835 163 MB File Length: 163,000,011 Parsing time: 4,060ms Object creation times: 27,166,668 File Length: 163,000,011 Parsing time: 6,223ms Object creation times: 27,166,668 326 MB File Length: 326,000,011 Parsing time: 7,202ms Object creation times: 54,333,335 File Length: 326,000,011 Parsing time: 11,871ms Object creation times: 54,333,335
  • 16. Dart 1 • Async await syntax (run 10,000 times) // case 1 foo() async { return 1; } // case 2 Future<int> bar() { return new Future.value(2); } // case 3 baz() { return 3; } Case 1 - Async and Await: 130ms Case 2 - Future: 79ms Case 3 - Sync: 0ms main() async { var f = await foo(); // change to -> bar().then((b) { // b ... }); } 用到的地方全部要改寫用 bar().then()…
  • 17. 當初的女神… Photo by Damir Spanic on Unsplash
  • 18. Dart 2 – 2018 Aug. • Pros. • Performance boost • Type system (will cause runtime error) • 而且 (7400+ errors need to be fixed) - 純工人智慧 • Cons. • Drop Dartium • DropTransforms • Workaround: conditional exports • Chrome or DartDevC (DDC) • 目前測到的感覺,DDC沒問題不代表JS不會有問題 (老症狀) • Dart2JS 的stacktrace (火星文)
  • 19. Dart 2 • Dart2JS 的stacktrace (火星文)
  • 20. Dart 2 • Source map 反推 (依舊是火星文) 都是Dart自 己的async stracktrace

Editor's Notes

  • #2: 今天來分享一個產品開發過程的故事,為什麼我們要換掉TypeScript,首先來自我介紹一下。
  • #3: 我叫陳威亨,英文名字叫我Jumper,目前任職於普奇科技擔任研發處長,本身也是半路出家,14年前去參加資策會開始轉行了, 雜誌很喜歡分享我的轉職故事,因此被採訪了幾次。
  • #4: Keikai 這產品是一個web spreadsheet component, 把它想像成把Excel可以使用在Browser上,然後支援多人連線的元件。 這故事要把時空背景移到2016年初,所以接下來的內容都要依那個年度來看比較不會失針。 先來看一段1分鐘的Demo
  • #5: 在2016年的春天,我們新產品的幾項訴求, 1. 可在網頁上使用 2. 最好是共用的程式碼可以跑在Browser跟Server side 3. 當前最主流的程式語言 4. 支援靜態分析的,提高程式的品質 根據這樣的條件,當年能選的就剩下NodeJs之類的,所以我們選了TypeScript
  • #6: Types: Optional static type notation 也支援Union types,可以混搭型別 Namespaces and Modules: 好切割你的程式碼 Generics: 一樣也有泛型
  • #7: TypeScript – tsconfig.json跟TS相關的設定 Typings – 如果用到的nodejs library沒有ts的typings, 還要自己寫 (不同的寫法可能會造成 ES6 在imports時語法會有問題) SystemJS: 用來動態載入modules,當年TypeScript好像比較推薦這個。 Webpack: 壓縮打包JS需要用的,大家比較熟悉 ts-loader: 我們客制化了一個自己的,為了可以載入submodule 而做的。(當年ts會看不到submodule, 所以做個mapping到node_modules下去騙它) babel: 要支援舊版browser就需要用到它。 ts-node – (wrong line number when run with Webstorm) Gulp – task runner,用來跑整個產品出貨,測試,產生文件需要的任務,有寫過Java的人,它就像Java的Ant一樣的工具。 Mocha - run test cases 有沒有像在7-11打工的工讀生一樣呢? (樣樣都要學)
  • #8: 產品開發幾個月後 就發現一個不好解的問題,也許是做Library or Component而且modules又切很細的才會遇到的問題,一般只拿來寫應用程式可能不會遇到。
  • #9: 像 a module 用到 b module, 又用到 c module ,然後直回到a module, 看起來很好避開,但如果你的modules是很多,而且,你不知道你的使用者會如何呼叫你的程式, 這樣,你的排列組合就會很多種,因為JS是interpreter 的程式語言,跟你怎麼寫的順序有關係。 (當然現在也有很多技術可以compiles the code on the fly 像v8) 下面這張圖比較可以說明現狀。
  • #10: 有去過日本東京自由行的人就會看過這張圖了, 相像一下,你的使用者用你的API就像是在某一個捷運站入口一樣,然後轉乘到另一個捷運站出口,只要二個捷運站有其他路線會互相通連的話,這個JS通病就會出現! 這樣,你怎麼可以預防這問題? 難度蠻高的,而且檢查工具幫不上忙,因為它根本不知道你的使用者會從哪一個入口進去,哪一個出口出去。
  • #11: Lazy import modules: 也是蠻難的,因為你的開發人員要照規則走,但一定會有人忘記, 而且你的載入module都要寫在method的body裡, 一方面不好維護,一方面程式效能也不高。 哪…只好換程式語言嗎? 當年可直接更換剩下Dart可以選擇,但真的要這樣嗎? 當年ts檔有1450個以上,程式碼打個8折 (扣掉一些換行跟註解),算28萬,or 算25萬好了,怎麼換? 只有3~4個工人,不是人工智慧 聽說,那些年行政院也才三個人上班,應該沒問題Der 所以真的要衝嗎? 還是心裡有點怕怕的…
  • #12: 原來那些年就已經有媽祖來托夢了! 媽祖都說來換大的,不要小的,那還怕什麼! 其實換語言不用請到媽祖啦。
  • #13: Types: Optional static type notation 支援 Asyn and Await, 當年TS還沒支援,只有實驗版。 Dartium 倒是當年最好用的,因為執行Dart code在browser上,不需要compiling到JS, 這開發速度 大大的提升。(之前TS每改一次來測試都要等個幾分鐘) Transforms: 動態加減程式碼,有點像AOP的概念,因為我們的程式打算寫一份,但可以跑在client and server, 所以我們需要在client的程式做一些加工,這樣它就能在client觸發時,可以發一個event用ajax or websocket送到server, 然後server在用reflection把對應的object抓出來,然後在呼叫一樣的method,這樣就能二邊跑一樣的程式,只要在compiling times用code gen做一點小手腳就行了。 突然覺得對Dart有點一見鐘情而且相見恨晚的感覺有沒有。
  • #14: 這時Dart就像我們阿宅們心中的女神一樣,長髮披肩,秀長的腳,有沒有… 但交往久了,總是會有一些壞習慣跑出來, 接下來要看一下,它有什麼缺點呢?
  • #15: 跟js整合不好 - (如果不是傳原生型別,可能都會出問題) ,JS and Dart兩邊雖然都跑在browser上,但彼此是看不到對方的。(蠻傻眼的) 就像同在一個Browser裡,各自表述 一樣   Library太少 –大多要自己刻,喜歡寫程式的人這邊蠻適合練功的,但非常不推這個當快速產品開發的語言 (會花太多時間成本在搞跟產品沒關係的事情上面) 開發生態系太小 -> 沒什麼共鳴, 文件少,討論少,有問題找不到別人的解法,人才也不好找 效能問題也是蠻頭大的,目前列的這三項,差不多都已經發給Dart team 2年多了,issue還是還沒close掉。 String 操作過慢,跟Java比的話,因為我們做Excel相關的,所以需要去載入一個Excel檔,裡面是XML格式的字元,光載入就很花時間,剩下的事怎麼加速。 Map -> 這在轉成JS的Object相比下,存取的速度慢了3倍多,Google的工程師出來說因為用了LinkedHashMap (the default Map)來實作JS的部份,所以沒辦法。 Async & Await 的sugar語法太慢,這也很頭痛的問題, 連他們自己Angular team的人都出來說不要用。
  • #16: 看紅字的部份,在檔案大小是20mb時,Java 在處理的速度大約快Dart接近一倍的時間。 雖然檔案變大,但還好是沒乘數成長。 這檔案的測試主要是因為我們在處理Excel檔時,所需要的時間,因為Excel是有壓縮過的,所以解壓後的大小才是真正要處理的時間。 如最後一項,326mb大小的檔在excel壓縮過大約只有3~40mb大小而已,但光parsing 做字串處理就需要7秒左右在Java,但Dart卻需要12秒。
  • #17: 另一項問題async and await的語法居然速度是超慢的,相對於同步的語法。   左邊列了三個case, 第一個是 async 的語法, 第二個是 Future語法 (像JS的promise) ,第三個是直接return value的同步語法。   三個比較跑1萬次所花的時間,很明顯就是async and await的語法是不能用的,慢太多了 因為Future or Async這種非同步語法的method是會被感染的,只要有用到非同步的method,基本上,都會一跑向上都是非同步的method.   因此為了要加速,我們就實作了一個Future的interface, 但底層是同步的method,用來騙compilier但runtime是跑同步的。   右下的case就是假設我們不能用async and await的語法,那所有有呼叫到future的method,都要改用 bar().then().then()…. 如果你的邏輯有3~50行的話,然後裡面又包含很多非同步的method,這段程式會變的很難讀得懂。 這時…回想一下當初的女神,好像…有點走鐘了
  • #18: 當初完全的女神怎麼變… 想分手,(再換一次語言?) 可能會被打到住院… (不是他打的,是被你老闆打的,哈) 看來分手不是一條選項,那只好學習忍耐,有結過婚的人就能體會我這句話的意思。 (哈)
  • #19: 一直到了2018年8月,Dart2出現了,主要是為了Flutter而產生的。 字串處理的效能變快了 (我們測試下跟Java差不多快)   Type system: 簡單來說就是全部都strong mode,早期dart 1是可以選擇的,但這樣子的話,compiler 沒辦法optimized,當然為了Flutter的關係,Dart2改變了這個。   Dartium 沒了 (有點回到TS的感覺,Compiling to JS的時間差不多可以去泡一下咖啡)   Tranforms: 也沒了 (沒辦法在JS and Server中插入不同的程式),這比較麻煩,還好最後有找到一個方式可以解套,但這居然是一個隱藏版的功能…。   目前在Web程式執行上,只能Chrome也就是說整個compiling 到JS,另一個就是用DDC (一樣是JS),但是有限度的,而且DDC(只能支援chrome…), 其他Browser就,自己看著辦。   Dart2JS基本上就是火星文,而且預設他們的release選項還沒有sourcemap… (需要一點沒有文件說明的客制參數)
  • #20: 來看一下火星文, 這是有次,有個同事說 Jumper, 客戶遇到這個error, 你看得出來是哪邊出錯嗎? … 我心想: 我看得出來我就去買樂透看明牌了,不用來寫程式了。 那怎麼辦? 有,用Source map 反推啊! (很聰明哦!)
  • #21: 看一下左邊紅線的地方。 除了第一個是我們main 裡面去攔到的非同步error, 剩下都是Dart 自己的strack trace, 所以還是一樣沒線索。 通常發生這問題是因為我們有某段會出錯的地方剛好在一個非同步的程式中,然後我們漏了去catch這個error造成的。(跟java的future如果沒攔到,一樣會看到只有底層的stracktrace) 此時,大家的腦中應該跟我一樣都出現了三個字,有沒有?很想罵出來… 對不對? 我不是館長,不能直接罵,我寫在下一張投影片
  • #22: 謝謝大家,今天分享到這。