J qmobiはjqueryから軽量化しているか
Upcoming SlideShare
Loading in...5
×
 

J qmobiはjqueryから軽量化しているか

on

  • 2,084 views

jqMobiとjqueryの違いなど

jqMobiとjqueryの違いなど

Statistics

Views

Total Views
2,084
Views on SlideShare
2,083
Embed Views
1

Actions

Likes
1
Downloads
3
Comments
0

1 Embed 1

https://twitter.com 1

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    J qmobiはjqueryから軽量化しているか J qmobiはjqueryから軽量化しているか Presentation Transcript

    • jqMobiはjQueryからどうやって 軽量化しているかの一側面 有路 央 伊達巻の日。
    • jQueryとjqMobiを単純比較してみる• jQuery minified 92kb• jqMobi min 15kb• jQueryMobile minified 89kb• jqUi min 71kb全て圧縮/難読化済みのjsのプログラムサイズ
    • ところで みなさん、jQueryにおけるselector使ってますか? • $(“#id”) • $(“.class”) • $(“div.music > spant.title”) • $(“div.class, span.class”) などなど
    • ところで みなさん、jQueryにおけるselector使ってますか? • $(“#id”) • $(“.class”) • $(“div.music > spant.title”) • $(“div.class, span.class”) などなど これらがどうやって動いているか見てみましょ う
    • http://code.jquery.com/jquery-1.7.2.js init: function( selector, context, rootjQuery ) { var match, elem, ret, doc; // Handle $(""), $(null), or $(undefined) $() <- jQuery Objectが if ( !selector ) { 欲しいときなど return this; } // Handle $(DOMElement) if ( selector.nodeType ) { this.context = this[0] = selector; $(document) this.length = 1; $(document.getElementById(“id”)) な return this; ど } // The body element only exists once, optimize finding it if ( selector === "body" && !context && document.body ) { this.context = document; this[0] = document.body; this.selector = selector; $(“body”)用 this.length = 1; return this; }
    • ここからが本番 事前準備// Handle HTML strings if ( typeof selector === "string" ) { // Are we dealing with HTML string or an ID? if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { // Assume that strings that start and end with <> are HTML and skip the regex check match = [ null, selector, null ]; Htmlタグを入力したとき } else { match = quickExpr.exec( selector ); } quickExpr = /^(?:[^#<]*(<[wW]+>)[^>]*$|#([w-]*)$)/ タグ(<>で囲まれたワード)と#で始まる文 字を抜き出している match[0] = selectorの該当全部 match[1] = タグの中身(があった場合) match[2] = #から始まるワード(があった場 合)
    • タグの場合 // Verify a match, and that no context was specified for #id if ( match && (match[1] || !context) ) { // HANDLE: $(html) -> $(array) if ( match[1] ) { context = context instanceof jQuery ? context[0] : context; doc = ( context ? context.ownerDocument || context : document ); // If a single string is passed in and its a single tag // just do a createElement and skip the rest ret = rsingleTag.exec( selector ); Htmlタグからelementを作る if ( ret ) { if ( jQuery.isPlainObject( context ) ) { selector = [ document.createElement( ret[1] ) ]; jQuery.fn.attr.call( selector, context, true ); } else { selector = [ doc.createElement( ret[1] ) ]; } } else { ret = jQuery.buildFragment( [ match[1] ], [ doc ] ); selector = ( ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment ).childNodes; } return jQuery.merge( this, selector );
    • $(“#id”)の場合 // HANDLE: $("#id") } else { elem = document.getElementById( match[2] ); // Check parentNode to catch when Blackberry 4.6 returns // nodes that are no longer in the document #6963 if ( elem && elem.parentNode ) { // Handle the case where IE and Opera return items // by name instead of ID if ( elem.id !== match[2] ) { IDからgetElementByIdで return rootjQuery.find( selector ); Elementを取得 } // Otherwise, we inject the element directly into the jQuery object this.length = 1; this[0] = elem; } this.context = document; this.selector = selector; return this; }
    • ここまでselectorは#idのみ。では .class や より複雑なCSS selectorはどうやって判定しているのか // HANDLE: $(expr, $(...)) } else if ( !context || context.jquery ) { return ( context || rootjQuery ).find( selector ); // HANDLE: $(expr, context) jQuery.find()を利用 // (which is just equivalent to: $(context).find(expr) } else { return this.constructor( context ).find( selector ); } では findを見てみましょう
    • jQuery Line:5384 Sizzle.attr = jQuery.attr; Sizzle.selectors.attrMap = {}; jQuery.find = Sizzle; jQuery.expr = Sizzle.selectors; jQuery.expr[":"] = jQuery.expr.filters; jQuery.unique = Sizzle.uniqueSort; jQuery.text = Sizzle.getText; jQuery.isXMLDoc = Sizzle.isXML; jQuery.contains = Sizzle.contains; Sizzle だそうです。 Sizzleってなに?
    • Sizzleとは http://sizzlejs.com/ 2008/11/13に書かれたとあるblogの中にあったので引用 http://webos-goodies.jp/archives/51408207.html jQuery の開発者である John Resig 氏が、 次期 jQuery のために開発しているセレクタエンジンです。 これがjQueryに導入されリリースされたのが2009/1にでたjQuery1.3です。 jQueryのソースにもこんな感じで書いてあります /*! * Sizzle CSS Selector Engine * Copyright 2011, The Dojo Foundation * Released under the MIT, BSD, and GPL Licenses. * More information: http://sizzlejs.com/ */
    • Sizzleだけで、34kb 1,442行のjsプログラムです(無圧縮時)jQuery.min.js上の圧縮/難読化済みでも約11kb (有路調べ)内部的にも正規表現を多用しており決して速いとはいえないプログラムになっていま
    • Sizzleだけで、34kb 1,442行のjsプログラムです(無圧縮時)jQuery.min.js上の圧縮/難読化済みでも約11kb (有路調べ)内部的にも正規表現を多用しており決して速いとはいえないプログラムになっていま しかも
    • たいていのブラウザのjavascriptエンジン内にはquerySelectorAllというselectorを実装しているのです。ブラウザ側で実行するので当然高速です
    • たいていのブラウザのjavascriptエンジン内にはquerySelectorAllというselectorを実装しているのです。ブラウザ側で実行するので当然高速です つまりはSizzleはいらない子
    • たいていのブラウザのjavascriptエンジン内にはquerySelectorAllというselectorを実装しているのです。ブラウザ側で実行するので当然高速です つまりはSizzleはいらない子 jQuery内でも ~(Sizzleのコード) ~ if ( document.querySelectorAll ) { ~(中略)~ Sizzle = function( query, context, extra, seed ) { context = context || document; ~(中略)~ return makeArray( context.querySelectorAll(query), extra ); ~(後略)~ と容赦なく上書きしてます
    • jQueryからもSizzleのコードを削除したいのですが、 レガシーなブラウザのために残してあるのが実際のところでしょう Androidのwebブラウザ・iPhoneのブラウザ等にも 当然querySelectorAll は実装されています。https://developer.mozilla.org/en/DOM/Document.querySelectorAll Firefox Internet SafariFeature Chrome Opera (Gecko) Explorer (WebKit)Basic support 1 3.5 (1.9.1) 8 10 3.2 (525.3) Firefox OperaFeature Android Mobile IE Mobile Safari Mobile Mobile (Gecko)Basic support 2.1 yes 9 10.0 3.2
    • このことからjqMobiでは function _selector(selector, what) { var dom; if (selector[0] === "#" && selector.indexOf(" ") === -1 && selector.indexOf(">") === -1) { if (what == document) dom = what.getElementById(selector.replace("#", "")); else dom = [].slice.call(what.querySelectorAll(selector)); return dom; } selector=selector.trim(); if (selector[0] === "<" && selector[selector.length - 1] === ">") //html { var tmp = document.createElement("div"); tmp.innerHTML = selector.trim(); dom = [].slice.call(tmp.childNodes); } else { dom = [].slice.call(what.querySelectorAll(selector)); } return dom; } 約20行程度:700byte弱(無圧縮時)にすることに成功しています
    • まとめ• jQueryは過去のしがらみから重い(部分がある)• jqMobiは「mobileに特化」しているおかげで 切り捨てられるコードがある 以上。ご静聴ありがとうございました