totec2014_front_presen



totec2014_front_presen

0 0


totec2014_front_presen

presentation of totec2014 frontend tuning

On Github varmil / totec2014_front_presen

TOTEC2014 front-end Review

name = '山本 晃大'
occupation = 'ぎじゅつけい'
properties = [
    'JSer', 'Underscore.js', 'Node.js'
    'PHPer(過去の話)', 'isucon'
]

Created By Akihiro Yamamoto

アジェンダ

どんな大会なのか 考えたこと やったこと やったこと具体例 まとめ

どんな大会なのか

何を競うの?

どんな大会なのか

  • HTMLファイルサイズ
  • CSSファイルサイズ
  • JavaScriptファイルサイズ
  • 画像ファイルサイズ
  • リクエスト数
  • DOM要素数
  • JavaScriptのエラー有無(1つでもエラーがあればNG)
  • チューニング前後の表示差異(ImageMagickによる平均画素数比較で閾値を超えるとNG)

どんな大会なのか

  • 11:00~18:00 の7時間に渡って競技が行われる
  • アメーバ水が飲み放題、お昼はサンドイッチ配布

考えたこと

(勝ちに行こう)

考えたこと

  • Try and Error をとにかく多く
    • commit, pushを細かく刻む

考えたこと

  • スコアにならないことは全て無視
    • Response time
    • リクエスト数の削減( 100point/req )

考えたこと

  • 何よりも「ハマらない」こと
    • 使い慣れたgruntの利用
    • 経験がほぼ無かったCSS Spritesはスルー

やったこと

消す、纏める

(100%これだけです)

やったこと

インフラチューニングの時のように

VarnishでFOOOO!!!

というような華麗な技は無し

やったこと

とりあえず開始前に gulp-webserver の導入

var gulp = require('gulp');
var webserver = require('gulp-webserver');

gulp.task('webserver', function() {
    gulp.src('pu7mQgd')
        .pipe(webserver({
            livereload: true,
            directoryListing: true,
            port: 9999,
            fallback: 'index.html'
        })
    );
});

gulp.task('default', ['webserver']);

やったこと

  • [html]不要CSS、JSファイルのloadを削除
  • [html]不要DOM、classの削除
  • [html]grunt-contrib-htmlminによるminify
  • [css]不要プロパティの削除
  • [css]grunt-contrib-cssminによるminify
  • [js]不要クラス、不要メソッドの削除
  • [js]grunt-contrib-uglifyによるminify
  • [画像]ImageMagickによる画像圧縮
  • [画像]pngquantによる画像圧縮
  • [その他]grunt-contrib-concatによるJS、CSSの結合

やったけどrevertしたこと

  • cdnjsからライブラリload
    • 手っ取り早くminifyされたファイルが欲しかった
    • HTMLのサイズが小さくならない+concat不可
    • 故に、明らかな悪手

やったけどrevertしたこと

  • zepto.jsの利用
    • JSエラーが大量に出る+何か厄介そう
    • ということで、1分で諦める

やったけどrevertしたこと

  • benchmarkツールの死角を突いて画像を超圧縮!!
    • 良い戦略だった
    • 審査員から「失格にするよ」と脅されたので断念
convert -quality 10 ./images/features/2.png ./img_o/features/2.jpg
convert -quality 10 ./images/features/3.png ./img_o/features/3.jpg
convert -quality 10 ./images/features/4.png ./img_o/features/4.jpg
convert -quality 10 ./images/features/5.png ./img_o/features/5.jpg

やったけどrevertしたこと

これが元画像で...

やったけどrevertしたこと

実際に提出しようとした画像がこちら

(ファイルサイズ 1/50)

やったこと具体例

不要なloadを減らす ライブラリ本体の削減 gruntを使う JS, HTML, CSSのMinify, concat 不要DOM,Classの削除 画像圧縮

やったこと具体例 | 不要なloadを減らす

before(cssも同様)
(24ファイル。多すぎるので2列)

"javascripts/jquery-1.11.1.js", "javascripts/underscore.js"
"javascripts/underscore.string.js", "javascripts/backbone.js"
"javascripts/bootstrap.js", "javascripts/coffee-script.js"
"javascripts/createjs-2013.12.12.min.js", "javascripts/imgLiquid.js"
"javascripts/jquery-ui.js", "javascripts/jquery.bxslider.js"
"javascripts/jquery.cycle.all.js", "javascripts/jquery.ellipsis.js"
"javascripts/jquery.heightLine.js", "javascripts/jquery.localscroll.js"
"javascripts/jquery.maximage.js", "javascripts/jquery.scrollto.js"
"javascripts/jquery.slides.js", "javascripts/jquery.smarttruncation.js"
"javascripts/masonry.pkgd.js", "javascripts/paper-full.js"
"javascripts/tabulous.js", "javascripts/trunk8.js"
"javascripts/jquery.smoothScroll.js", "javascripts/modernizr.custom.86912.js"

やったこと具体例 | 不要なloadを減らす

after
(14ファイル)

