星期二, 3月 24, 2015

排程與apache建立共用folder


由於透過排程建立image資料夾丟圖片
而後台(人工)作業也會透過apache建立資料夾丟圖片
但權限不同(owner不同),造成無法丟入圖檔
最麻煩的是Server被禁止無法在php裡執行chmod

想了幾個做法
  1. 透過localhost/shell啟動apache/[cron-user]建立folder  (failed)
    原本想用排程透過curl呼叫"建立folder"的PHP (owner 為apache)
    但因為一樣是建立自己的帳號,反而是自己無權限丟檔  o_Q
  2. 排程執行固定執行Shell (work around)
    可以,但因為要改對方建立的folder,所以得要有root權限,不太好的解法 
  3. 透過apache執行排程 (solution)
    原本想建立apache user來寫排程,但Admin不同意
    後來看到可以sudo為apache來寫排程,這樣一來都是owner都是apache~ YA~
    sudo -u apache crontab -e

星期日, 3月 08, 2015

PHP到底有沒有DB Connection Pooling

一直沒搞懂到底PHP有沒有Connection Pooling...
看了Persistent connections,又有人說不要用
沒事就被打個槍,還是好好研究一下

先簡單的來說有什麼做法(linux下)
  1. PHP的MSSQL extension
    1. 就是常見的pconnect,不建議
  2. PHP的PDO extension
    • 做法
      • 將connection cache下來,當其他的php script request,再重覆使用
        寫法如下
        <?php
        $dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass, array(
            PDO::ATTR_PERSISTENT => true
        ));
        實驗結果PDO可以的ATTR_PERSISTENT ,還可關掉ODBC的pooling
    • 討論
      • PHP官網指出,如果有ODBC做pooling的話,就用ODBC做,因為可讓同process其他的模組使用
  3. ODBC Connection Pooling(unixODBC)
    • 做法
      • 存在Web Server裡,供給Web Server Process使用
      • 前提是使用的ODBC driver及library要有支援
      • PDO_ODBC及unixODBC v2.0後都有支援Connection Pool
    • 另外利用ODBC的還有以下,但各自有沒有再實作pooling沒研究
      • Microsoft ODBC
      • Easysoft ODBC
  4. freeTDS
    • 做法:利用linux process管理connection
    • 怪可怕的,如果process掛了,那connection就GG了
    • 而且只接受TDS 4.2, 也不接受ntext

Summary

看起來利用ODBC比較做是比較建議的做法
另外就不用再用PDO做persistent,因為會被cache住,不會還給ODBC.

  • 使用Pooling注意事項
    勿改變connection 狀態,例如改default db,造成使用同組db帳密的request會讀取錯誤


Reference
Connections and Connection management
ODBC Connection pooling

星期一, 3月 02, 2015

Code Review項目

一直覺得Code Review滿重要的
高效代碼審查:來自前質疑者的9個建議有提到Code Review有助於以下

  • 抓bug
  • 保證代碼的可讀性,可維護性
  • 在團隊中散播代碼的知識
  • 讓新人適應團隊的工作方式
  • 讓大家接觸不同的思路

文章還有提到些具體的做法
我也要加入Working Agreement

  • 每次的pull request都要求所有team member做code review
  • 條列check item
    • 這項還滿不錯的,至少每個人會習慣必要的項目
      自己寫code時也會注意


Reference: 高效代碼審查:來自前質疑者的9個建議

禁止root遠端ssh登入 linux


新架了Linux Server,沒想到才幾天而已
就發現root在2小時內,就有7000多次的登入失敗記錄

太可怕了... 趕快加個限制
禁止root遠端ssh登入 linux

vi /etc/ssh/sshd_config
--
PermitRootLogin no
--
/etc/init.d/sshd restart

Reference:
Security Tip: Disable Root SSH Login on Linux

星期二, 2月 17, 2015

API Response Format

