• 從 Mama 說起的前端優化

    Mama,是我一個興趣項目。

    網站截圖

    為什麼她需要前端優化呢?

    這是由於,在 1.1.4 版本中,她有一個新的功能「Line的表情」選擇。

    我一共下載了大約 800 個 LINE 的表情圖片,如果在舊的圖片添加方式上,我必須要如下操作 800 次才可以完成添加圖片。

    • 上傳圖片到 asset 目錄;
    • 添加一行 single.html 的代碼;
    • 修改 app.js 的代碼以確保顯示正確數量的文本輸入框;
    • 修改 photos.php 的代碼以確保位置正確;
    • 測試是否成功添加。

    如果我真的按照剛才的添加方法添加 800 的圖片,我不相信可以完成。所以,我決定重寫了 MAMA 的圖片添加方法。我做了什麼?

    • 新建了一個 output.php 的文件,用於檢查 pngs 的目錄內容。並且自動輸出 photos.json 文件以提供給 app.js 讀取。
    • app.js 讀取 photos.json 文件,自動創建對應的 HTML DOM 以顯示圖片。
    • 測試是否能夠正常工作。

    現在就變得很好,她終於可以不用手工修改代碼來實現添加圖片了。有一個簡單的腳本程序在維護。但是,這裡又引申出一個新的問題。圖片很多時候需要不同位置的輸入框,所以,我又給腳本作出修改,讓她能讀取一個對應的文件來自定義某些圖片。處理完圖片,其實,有些系列也就是有所不同的位置,如是,我給目錄也做出了基礎參數的支持。 image

    OK, very well. 一切看起來很好。
    如是,我就如此發佈了 1.1.4 的第一個版本。並且走去睡覺。

    解決 HTML DOM 性能

    在我睡醒之後,我總覺得伺服器訪問起來很緩慢,「添加分鏡」的功能需要等待大約 6 秒的加載時間,我在思考是不是一些什麼事情從而導致這個緩慢的問題。然而,我打開了 Safari 的「檢察元素」工具來分析這些載入時間的問題。

    image (我已經沒有當時的分析記錄的截圖了)

    然而,讓我驚訝的事情是,app.js 的腳本工作得很慢。特別它在請求 single.html 的時候,就有大約 6 秒的時間讓瀏覽器卡死。

    image

    如是,我開始思考這其中的原因。經過分析,我覺得這是讓 Javascript 做了太多的事情了,從 Ajax 獲得文本,到建立 HTML DOM,接著瀏覽器還要瞬間加載大約1000個圖片 。這一切,讓 Javascript 的性能遇到瓶頸了。

    第一步,我放棄了讓 Javascript 來自動建立 HTML DOM。我寫了另外一段代碼,使用 PHP 寫的。來完成 HTML DOM 的建立。

    image

    這樣的修改,「添加分鏡」這個功能就從 6 秒的等待時間,縮短到了 4 秒了。

    第二步,使用 LazyLoad 的辦法加載圖片。我繼續分析,我認為瞬間加載 1000 個圖片這個方法蠢死了。於是,我做出了少留修改,讓這1000個圖片使用 LazyLoad 的辦法載入。(上面的代碼片段已經包含了LazyLoad)

    第三步,過去的 Load 的辦法,我也修改為 get 的辦法image

    第四步,很理所當然地把所有的 PNG 文件都壓縮了一遍。

    很好,一切的速度的感覺回來了。

    現在,點擊「添加分鏡」按鈕只有大約 1 秒多的延遲,但是我暫時沒有辦法解決這個問題。除了還有這個問題,還有一個問題就是編輯窗口的圖片必須要等待小圖片的完整載入才可以開始載入。這個我相信是瀏覽器的下載線程導致的。

    這個筆記,關鍵在於有幾點:

    • 不要讓 Javascript 來處理 DOM 的事情(很慢)
    • 同時載入 N 個圖片是一個笨死的辦法
    • 能夠在服務器端完成,就不要在客戶端完成(能寫 PHP 就不要寫 Javascript)。