歲末年終,一起來幫你家 D3 瘦身吧!

更新於 發佈於 閱讀時間約 8 分鐘

最近某專案弄完上線之後,因為想要加快 First Meaningful Paint 的速度,開始調查有沒有甚麼可以改進的地方。

看著看著就看到博大精深(超大包)D3

raw-image

其實也不過就是 gzip 後 74.7KB 嘛…

本文的終極目標就是希望針對自己的需求,能夠幫 D3 瘦身一下。

不想再聽到瀏覽器的悲鳴了!

D3 為何大包

是這樣的,其實 D3 是一個包羅萬象的超強 library,不能單純的把它定位成「一個畫圖的 library」。

官方介紹如下:

D3.js is a JavaScript library for manipulating documents based on data. D3 helps you bring data to life using HTML, SVG, and CSS. D3’s emphasis on web standards gives you the full capabilities of modern browsers without tying yourself to a proprietary framework, combining powerful visualization components and a data-driven approach to DOM manipulation.

如果你也實際用過 D3,就會瞭解 D3 的強大之處在於它對 資料數據 -> 圖像數字 的處裡非常有一套,我這邊也不說太多,如果想深入一點瞭解 D3,可以參考幾乎每年都有人寫的鐵人賽系列文章:

我是不太推薦完整閱讀「Reac / Vue + D3」的這類型的系列。以想學 D3 的角度來看,介紹 React / Vue 的部分感覺沒什麼卵用,想要讀的話,可以只看其中 D3 的部分就好囉!

而 D3 本身其實被切分為非常多的 package,依據使用情況的不同,會用上不同 package 的功能,一樣推薦一個非常優質的 D3 教學網頁:

Intro to D3

好的,簡單來說就是如果你照官網寫的起手式

raw-image

就會把上面 gif 裡面所有的 package 全部載入網頁裡,這樣做會影響我們 FMP 的點有兩個:

  • 因為比較大包,需要額外的下載時間
  • 因為比較大包,瀏覽器載入這段 code 會花比較多時間

那麼接下來就來幫它瘦身吧!

瘦身123

首先,這次的專案本身是一個 Gatsby 網站,也就是說我們有強力的 webpack bundler 做後盾。

我們可以透過 webpack 包出一個只有我們需要的功能的 D3 object。

首先需要檢視我們到底用了哪些 D3 的 package 裡的功能,先看一眼網站內的效果:

用到的 package 如下:

  • d3-selection 基本選取操作工具,這是必備的
  • d3-transition 看到動畫表示有用到
  • d3-ease 看到比較炫砲的動畫表示有用到
    用到特殊 timing function 的 transition 總是會炫砲一點
  • d3-interpolate 看到比較炫砲的動畫表示有用到
    有嘗試自訂 interpolation 表示對動畫比較有追求,通常也會呈現比較炫砲的效果
  • d3-shape 看到複雜 SVG 圖形表示有用到
    複雜 SVG 圖形指的是像圓餅圖的切片這種需要用 <path> 才畫得出來的

當然,純看效果是沒有辦法 100% 兜出需要的 package 的,畢竟最懂用了什麼的人是寫這段 code 的我,所以上面這種純推論的伎倆其實是瞎掰的。

我是看 code 來找出用了哪一些 package 的,欸嘿 థ౪థ

心法

一眼看出使用什麼 package 的大原則就是

對照一下 d3.xxx() D3 API Reference 的哪個 package 區塊裡面。

舉例來說,我們看一下這段 code (可以不用嘗試理解它,隨便看看):

raw-image

套用大原則,可以用 d3.xxx() 對應出 package:

  • d3.select -> d3-select
  • d3.pie -> d3-shape
  • d3.entries -> d3-collection
  • d3.arc -> d3-shape

然而事情往往沒有這麼簡單,D3 鏈式操作的特性,使得其實有些 package 幾乎沒有用到 d3.xxx() 這種形式的呼叫,而是針對特定的物件(通常是 selection)做 prototype 的擴充。

D3 API Reference#d3-transition 就是一個很好的例子:

raw-image

實際使用的時候大都是:

raw-image

此時,儘管沒有用到 d3.xxx() 類的呼叫,還是需要記得打包要算上 d3-transition

場外加映一下 d3-transition 裡面是怎麼寫的

raw-image

經過一番嚴謹的判斷,我把有用到的部分重新 export 成一個 d3

檔案: d3.js

檔案: d3.js

最後再把原本從 global 抓的 d3 換成 import 這個自己打包的版本就好啦!

修羅場

只是打包完畢並不能夠滿足我們旺盛的好奇心。

跟應有盡有的版本相比,到底變小了多少呢!?

讓我們親手來比較看看吧!

D3 的 d3/d3 repository 就是官方版打包用的 repository,話不多說,馬上 fork 一個來打包。

Fork 之後,小修改一下,在官方完整版之外加入我們的 custom 版本:

  • 新增 custom.js 作為 custom build 的進入點
  • 新增一個 rollup-custom.config.js 官方版是用 rollup 打包,比較適合打包 library
  • 修改 npm script 的 pretest,加入執行我們這個新的 rollup config