對API的response沒有設定標準格式
每次寫API就在想,網路上看到這版本還不錯
再小調整一下,符合自己需要的
統一這個版本了
{
    success: <boolean>,
    error : { /* Only included if success is false. */
        code: (customize error code)
        msg: (for message)
    },        
    response: {} /* Only included if success is true */
}


Reference
Sentiment Analysis Endpoint

星期四, 1月 08, 2015

導Agile可以,但品質要顧好

前陣子學Agile,懂了點皮毛,正在公司導Agile
最近主管回覆:「導Agile可以,但品質要顧好」
聽起來很不合agile的邏輯,想了好久

Agile是Rough, adaptive plan,不是No plan...

我在想主管應該是以為Agile是No Design, No Plan在開發
因此對Agile會有些品質的誤解
在 Henrik Kniberg 的 文章 What is Scrum? 裡有張圖還不錯


應該就能知道Agile是Rough, adaptive plan
而不是No plan的開發









品質應該更好... 顧吧

對主管的話特別有反應是因為....
Agile把feature size切小,不敢說小就簡單
但至少開發, Tester對該週期開發的feature掌握度高
即使出搥了,也能快速的找出問題修正

公司有個team
每個月上20多個features,要上線時都要搞半夜上線
一有問題,就得從這堆features找bug
我實在很佩服,問他們不會壓力很大嗎
還說不會哩... 真是神人....

每個release短一點,features少一點

如果改成每週上5個features,我想相對大家會容易應付些
雖然每週上線壓力有點大,不過總比一個月上20多個feature好一些
而且如同agile說的,也許剩餘的feature會因些feedback有所調整或消失...

星期四, 11月 20, 2014

Kanban: Successful Evolutionary Change for Technology Organizations

  • Continuous Improvement Culture
    • bottleneck
  • setup board
  • prioritize
  • WIP
    • preventing workers from becoming overloaded
  • Pull
  • Metrics & Management Reporting
    • Tracking WIP
    • Cycle Time
    • Due Date Performance
    • Throughput
    • Issues & Blocked Work Items
    • Flow Efficiency
    • Initial Quality
    • Failure Load



星期日, 8月 31, 2014

Bowling Game Kata

看了Uncle Bob的建議,每天想來練一下Kata
而Uncle Bob又力推Bowling Game,所以原本想拿來當kata練一下不同的語言

沒想到實做之後,才發現這是個滿棒的kata
邏輯不會太難,但可能寫成超複雜的,滿多重構的行為,而且很適合當TDD的教材
把所有的team member都抓來練習一下

以下整理最近帶team member的心得
  • Refactoring (clean code)
    • 變數、method的命名
      刻意讓team member命名滾球、局數
      最後讓大家猜別人命名的意思
      最後讓大家直接用保齡球的術語roll, frame
      clean code: 不懂時,直接請domain expert命名,至少以後domain expert能夠說出這是什麼
    • redundant code
      去除重覆的程式
    • decompose condition
      讓程式變的更加clean, isSpare,isStrike,getSpareBonus那段
    • 隱藏細節
      上一段的延伸,有些team member把整段getSpareBonus做成calSpareBonus
      感覺上沒什麼差,但在看code感覺差很多
      • calSpareBonus
        這個function叫做score(算總分),因此這function最重要的事就是"算分數"
        但這裡把算分的邏輯隱藏了,因此未來看code的人,不易注意到score被其他function異動了
        int score = 0;//成員變數 - 總分 
        public int score(){
            //略
            if (isSpare())
                calSpareBonus(); 
            //略
        }
      • getSpareBonus
        關於score的異動,能夠清楚掌握
        而Spare的Bonus算法在這不重要,因此隱藏起來
        讓程式更容易閱讀
        public int score(){
            int score = 0;//總分
            //略
            if (isSpare())
                score += getSpareBonus(); 
            //略
        }
  • Pair-Programming
    自己開發會有盲點,跟幾個同事練習的過程中
  • 在算跨局的輯邏會想的滿複雜的,但partner會參與討論 也許沒能討論出更好、更簡單的解法,但至少那段神邏輯有另一個人"看的懂"
  • TDD
    只滿足目前的需求即可
    開發上,大家容易被分數算法綁住,因此一開始想把邏輯寫對
    但這不太容易,因為算法還得考慮Spare, Strike,因此一次要把邏輯寫出來有點難
    寫完,你也不會寫test case了,因為已經寫完繳卷了

    這點最適合TDD指的只滿足目前的需求即可
    先寫個最簡單的算法驗證,再來spare,再來strike,一個個拼出完整的邏輯
    也許整個寫法得翻掉重寫,但令人放心的是test case已經寫好了
    所以可以放心重寫

    雖然一直說TDD很棒,但沒實際體會過,大家只會覺得很難達成
    實際經歷好幾次的大改結構,但重新測試的時間,卻只是一瞬間
    大家就能體會TDD好處