'javascripts/jquery-1.11.1.js',
'javascripts/underscore.js',
'javascripts/underscore.string.js',
'javascripts/backbone.js',
'javascripts/coffee-script.js',
'javascripts/imgLiquid.js',
'javascripts/jquery.bxslider.js',
'javascripts/jquery.ellipsis.js',
'javascripts/jquery.heightLine.js',
'javascripts/jquery.localscroll.js',
'javascripts/jquery.maximage.js',
'javascripts/jquery.scrollto.js',
'javascripts/masonry.pkgd.js',
'javascripts/jquery.smoothScroll.js'

やったこと具体例 | ライブラリ本体の削減

ex) backbone.js: 61kb => 9kb

ex) bootstrap.css: 133kb => 2kb

=> ライブラリ本体もゴリゴリ削る

やったこと具体例 | gruntを使う

  • これらの作業は割と序盤からwatchしながら行った。
watch: {
    js: {
        files: 'javascripts/*.js',
        tasks: ['concat:js', 'uglify']
    },
    css: {
        files: 'stylesheets/*.css',
        tasks: ['concat:css', 'cssmin']
    },
    html: {
        files: './src/index.html',
        tasks: ['htmlmin']
    }
}
  • 反省:序盤ではbuildに結構な時間がかかった。

やったこと具体例 | gruntを使う

  • 反省:JSエラーが見辛いこと、この上なし

  • 苦肉の策で、いじるファイルは外出しして作業

<scrip src="javascripts/backbone.js"></scrip>
<scrip src="min/jm.js"></scrip>

補足(今日知りました)

sourceMap オプションを使いましょう(自戒)

uglify: {
    dist: {
        options: {
            // 同階層にjm.js.mapファイルが生成される
            //# sourceMappingURL=jm.js.map というリンクがjm.jsの末尾に挿入される
            sourceMap: true
        },
        files: {
            'min/jm.js': 'concat/j.js'
        }
    }
},

補足(今日知りました)

使うと、こうなります。

やったこと具体例 | JS, HTML, CSSのMinify, concat

gruntでファイル変更を監視しつつ...

concat: {
    js: {
        src : [
            'javascripts/jquery-1.11.1.js',
            'javascripts/underscore.js',
            'javascripts/underscore.string.js',
            ...(略)...
        ],
        dest: 'concat/j.js'
    },
    css: {
        src : [
            'stylesheets/bootstrap.css',
            'stylesheets/jquery.bxslider.css',
            'stylesheets/main.css'
        ],
        dest: 'concat/c.css'
    }
},
uglify: {
    dist: {
        files: {
            'min/jm.js': 'concat/j.js'
        }
    }
},
htmlmin: {
    dist: {
        options: {
            removeComments: true,
            collapseWhitespace: true
        },
        files: {
            './index.html': 'src/index.html'
        }
    }
},
cssmin: {
    combine: {
        files: {
            'min/c.css': 'concat/c.css'
        }
    }
},

やったこと具体例 | 不要DOM,Classの削除

BEFORE
<section class="Sitesummary">
    <div class="Sitesummary-element-container">
        <div class="inner">
            <div class="Sitesummary-permalink-block">
                <h1>
                    <div class="Sitesummary-text-block">
                        <span class="Sitesummary-button-spot">
                            <img src="images/visual-title.png" alt="Pashalistock Tokyo.
                            100% Free Stock Photos. Every. Single. Week.
                            Everything you need for your creative projects, all public domain images!">
                        </span>
                    </div>
                </h1>
            </div>
        </div>
    </div>
</section>

やったこと具体例 | 不要DOM,Classの削除

AFTER
<section class="Sitesummary">
        <div class="inner">
                <h1>
                    <img src="images/visual-title.png">
                </h1>
        </div>
</section>

やったこと具体例 | 画像圧縮

ImageMagick, pngquantの併用

convert -quality 75 ./images/visual-photo.png ./img_o/visual-photo.jpg
convert -quality 75 ./images/features/1.png ./img_o/features/1.jpg
convert -quality 75 ./images/features/2.png ./img_o/features/2.jpg
convert -quality 75 ./images/features/3.png ./img_o/features/3.jpg
convert -quality 75 ./images/features/4.png ./img_o/features/4.jpg
convert -quality 75 ./images/features/5.png ./img_o/features/5.jpg

pngquant --ext _.png images/photos/ *.png
pngquant --ext _.png images/onlineshopitems/ *.png

(割と適当)

まとめ

正味作業時間への意識 不要なコードは書かない 1度に1つのことだけをやる

まとめ

  • 正味作業時間への意識
    • ムダ:考えている ふり
    • 付加価値のない作業:準備、調べもの、仕様確認
    • 正味作業:意味のあるコードを書く

まとめ

  • 不要なコードは書かない
    • (後で使うかも!というのは甘えであり幻想では?)

まとめ

  • 1度に1つのことだけをやる
    • PDCAサイクルの早さが違う
n = changedNumber
complexity = Math.pow(2, n) - 1

ご清聴ありがとうございました

0