最後執行

raw-image

然後我們就可以在 dist 資料夾裡面看到成果(方便視覺上比較,我把 *.node.js 砍了):

raw-image

同時也來比較一下實際載入花的時間:

raw-image

總結比較結果:

  • 檔案大小差距 242KB vs 50KB -> 瘦身後,大小減少了約 80%
  • 執行時間差距 58ms vs 16ms -> 瘦身後,載入 library 時間減少了約 72%

後記

是說最近我打算把方格子也加入我發表文章的平台。

畢竟我不喜歡大家一股腦往 Medium 發中文文章的模樣,如果不做點什麼來表現我堅定的立場,好像說不太過去。

這篇就是第一篇同步在方格子跟我的 blog 上架的文章。

考慮到方格子的向性,我也打算順便寫一些別的有的沒的(?),拓展一下寫文的觸角,看看有沒有什麼新的火花。最近看了紫羅蘭永恆花園之後,深刻感受到文字的力量之大,同時也覺得沒辦法好好運用文字的自己有點可悲 😢

稍微總結一下在方格子上的計畫:

  • https://pymaster.tw 同步發文
  • 除了前端專題,可能會再開一個動畫心得專題
  • 提高產文頻率,希望一週兩篇以上前端專題,動畫心得的話就看心情囉

希望往後我的文字能夠更加隨心所欲、Sincerely

👉我的方格子個人頁面