回想其實好久以前就看過這Bowling Game的練習(很多對話那個)
不過就只有用"看"的,沒有實際寫過,身體力行的體驗果然不一樣
大家也來kata一下

p.s. 不過我以為這保齡球算法的方法大家應該都瞭解
沒想到大家都忘了... 話說上次打應該也是5年前了...

更多的Kata題目

星期六, 8月 23, 2014

CentOS 7 無法access apache

前陣子聽到CentOS 7出了,載下來裝好發現連不到網頁
搞不清楚問題在哪,最後猜是SELinux~
# sestatus
SELinux status:                 enabled    
SELinuxfs mount:                /selinux
Current mode:                   enforcing
Mode from config file:          enforcing
Policy version:                 24
Policy from config file:        targeted
果然是開啟的
再來就來關掉selinux
改成disabled
# vi /etc/selinux/config
--
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#       enforcing - SELinux security policy is enforced.
#       permissive - SELinux prints warnings instead of enforcing.
#       disabled - No SELinux policy is loaded.
SELINUX=disabled
# SELINUXTYPE= can take one of these two values:
#       targeted - Targeted processes are protected,
#       mls - Multi Level Security protection.
SELINUXTYPE=targeted
再一次
# sestatus
SELinux status:                 disabled

很高興的以為抓到問題,但restart後一樣連不到... QQ
試好久,猜應該是firewall問題
果然一查CentOS 7 firewall,就找到答案了
以下截錄 關閉 CentOS 7 上的 Firewall
關閉 Firewall
# systemctl stop firewalld

預設不啟動 Firewall
# systemctl disable firewalld
rm '/etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service'
rm '/etc/systemd/system/basic.target.wants/firewalld.service'

總於... 連的到網頁了... ya

星期日, 8月 17, 2014

How to undo the last Git commit?

如何調整已經commit的.... commit



$ git commit "待調整的commit"   (1)commit後
$ git reset --soft 'HEAD^'       (2)回剛才的commit 
$ edit                           (3)重新調整
$ git add ....                 (4)
$ git commit -c ORIG_HEAD      (5)跳視窗修改commit message"待調整的commit"


p.s. 上次回復(revert)到太早期的版本,造成一堆commit都不見
幸好git還是有保留下來,不然就挫咧等...

星期六, 8月 16, 2014

[書]The Clean Coder

滿精采的一本書,讓開發人員要自我要求,更要表現出專業,勇敢的說Yes/NO

Chapter 1. 專業主義
  • Minimal-list
    Uncle Bob說軟發開發人員"至少"需"精通"的項目
    • Design Patterns
    • Design Principles
      SOLID
    • Methods
      XP, Scrum, Lean, Kanban, Waterflow,結構化分析及結構化設計等
    • Disciplines
      TDD, OOD, Continuous Integration, Pair Programming
    • Artifacts
      UML, DFD, 結構圖, Petri網路圖, 狀態圖,流程圖和決策表
