CI上的Web前端性能測試

KayleeKendr 8年前發布 | 40K 次閱讀 PhantomJS Docker JUnit 測試工具

來自: http://icodeit.org/2016/02/performance-testing-in-ci/

Web站點的響應速度

雅虎在2006年就發布了一份提升Web站點響應速度的 最佳實踐指南 。該指南包含了35條規則,分為7個類別。這些規則已經被廣泛使用,并指導人們在新的站點設計時更有針對性的考慮問題。這份指南已經成了Web前端性能度量的一個事實標準了。

YSlow 是一個基于這份指南的測試工具,它可以測試一個站點是否“慢”,以及為什么“慢”?你可以通過很多方式來使用 YSlow ,比如Firefox,Chrome的插件,命令行工具,甚至PhantomJS這樣的無頭(Headless)瀏覽器。YSlow會檢測你的站點中的資源是否沒有壓縮,是否缺失了超時設置,更進一步,它還會檢測你的JS/CSS是否已經壓縮/精簡化,圖片的尺寸,是否使用了CDN等等很多的維度。它還可以生成很多格式的報告,比如打分信息,TAP協議的輸出,以及junit測試報告的格式。

我們這里討論如何在持續集成服務器上設置一個 YSlow 任務,這個任務會在每次構建之后,測試你應用的性能指標,以幫助你更快的發現和定位問題。當然,我推薦你在 staging 環境,很多開發者在測試環境,本地開發環境都會啟動很多對 Debug 友好的設置,比如未壓縮的JS/CSS,沒有超時設置的響應等,這會導致該構建任務的 打分 不夠準確。

搭建CI環境

按照傳統方式,如果要搭建一個這樣的CI任務,我們需要至少做這樣一些事情:

然后設置環境變量,在Jenkins上創建任務,并運行YSlow.js腳本。這個任務很簡單,只需要設置好參數,然后將結果輸出為Jenkins上的報告即可。比如:

$ phantomjs /var/share/yslow.js -i grade -threshold "B" -f junit \ http://bookmarks-frontend.s3-website-us-west-2.amazonaws.com/ > yslow.xml 

</div>

  • -i grade 展示打分(grade)信息(還可以是basic/stats/all)等
  • -threshold "B" 指定失敗的閾值為B
  • -f junit 輸出為 junit 識別的XML格式

這里的閾值可以是數字(0-100分),字母(A-F級別)或者一個JSON字符串(混合使用)

-threshold '{"overall": "B", "ycdn": "F", "yexpires": 85}' 

</div>

上面的命令會測試站點 http://bookmarks-frontend.s3-website-us-west-2.amazonaws.com/ 的各項指標,并應用雅虎的那35條規則,并最終生成一個 junit 測試報告格式的文件: yslow.xml 。

但是維護CI環境是一個比較麻煩的事情,而且既然每個項目都可能會用到這樣的 基礎設施 ,一種好的做法就是將其做成一個 鏡像 保存起來,以方便其他項目的復用!這里我們使用 docker 來安裝和配置我們的CI環境,配置完成之后,我們可以將 docker 的鏡像分享給其他團隊,也可以供我們在下一個項目中使用。

基于docker/docker-compose的環境搭建

docker 出現之前,我們要搭建一個 測試 或者 staging 環境,往往需要很多個不同角色的機器:有專門的數據庫服務器,文件服務器,緩存服務器,Web服務器,反向代理等等。這樣在成本上顯然是個不小的開銷,如果將所有不同的組件部署在同一臺機器上,則又可能互相干擾,只需要一個小小的失誤,整個系統就需要重新配置。更可怕的是,這個環境和生產系統不一致,那么很可能真實的錯誤要等到系統上線之后才會被發現。

比如在2012年,我所在的一個項目中,客戶的系統采用傳統的J2EE架構。本地開發中,我們使用了Jetty作為容器,而 測試 和 Staging 環境使用了Tomcat。由于Tomcat對空格的處理和Jetty有所不同,我們在本地測試通過,并且運行良好的代碼,在 Staging 變得完全不能工作。這個問題花費了團隊很多時間來排查錯誤。

在 docker 出現之后,我們可以在一臺物理機器上運行多個互不干涉的容器,每個容器可以是一個組件(比如運行數據庫的容器,Web服務器容器等等)。這樣不但縮減了成本,而且可以讓我們的環境盡可能和生產環境一致(有的項目甚至直接將CI出來的鏡像應用到生產中)。不過對多個容器的管理是一個很麻煩的事情,好在 docker 提供了 docker-compose 工具來解決這個問題。使用 docker-compose 可以定義一組互相獨立,但是又可以協作在一起的容器,這樣我們可以很容易的搭建一個 仿生產 環境。