留言
avatar-img
留言分享你的想法!
avatar-img
批歪的沙龍
4會員
7內容數
網頁前端是一個需要與時俱進的工作。 你也喜歡前端嗎? 在這邊你可以找到一些前端小知識、新技術或是趣聞,歡迎與我們一同成長 🚀
你可能也想看
Thumbnail
大家好,我是一名眼科醫師,也是一位孩子的媽 身為眼科醫師的我,我知道視力發展對孩子來說有多關鍵。 每到開學季時,診間便充斥著許多憂心忡忡的家屬。近年來看診中,兒童提早近視、眼睛疲勞的案例明顯增加,除了3C使用過度,最常被忽略的,就是照明品質。 然而作為一位媽媽,孩子能在安全、舒適的環境
Thumbnail
大家好,我是一名眼科醫師,也是一位孩子的媽 身為眼科醫師的我,我知道視力發展對孩子來說有多關鍵。 每到開學季時,診間便充斥著許多憂心忡忡的家屬。近年來看診中,兒童提早近視、眼睛疲勞的案例明顯增加,除了3C使用過度,最常被忽略的,就是照明品質。 然而作為一位媽媽,孩子能在安全、舒適的環境
Thumbnail
我的「媽」呀! 母親節即將到來,vocus 邀請你寫下屬於你的「媽」故事——不管是紀錄爆笑的日常,或是一直想對她表達的感謝,又或者,是你這輩子最想聽她說出的一句話。 也歡迎你曬出合照,分享照片背後的點點滴滴 ♥️ 透過創作,將這份情感表達出來吧!🥹
Thumbnail
我的「媽」呀! 母親節即將到來,vocus 邀請你寫下屬於你的「媽」故事——不管是紀錄爆笑的日常,或是一直想對她表達的感謝,又或者,是你這輩子最想聽她說出的一句話。 也歡迎你曬出合照,分享照片背後的點點滴滴 ♥️ 透過創作,將這份情感表達出來吧!🥹
Thumbnail
嗨,你有沒有想過用 ChatGPT 來減少 DevOps 工作? 今天我將向您展示如何使用 ChatGPT 減少 NodeJS 網絡應用程式的鏡像大小。 您會驚訝於 ChatGPT 如何能夠在短短幾分鐘內輕鬆生成一個無錯誤的 Docker 文件,來優化 Node.js docker 映像的大小。
Thumbnail
嗨,你有沒有想過用 ChatGPT 來減少 DevOps 工作? 今天我將向您展示如何使用 ChatGPT 減少 NodeJS 網絡應用程式的鏡像大小。 您會驚訝於 ChatGPT 如何能夠在短短幾分鐘內輕鬆生成一個無錯誤的 Docker 文件,來優化 Node.js docker 映像的大小。
Thumbnail
JavaScript 的關鍵價值 JavaScript 是一種強大且廣泛使用的編程語言,具有許多價值和應用。以下整理 JavaScript 的關鍵價值: 客戶端網頁開發、跨平台開發: JavaScript 是種瀏覽器的語言,可實現動態網頁效果,並通過操作 HTML 和 CSS,使網頁互動性提昇,提供
Thumbnail
JavaScript 的關鍵價值 JavaScript 是一種強大且廣泛使用的編程語言,具有許多價值和應用。以下整理 JavaScript 的關鍵價值: 客戶端網頁開發、跨平台開發: JavaScript 是種瀏覽器的語言,可實現動態網頁效果,並通過操作 HTML 和 CSS,使網頁互動性提昇,提供
Thumbnail
這是教你插入野頁碼從簡報的第3頁開始為編碼第1頁, 我把第2頁設計成目錄頁我不想讓他有編碼,所以從第3頁開始,這樣有懂嗎?呵呵 首先到最上方的功能選項 [ 插入 ]然後 [ 頁首及頁尾 ] ☑勾選投影片編號 ☑標題投影片中不顯示 然後按全部套用 再來到功能選項的 [ 設計 ] 然後 [ 投影片大小
Thumbnail
這是教你插入野頁碼從簡報的第3頁開始為編碼第1頁, 我把第2頁設計成目錄頁我不想讓他有編碼,所以從第3頁開始,這樣有懂嗎?呵呵 首先到最上方的功能選項 [ 插入 ]然後 [ 頁首及頁尾 ] ☑勾選投影片編號 ☑標題投影片中不顯示 然後按全部套用 再來到功能選項的 [ 設計 ] 然後 [ 投影片大小
Thumbnail
Draco 是開源的3D 圖形壓縮, 前些陣子在處理的專案,需要用到放置3D模型, 問題來了,上百個幾千幾萬K大大小小的gltf模型,一次載入超級慢的, 公司配備電腦等級還不錯, 本機load的快,也需要大概1分鐘內時間, 當然跟現場的網路也有關係,但是減少loading還是有必要的, 拜訪goog
Thumbnail
Draco 是開源的3D 圖形壓縮, 前些陣子在處理的專案,需要用到放置3D模型, 問題來了,上百個幾千幾萬K大大小小的gltf模型,一次載入超級慢的, 公司配備電腦等級還不錯, 本機load的快,也需要大概1分鐘內時間, 當然跟現場的網路也有關係,但是減少loading還是有必要的, 拜訪goog
Thumbnail
此版本的目標畫面成果是: *金色名字。 *金色社交按鈕圖示,點擊按鈕另開對應的網頁或著顯示comming soon。 *名字和按鈕在網頁中央,如果網頁寬度不夠會換行,夠就不換行。
Thumbnail
此版本的目標畫面成果是: *金色名字。 *金色社交按鈕圖示,點擊按鈕另開對應的網頁或著顯示comming soon。 *名字和按鈕在網頁中央,如果網頁寬度不夠會換行,夠就不換行。
Thumbnail
一個網頁只會有一個h1 標籤(h1.p.img)裡面可以放多個屬性(src.background.color) 建立 HTML 環境 告訴大家這是html5的語法 關於整個專案的資訊放這裡面 頁籤標題 寫給別人看的要放這裡面 Emmet 預設安裝 /*語意使用英文*/ /*使
Thumbnail
一個網頁只會有一個h1 標籤(h1.p.img)裡面可以放多個屬性(src.background.color) 建立 HTML 環境 告訴大家這是html5的語法 關於整個專案的資訊放這裡面 頁籤標題 寫給別人看的要放這裡面 Emmet 預設安裝 /*語意使用英文*/ /*使
Thumbnail
接續上一篇,這邊要來寫一個React hello world app,最後安裝webpack-dev-server來提升開發效率。 使用npm安裝react, react-dom: $ npm install react react-dom --save dependencies下紀錄的是生產環境會
Thumbnail
接續上一篇,這邊要來寫一個React hello world app,最後安裝webpack-dev-server來提升開發效率。 使用npm安裝react, react-dom: $ npm install react react-dom --save dependencies下紀錄的是生產環境會
Thumbnail
JavaScript 能做許多事,尤其透過瀏覽器的 API 或套件,我們得以悠游於巨量資料中,將資料轉換為與使用者溝通的介面,以下就來分享 15 個實用的 Vanilla JS 程式碼...
Thumbnail
JavaScript 能做許多事,尤其透過瀏覽器的 API 或套件,我們得以悠游於巨量資料中,將資料轉換為與使用者溝通的介面,以下就來分享 15 個實用的 Vanilla JS 程式碼...
Thumbnail
安裝軟體:ATOM-https://atom.io/ 基本上安裝畫面上的download會顯示您目前所用的工具所需的軟體 這邊顯示是Windows的64-bit就是我所用的~Mac會顯示Mac用的 2.每個軟體學習一開始都是要從HELLO WORLD開始,是因為要確認”環境”是否安裝”完成
Thumbnail
安裝軟體:ATOM-https://atom.io/ 基本上安裝畫面上的download會顯示您目前所用的工具所需的軟體 這邊顯示是Windows的64-bit就是我所用的~Mac會顯示Mac用的 2.每個軟體學習一開始都是要從HELLO WORLD開始,是因為要確認”環境”是否安裝”完成
Thumbnail
最近某專案弄完上線之後,因為想要加快 First Meaningful Paint 的速度,開始調查有沒有甚麼可以改進的地方。 看著看著就看到 242KB 的 D3... 🤭
Thumbnail
最近某專案弄完上線之後,因為想要加快 First Meaningful Paint 的速度,開始調查有沒有甚麼可以改進的地方。 看著看著就看到 242KB 的 D3... 🤭
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News