Chapter 2. Say "NO"
能就是能,不能就是不能。不要說「說說看」 --Yoda
每次專案一趕,就一定會說的話... (泣)

Chapter 6. 練習
熟能生巧,訓練手指和大腦,每天來一、兩個kata保持技巧純熟
reference: Code Kata
  • Bowling Game
  • Prime Factors
Chapter 9. 時間管理
開會的成本很高,有時又是沒有效益的
管理自己的時間是自己的責任
  • 離席
    如果發現會議是在浪費時間,應在合適的時機,禮貌地離席
    如果已經偏離原有的議程,應要求列新的議題和議程
  • 爭論/反對
    Kent Beck:凡是不能在5分鐘內解決的爭論,都不能靠辯論解決。」因各方拿不出「足夠有的有的證據」
    唯一解決方法是「去取得資料,讓資料來說話」

星期六, 8月 09, 2014

Google表單發確認信

Google表單挺方便的,又是免費使用,資料又自動整理到Google Drive的試算表
而內含的編輯器也可加trigger發送確認信


  1. 新增表單
    點選「新增/Google表單」
  2. 查看回應
    表單的設計就不多說了,直接看回應
    點選「查看回應」
  3. 編輯指令
    點選「工具/指令碼編輯器」
  4. 新增Script檔案
    點選「檔案/新增/指令碼檔案」
  5. 編輯Script
    以下程式碼即為上圖的程式,參考以下改來的
    reference: Send Google Forms by Email
    /* Send Confirmation Email with Google Forms */
    function SendGoogleForm(e) {  
      var message = '';
      for (var filed in  e.namedValues) {
            message += filed + ": " +  e.namedValues[filed] + '< br />';        
        }
         var recipient = e.namedValues['電子信箱']; //e即為回覆的試算表,而namedValues即取得該欄位名的內容
        var cc = 'yup.japan@gmail.com';          //cc一份給自己
        var subject = "Yup!代購單確認單";
        var sendername = 'Yup!代購';
        var textbody = message.replace('< br />', '\n');
        GmailApp.sendEmail(recipient, subject, textbody, 
                                {cc: cc, name: sendername, htmlBody: message});
    }
    
    function Initialize() {
      var triggers = ScriptApp.getProjectTriggers();
     
      for(var i in triggers) {
        ScriptApp.deleteTrigger(triggers[i]);
      }
      
      ScriptApp.newTrigger("SendGoogleForm")
      .forSpreadsheet(SpreadsheetApp.getActiveSpreadsheet())
      .onFormSubmit()
      .create();
    }
  6. 啟動程序
    寫好Script,現在還得設定觸發
    點選「資源/現在專案的啟動程序」
    p.s. 如果仍收不到信的話 要先跑一次initialize(),手動執行or設觸發都可
  7. 新增觸發程序
    由於尚未建立任何觸發程序,因此會跳出這個視窗
    點選「尚未建立觸發程序,按一下....」
  8. 設定觸發程序
    設定user提交表單時,才會觸發程序

這樣就完成了,user提交表單後,就會發信通知

p.s. 在google form及google試算表都可以寫script,但在form觸發會抓不到內容
p.p.s. 好像得先按「執行」run過一次程式裡的Initialize()

星期日, 7月 27, 2014

如何寫unit test