比如我們可以定義個 docker-compse.yml

app:  build: .  links:  - db:postgres  ports:  - 8000:8000  volumes:  - .:/app  working_dir: /app  entrypoint: /app/start.sh  environment:  JDBC_DATABASE_URL: jdbc:postgresql://postgres:5432/bookmarks  DATABASE_USER: bookmarks-user  DATABASE_PASS: bookmarks-password  db:  image: postgres:9.3  ports:  - 5432:5432  environment:  POSTGRES_DB: bookmarks  POSTGRES_USER: bookmarks-user  POSTGRES_PASSWORD: bookmarks-password 

</div>

這個 docker-compose 定義了兩個組件, app 和 db 。 db 使用了 postgres:9.3 鏡像,并設置了自己的環境變量。 app 則從當前目錄 . 構建一個新的鏡像, app 與 db 通過 links 屬性連接起來。

如果在當前目錄執行 docker-compose build 命令, docker-compose 會找到本地的 Dockerfile ,然后構建出一個 docker 的鏡像,并啟動該容器,同時,它還會啟動 postgres:9.3 容器作為數據庫組件。這樣我們的環境就被完整的搭建好了。

搭建CI環境

app:  build: .  ports:  - 8080:8080  - 50000:50000  volumes:  - ./data:/var/jenkins_home 

</div>

這個配置,表明我們會根據當前目錄的 Dockerfile 來構建一個鏡像。

通過命令 volumns ,我們將本地目錄 ./data 映射為 jenkins_home ,這樣我們定義的job信息,以及插件的安裝都會放到本地的目錄中,方便管理。配置完成之后,構建并啟動該容器:

FROM jenkins:latest  # Env ENV PHANTOMJS_VERSION 1.9.6 ENV PHANTOMJS_YSLOW_VERSION 3.1.8 ENV SHARE_BIN /var/share  # Install stuff by using root USER root RUN apt-get update RUN apt-get upgrade -y RUN apt-get install -y git wget libfreetype6 libfontconfig bzip2  RUN mkdir -p $SHARE_BIN  RUN wget -q --no-check-certificate -O /tmp/phantomjs-$PHANTOMJS_VERSION-linux-x86_64.tar.bz2 \ https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-$PHANTOMJS_VERSION-linux-x86_64.tar.bz2 RUN tar -xjf /tmp/phantomjs-$PHANTOMJS_VERSION-linux-x86_64.tar.bz2 -C /tmp RUN rm -f /tmp/phantomjs-$PHANTOMJS_VERSION-linux-x86_64.tar.bz2 RUN mv /tmp/phantomjs-$PHANTOMJS_VERSION-linux-x86_64/ $SHARE_BIN/phantomjs RUN ln -s $SHARE_BIN/phantomjs/bin/phantomjs /usr/bin/phantomjs  RUN wget -q --no-check-certificate -O /tmp/yslow-phantomjs-$PHANTOMJS_YSLOW_VERSION.zip \ http://yslow.org/yslow-phantomjs-$PHANTOMJS_YSLOW_VERSION.zip RUN unzip /tmp/yslow-phantomjs-$PHANTOMJS_YSLOW_VERSION.zip -d $SHARE_BIN/ USER jenkins 

</div>

執行下面的命令來設置并啟動CI服務器:

docker-compose up 

</div>

創建新任務,并指定該任務執行的命令為:

$ phantomjs /var/share/yslow.js -i grade -threshold "B" -f junit \ http://bookmarks-frontend.s3-website-us-west-2.amazonaws.com/ > yslow.xml 

</div>

由于此時 phantomjs 已經被安裝到了容器中,我們可以直接在jenkins中使用。運行結束之后,這個命令會生成一個報告:

  • 沒有壓縮內容
  • 沒有添加過期的頭信息

在產品環境,我們需要使用反向代理來添加這些頭信息,以保證最終用戶在使用Web站點時的體驗。

總結

我們只需要很少的配置就可以設置好一個工作良好的CI任務,這樣在程序員某天引入了未經壓縮的JS/CSS或者UX不小心提供了巨大而未經處理的圖片時,你可以盡快的得到通知,并在正是上線之前發現這些問題。

代碼配置 在這里。

</div>

 本文由用戶 KayleeKendr 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!