以前覺得unit test不就寫test case
想到啥,就寫啥,沒有目標的亂寫
記得以前連搬檔案都寫了一個case來測
最近領悟了點東西,趕緊來整理一下

  • 測試資料
    寫test case最麻煩的地方在準備測試資料
    由於資料大多存取DB,因此得準備一個測試DB
    但資料被改後,還得再倒回去,否則test case會fail
    以前都用dump,再整個倒回去
    開發上還挺累人的

    個人測試還好,多人用同一個測試DB,就會互相蓋DB
    難道要一人一DB嗎... 這提出申請,一定被上頭打槍...

    後來才瞭解,這不是unit test
    這已經是integration test(接DB)
    unit test應該在幾秒內跑完才叫unit test
  • 利用Mock & Stub模擬測試資料
    後來就利用這做法,避免接DB,及外部API的動作
    說方便... 是比接DB方便... 但也還好...還是得寫一堆code,只為了準備測試資料
    想利用TDD寫好unit test,還是挺花時間的
    要說服其他人用,力道上還是不夠
  • 測邏輯就好
    直到前陣子,Kent Beck, Martin Fowler及DHH在討論「 IS TDD DEAD 」
    DHH在說實務上用TDD不可行,當然是被兩位大師訓了一頓...
    不過影響最深刻的是Martin Fowler說他幾乎沒在寫Mock

    實在太令人驚訝了...居然沒在寫mock.....
    很想實際看一下些大師怎麼寫的...

    雖然還是不知道大師怎麼寫的
    不過自己重新領悟unit test就是在測試邏輯
    即然是測邏輯.... 那.... 就把邏輯這段再抽成一個function獨立出來就容易測了
    YA~~
    現有終於可以輕鬆的寫test case (泣)
當然~ 難免有些地方還是不好寫unit test
大師也說... 不好寫的就不要刻意寫,工具有他的極限
不要硬寫,而搞死自己 <= 好吧 這句是我自己將來為了辯解沒寫unit test的藉口

星期日, 7月 13, 2014

[書]敏捷與Scrum軟體開發速成

最近在聽同事在提Scrum
自己的team都是用XP開發
Scrum這詞也聽好幾年了,但一直不知道有何差異
聽完同事說的,還是掌握不到做法
有點見樹不見林的感覺
說完還是不知怎麼做











今天正好路過書店逛了一下
看到「敏捷與Scrum軟體開發速成」Amazon有4.5顆星的評價
嘖嘖~ 直接買來看

章節安排挺不錯,很順暢的一篇篇讀,也不會太多廢話,有些真的話很多...
從敏捷方法的緣起說起
再強調敏捷的價值觀與原則,不會硬套方法
最後帶入實務做法
感覺讀完就上手了~ 怪不得4.5顆星了~
近期來試一下...

翻譯也挺不錯的,用詞都很到味,可以感覺譯者懂這方面的domain knowledge
譯注也很用心在寫,第一次看過這麼多譯注
某些文化梗也有翻,而有些資料也得花時間找~
真是佛心來著~

星期五, 5月 23, 2014

程式應易抽換,而非再利用

幾年前看到這句話「程式應易抽換,而非再利用」,一直看不懂這意思
過去觀念一直是程式應模組化,以便「重覆使用」
怎麼會這麼說呢

最近在學軟體架構,講師又提到這詞
沒說沒感覺,再回去review Design Patterns
還真的都在說易更換,而非重覆使用
為什麼呢

先看這句Prefer composition over inheritance (組合超越繼承)
這句話也讓我想了很久
物件的好處不就是要繼承嗎?
怎麼又要我們不要用繼承,那過去在學的是什麼

原因1:父類別的改變就會直接影響所有的子類別
原因2:因為程式只會對父類別操作,所以子類別需熟悉父類的實作(例如父類別的function實作二件事,而子類別只實無一件事)

因此用composition不會影響原結構而且易於抽換不同的物件
所以"Prefer composition over inheritance"
而這句就代表了「程式應易抽換,而非再利用」

真是太深奧了...

星期四, 5月 08, 2014

DB 記憶體緩慢上升

最近DBA提到DB的記憶體有緩慢上升的問題

後來知道這是DB的機制,本來就會把記憶體吃滿
但DBA還是提出這樣他無法告之記憶體是否需擴充

針對這問題得看塞的內容是什麼
經過分析,我們的sql plan重複使用太低
也就是sql statement不重複,造成每次得重新compile新的sql

  • 減少Compile次數
    • 使用Stored Procedure
      微軟建議SQL compile 不要超過 Batch Request的10%, 但我們的系統大約在40%
      因此建議我們用Stored Procedure,當然我們沒用這方面
    • 使用prepare(bind)
      我本以為prepare只是用來過濾sql injection
      原來db在執行時,也得把sql statement先compile過
      因此where的條件不同,就會被當成新的statement

      這時便可透過prepare,把參數給參數化 (我想不到更好的詞了 Orz)
      如此一來該句只會被compile一次~

      p.s. sql也是需被compile的,嗯... 我從沒想過這問題...

    • PHP的PDO未實際改寫
      我們早就用bind的方式寫sql,但不曉得為何仍沒有轉換
      後來才發現原來PDO沒有實際轉換,而只是replace而已
      p.s. 不確定是PDO or 其他地方,先拿PDO當替死鬼


星期一, 3月 03, 2014

tmux亂碼

把vi設定好後,本以為完成了
set encoding=utf-8
set fileencodings=utf-8,cp950,latin1

但有時正常,有時又亂碼,一直搞不懂
cli下的中文是「?????」
而vi下的會是「______________」

後來發現在進tmux後,才會發生這問題
查了一下,加上以下這段再重開tmux就可以了
vi ~/.bash_profile
export LANG="zh_TW.utf8"
export LC_ALL="zh_TW.utf8"

Reference
tmux,亂碼已成往事

星期四, 2月 20, 2014

MS SQL資料庫定序(Collation)的議題

問題
當兩個column join時,而兩個定序不同,這時這個sql session就直接死給你看

解決方法
  1. 從db設定(但資料要重建)
    db, column都可以指定
  2. sql query直接指定
    SELECT str FROM test ORDER BY str COLLATE CHINESE_TAIWAN_STROKE_CI_AS
CS_AI vs CI_AS 傻傻搞不清楚
  • CaseSensitive_AccentInsensitive
  • CaseInsensitive_AccentSensitive
其他還有WS (Width sensitivity),即全型、半型字是否相同

Reference

星期日, 2月 09, 2014

[書]even faster web sites performance-best practices for web developers

針對js, css, image, browser等深入探討,以求最佳的效能


Ch1. Understanding Ajax Performance

Trade-offs - Fast. Good. Cheap. Pick Two.
  • 低於Inefficiency line就會流失user
  • 先利用YSlow改善
  • 利用ajax可大副降n,當然前提要考量ajax本體application要小
  • 事後再抓資料呈現
  • DOM及CSS的處理比JS的速度慢的多,針對JS加速不如小心處理DOM及CSS

Ch.2 Createing Responsive Web Applications

What is fast enough
  • ajax實現快速反應系統
  • 只針對不夠快的程式調整,重點是如何定義「不夠快」
    • 0.1 second : Limit for users feeling that they are directly manipulating objects in the UI. 例如hover
    • 1 second: Limit for users feeling that they are freely navigating the command space without having to unduly wait for the computer. 0.2秒~1秒會感覺在運作
    • 10 seconds : Limit for users keeping their attention on the task.
  • 也就是說application要在0.1s內啟動, 在1s內有所回應
  • 超過1s會讓user感覺到慢, 超過10s.... 該調程式了...

Meausuring Latency
  • 可利用firebug的profiler找出js的執行時間
  • Threading - js沒有mutilthread,不要想有的沒的 這只會把程式搞複雜
  • HTML5有Web Workers可達到threads效果,拿來當背景程式跑長時間的script
  • 如果browser不支援,google有Gears plugin-in

Effects of Memory Use on Response Time

  • memory也會造成效能issue
  • 在run GC時,會run整個heap,回收不再使用的物件,因此大量使用下,會讓系統發生短暫凍結
  • OS會提供virtual memory這比實體memory慢的多
  • Troubleshooting Memory Issues
    • 針js的memory沒有神器,只能追問題所在,參考 http://blog.pavlov.net/2008/03/11/firefox-3-memory-usage/
    • Use the delete keyword to remove JavaScript objects that are no longer needed
      from memory.

ch.3 Splitting the Initial Payload

  • 必要的application script先讀,不重要的後讀
  • 不相關的script模組就不要讀
  • 後讀的ui相關script要能先呈現loading圖示,避免user使用(lazy-loaded code)
  • stub function
    • 先回應空的,等載完後再覆寫
  • splitting script & CSS都能達到效果

Ch4. Loading Scripts without Blocking

  • 下載external script 會造成blocking(下載中的資源不會被擋)



ie8, Safari 4, Chrome 2可同時下載,但得等js載完且跑完,才會再下載其他資源
有方法可避開blocking的問題,但同時也有race conditions問題
即script如有順序問題,後者先執行會發生錯誤
解決方法
  • XHR Eval
    • 當資源下載後,用eval
    • 缺點:需在同一domain
  • XHR Injection
    • 把js當dom方式插入
    • 缺點:比eval慢
  • Script in Iframe
    • 開iframe把script當html下載
    • 缺點:需在同一domain, iframe耗資源
  • Script DOM Element
    • 方法:create個dom,改src,簡單易懂
    • var scriptElem = document.createElement('script');
      scriptElem.src = 'http://anydomain.com/A.js';
      document.getElementsByTagName('head')[0].appendChild(scriptElem);
  • Script Defer
    • 增加defer屬性,可平行下載
    • 缺點:只有ie支援
  • document.write Script Tag
    • 類似defer,可平行下載
    • 缺點:只有ie會平行下載
Ensuring (or Avoiding) Ordered Execution
利用script src寫法可確認依序下載


Ch.5 Coupling Asynchronous Scripts

Ch.6 Positioning Inline Scripts

Ch.7 Writing Efficient JavaScript
Managing Scope

Ch.8 Scaling with Comet

Ch.9 Going Beyond Gzipping

  • Besides proper configuration of HTTP caching headers, enabling gzip compression is typically the most important technique for speeding up your web page
  • 目前的browser都支援gzip,但會因firewall或防毒軟體限制而禁作gzip
  • 針對這些可以有以下做法
    • Design to Minimize Uncompressed Size
      • Use Event Delegation (選完才載入)
    • Use relative URLs
      • 同網站內的uri可以用相對路徑,這樣文字相對少
    • Strip whitespace
    • Strip attirbute quotes
      • html裡的attribute內容如為純文字(含括號,底線,分號等)可省略雙引號
    • Avoid inline styling
      • style多為重覆使用,寫在css共用
    • Alias JavaScript
      • Wasteful
        • var foo = $("foo);
        • foo.style.left = "0";
        • foo.style.right = "0";
      • Better
        • var foo = $("foo).style;
        • foo.left = "0";
        • foo.right = "0";
  • 以上約可節省11.7的傳輸量
Educate Users
  • 發生user不支援Accept-Encoding,應給個訊息提供,教育user
    • ex. Your Internet connection is slowed because it does not allow compression.
    • 不過經過proxy來的是無法解決的
Fix this Hide

Ch.10 Optimizing Images

  • GIF - 適用小動畫
  • PNG - 適用圖表(graphics - icons, logos, diagrams) 
  • JPG - 適用照片(photos)
Truecolor versus palette image formats
Interlacing

Stripping JPEG Metadata

  • Comments
  •  Application-specific (e.g., Photoshop) internal information
  •  EXIF information such as camera make and model, the date the photo was taken, the geolocation of the photo, thumbnails, or even audio

Ch.11 Sharding Dominant Domains

Ch.12 Flushing the Document Early

Ch.13 Using Iframes Sparingly

Ch.14 Simplifying CSS Selectors

  • 將css置於head中,以提高progressive rendering. (See High Performance Web Sites, Chapter 5.)
  • ie可能發生css expression被執行上千次
  • 避免inline styling,以減少download size
CSS Selectors有以下幾種方式
  • ID SelectorsExample: #toc { margin-left: 20px; }Simple and efficient
  • Class SelectorsExample: .chapter { font-weight: bold; }
  • Type SelectorsExample: A { text-decoration: none; }a lightweight way to add styling to all elements of a specified type, without having to add any extra characters
  • Adjacent Sibling SelectorsExample: H1 + #toc { margin-top: 40px; }
  • Child SelectorsExample: #toc > LI { font-weight: bold; }找出#toc下所有的LI(1層)
  • Descendant SelectorsExample: #toc A { color: #444; }找出#toc下所有的A(n層)
  • Universal SelectorsExample: * { font-family: Arial; }
  • Attribute SelectorsExample: [href="#index"] { font-style: italic; }
  • Pseudo-Classes and Pseudo-ElementsExample: A:hover { text-decoration: underline

以下討論performace

Rightmost First

Consider the following rule:
#toc > LI { font-weight: bold; }
由於id最有效,因此大家會認為先找#toc,再找底下的LI是較好的方法(左到右)
但其實browser是從右到左,因此這段selector反而相當沒效率,但先找出所有的LI,再看他的parent是不是#toc
可以想見Descendant Selectors就更差了,所有的node除非找到#toc,否則都要走完

Writing Efficient CSS Selectors

  • Avoid universal rules
    In addition to the traditional definition of universal selectors, Hyatt lumps adjacent
    sibling selectors, child selectors, descendant selectors, and attribute selectors into
    this category of “universal rules.” He recommends using ID, class, and tag selectors
    exclusively.
  • Don’t qualify ID selectors
    Because there is only one element in the page with a given ID, there’s no need to
    add additional qualifiers. For example, DIV #toc is unnecessary and should be

    simplified to #toc.
  • Don’t qualify class selectorsInstead of qualifying class selectors for specific tags, extend the class name to be specific to the use case. For example, change LI .chapter to .li-chapter , or better yet, .list-chapter.
  • Make rules as specific as possibleDon’t be tempted to build long selectors, such as OL LI A. It’s better to create a class, such as .list-anchor, and add it to the appropriate elements.
  • Avoid descendant selectorsDescendant selectors are typically the most expensive to process. Child selectors are often what’s intended and can be more efficient. It’s even better to follow the next guideline to avoid child selectors as well.
  • Avoid tag-child selectorsIf you have a child selector that is based on a tag, such as #toc > LI > A, use a class associated with each of those tag elements, such as .toc-anchor. 
  • Question all usages of the child selectorThis is another reminder to review all places where child selectors are used, and replace them with specific classes when possible.
  • Rely on inheritanceLearn which properties are inherited, and avoid rules that specify these inherited styles. For example, specify list-style-image on the list element instead of on eachlist item element. Consult the list

星期六, 1月 18, 2014

利用git管理production及development程式

個人開發可利用branch避免開發中的code影響緊急bug修正的問題
不過在團隊開發下,不曉得怎麼區分管理

看了網路上的建議,自己簡化為
建立production branch
1.開發用master
2.緊急上版用production修bug

另外...
由於公司內規定得透過包版上patch
而公司用CCCQ管理包版,因此每次都得再重上程式
這辦法也解決每次上patch都不確認是否有包到這次異動的檔案
看production merge後異動的檔案,即為patch內容
真是太棒了

不過
其實作者是建議切成staging, development, production三個
前者可拿來驗證後才准入後者
但是上測試機一樣得進CCCQ,才能包版更新... 所以就沒考慮了
反正開發機試完,只能進CCCQ上測試機...

Reference
Developing and Deploying with Branches