You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@weex.apache.org by ta...@apache.org on 2017/07/28 09:12:10 UTC

[31/43] incubator-weex git commit: * [html5] fix test cases & rm perf utils.

* [html5] fix test cases & rm perf utils.


Project: http://git-wip-us.apache.org/repos/asf/incubator-weex/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-weex/commit/a2064a49
Tree: http://git-wip-us.apache.org/repos/asf/incubator-weex/tree/a2064a49
Diff: http://git-wip-us.apache.org/repos/asf/incubator-weex/diff/a2064a49

Branch: refs/heads/0.16-dev
Commit: a2064a49014b2200490f47f61158272ecf2bcd97
Parents: 7e6c95b
Author: MrRaindrop <te...@gmail.com>
Authored: Tue Jul 25 21:13:54 2017 +0800
Committer: MrRaindrop <te...@gmail.com>
Committed: Tue Jul 25 21:13:54 2017 +0800

----------------------------------------------------------------------
 build/config.js                             |   6 +-
 html5/render/vue/index.js                   |  19 --
 html5/render/vue/mixins/base.js             |  45 ----
 html5/render/vue/utils/lazyload.js          |  24 +-
 html5/render/vue/utils/perf.js              | 283 +----------------------
 html5/test/render/vue/components/list.js    |   2 +-
 html5/test/render/vue/components/switch.js  |   5 +-
 html5/test/render/vue/examples/list-cell.js |   2 +-
 html5/test/render/vue/helper/index.js       |   2 +-
 html5/test/render/vue/helper/main.js        |   3 +-
 html5/test/render/vue/helper/utils.js       |   4 +
 html5/test/render/vue/utils/lazyload.js     |  56 ++---
 html5/test/render/vue/utils/perf.js         |  94 +-------
 html5/test/render/vue/utils/style.js        |  52 +++--
 package.json                                |   3 +-
 packages/weex-vue-render/README.md          |  10 +-
 16 files changed, 89 insertions(+), 521 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/a2064a49/build/config.js
----------------------------------------------------------------------
diff --git a/build/config.js b/build/config.js
index 544ecd9..85470d7 100644
--- a/build/config.js
+++ b/build/config.js
@@ -85,8 +85,7 @@ const configs = {
     entry: absolute('packages/weex-vue-render/src/index.js'),
     dest: absolute('packages/weex-vue-render/dist/index.js'),
     banner:`
-console.log('START WEEX VUE RENDER: ${subversion['vue-render']}, Build ${now()}.');
-window._jslib_init_start = window.performance && window.performance.now && window.performance.now() || +new Date();\n\n`,
+console.log('START WEEX VUE RENDER: ${subversion['vue-render']}, Build ${now()}.');\n\n`,
     format: 'umd',
     plugins: [
       postcss(),
@@ -105,8 +104,7 @@ window._jslib_init_start = window.performance && window.performance.now && windo
     entry: absolute('packages/weex-vue-render/src/index.core.js'),
     dest: absolute('packages/weex-vue-render/dist/index.core.js'),
     banner:`
-console.log('START WEEX VUE RENDER CORE: ${subversion['vue-render']}, Build ${now()}.');
-window._jslib_init_start = window.performance && window.performance.now && window.performance.now() || +new Date();\n\n`,
+console.log('START WEEX VUE RENDER CORE: ${subversion['vue-render']}, Build ${now()}.');\n\n`,
     format: 'umd',
     plugins: [
       postcss(),

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/a2064a49/html5/render/vue/index.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/index.js b/html5/render/vue/index.js
index a307e80..8a00a57 100644
--- a/html5/render/vue/index.js
+++ b/html5/render/vue/index.js
@@ -19,7 +19,6 @@
 import weex from './env'
 import { setVue } from './env'
 import { base, style, sticky } from './mixins'
-// import styleMixin from './mixins/style'
 
 /**
  * init weex.
@@ -44,18 +43,9 @@ function init (Vue/*, options = {}*/) {
   Vue.config.isReservedTag = tag => htmlRegex.test(tag)
   Vue.config.parsePlatformTagName = tag => tag.replace(htmlRegex, '')
 
-  /* istanbul ignore next */
-  // if (process.env.NODE_ENV === 'development') {
-  //   if (semver.lt(Vue.version, '2.1.5')) {
-  //     console.warn(`[Vue Render] The version of Vue should be ` +
-  //       `greater than 2.1.5, current is ${Vue.version}.`)
-  //   }
-  //   console.info(`[Vue Render] Registered components: `
-  //     + `[${Object.keys(components).join(', ')}].`)
   Vue.mixin(base)
   Vue.mixin(style)
   Vue.mixin(sticky)
-  // }
 }
 
 // auto init in dist mode.
@@ -65,13 +55,4 @@ if (typeof window !== 'undefined' && window.Vue) {
 
 weex.init = init
 
-// perf stat for componentCount.
-window._component_count = 0
-
-// perf stat for JSLibInitTime.
-window._jslib_init_end = window.performance && window.performance.now() || +new Date()
-window._weex_perf.stat.JSLibInitTime = parseInt(window._jslib_init_end - window._jslib_init_start)
-delete window._jslib_init_end
-delete window._jslib_init_start
-
 export default weex

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/a2064a49/html5/render/vue/mixins/base.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/mixins/base.js b/html5/render/vue/mixins/base.js
index 3ecc1c8..06bc980 100644
--- a/html5/render/vue/mixins/base.js
+++ b/html5/render/vue/mixins/base.js
@@ -24,21 +24,6 @@ import {
   extend
 } from '../utils'
 
-import {
-  tagBeforeCreate,
-  // tagMounted,
-  tagRootMounted,
-  tagFirstScreen,
-  tagBeforeUpdate,
-  tagUpdated,
-  tagBegin,
-  tagEnd
-} from '../utils/perf'
-
-// import { extractComponentStyle } from '../core'
-
-// import config from '../config'
-
 let lazyloadWatched = false
 function watchLazyload () {
   lazyloadWatched = true
@@ -70,21 +55,9 @@ export default {
     if (!lazyloadWatched) {
       watchLazyload()
     }
-    if (process.env.NODE_ENV === 'development') {
-      tagBeforeCreate()
-    }
   },
 
   mounted () {
-    if (this.$options._componentTag === 'image') {
-      window._has_image_in_first_screen = true
-    }
-    if (this === this.$root) {
-      tagRootMounted()
-      if (!window._has_image_in_first_screen) {
-        tagFirstScreen()
-      }
-    }
     if (!weex._root) {
       weex._root = this.$root.$el
       weex._root.classList.add('weex-root')
@@ -104,31 +77,13 @@ export default {
     watchAppear(this)
   },
 
-  beforeUpdate () {
-    if (process.env.NODE_ENV === 'development') {
-      tagBeforeUpdate()
-    }
-  },
-
-  updated () {
-    if (process.env.NODE_ENV === 'development') {
-      tagUpdated()
-    }
-  },
-
   destroyed () {
     triggerDisappear(this)
   },
 
   methods: {
     _fireLazyload (el) {
-      if (process.env.NODE_ENV === 'development') {
-        tagBegin('base._fireLazyload')
-      }
       getThrottleLazyload(25)()
-      if (process.env.NODE_ENV === 'development') {
-        tagEnd('base._fireLazyload')
-      }
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/a2064a49/html5/render/vue/utils/lazyload.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/utils/lazyload.js b/html5/render/vue/utils/lazyload.js
index 16fdc1e..158377b 100644
--- a/html5/render/vue/utils/lazyload.js
+++ b/html5/render/vue/utils/lazyload.js
@@ -22,10 +22,6 @@
 import { isElementVisible } from './component'
 import { createEvent, dispatchEvent } from './event'
 import { throttle } from './func'
-import { tagImg } from './perf'
-
-const SCREEN_REC_LIMIT = 3  // just record the first 3 times for screen-render finishing.
-let doRecord = true
 
 function preLoadImg (src: string,
     loadCallback: ?(Event) => void,
@@ -40,14 +36,9 @@ export function applySrc (item: any, src: ?string, placeholderSrc: ?string): voi
   if (!src) { return }
   function finallCb () {
     delete item._src_loading
-    if (doRecord) {
-      if (window._weex_perf.renderTime.length < SCREEN_REC_LIMIT) {
-        tagImg() // tag lastest img onload time.
-      }
-      else {
-        doRecord = false
-      }
-    }
+  }
+  if (item._src_loading) {
+    return
   }
   /**
    * 1. apply src immediately in case javscript blocks the image loading
@@ -59,9 +50,6 @@ export function applySrc (item: any, src: ?string, placeholderSrc: ?string): voi
    * 2. then load the img src with Image constructor (but would not post
    *  a request again), just to trigger the load event.
    */
-  if (item._src_loading) {
-    return
-  }
   item._src_loading = true
   preLoadImg(src, function (evt) {
     item.style.backgroundImage = `url(${src || ''})`
@@ -103,12 +91,6 @@ export function fireLazyload (el: Array<any> | any | null, ignoreVisibility: ?bo
     else if (isElementVisible(img, el)) {
       applySrc(img, img.getAttribute('img-src'), img.getAttribute('img-placeholder'))
     }
-    // In somecases there are images out of the screen in x-axis. There
-    // should not be a break point in these cases.
-    // else {
-    //   // alreay out of view, no need to compare any more.
-    //   break
-    // }
   }
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/a2064a49/html5/render/vue/utils/perf.js
----------------------------------------------------------------------
diff --git a/html5/render/vue/utils/perf.js b/html5/render/vue/utils/perf.js
index 0ae04bd..d08bb54 100644
--- a/html5/render/vue/utils/perf.js
+++ b/html5/render/vue/utils/perf.js
@@ -22,298 +22,19 @@
  * @fileOverview: perf data recorder.
  */
 
-import { debounce, depress, extend } from './func'
-// performance tracker for weex.
 export const perf: {
-  earliestBeforeCreates: Array<number>,
-  latestMounts: Array<number>,
-  earliestBeforeUpdates: Array<number>,
-  latestUpdates: Array<number>,
-  latestRenderFinishes: Array<number>,
-  // createTime: earliest beforeCreate -> latest mounted.
-  createTime: Array<{ start: number, end: number, duration: number }>,
-  // updateTime: earliest beforeUpdate -> latest updated.
-  updateTime: Array<{ start: number, end: number, duration: number }>,
-  // renderTime: earliest beforeCreate/beforeUpdate -> latest img loaded.
-  renderTime: Array<{ start: number, end: number, duration: number }>,
-  entries: Array<{ requestStart: number, responseEnd: number }>,
-  time: {},
-  firstAllMountedTime: ?number,
-  stat: {
-    // info stat.
-    connectionType: string,
-    requestType: string,
-    pageName: string,
-    templateUrl: string,
-    WXSDKVersion: string,
-    bizType: string,
-    JSLibVersion: string,
-
-    // performance stat.
-    screenRenderTime: number,
-    JSTemplateSize: number,
-    componentCount: number,
-    networkTime: number,
-    JSLibInitTime: number,
-    totalTime: number
-  }
+  time: {}
 } = window._weex_perf = {
-  earliestBeforeCreates: [],
-  latestMounts: [],
-  earliestBeforeUpdates: [],
-  latestUpdates: [],
-  latestRenderFinishes: [],
-  createTime: [],
-  updateTime: [],
-  renderTime: [],
-  entries: [],
-  time: {},
-  firstAllMountedTime: null,
-  stat: {
-    // info stat.
-    connectionType: '',
-    requestType: '',
-    pageName: '',
-    templateUrl: '',
-    WXSDKVersion: '',
-    bizType: '',
-    JSLibVersion: '',
-    // performance stat.
-    screenRenderTime: 0,
-    JSTemplateSize: 0,
-    componentCount: 0,
-    networkTime: 0,
-    JSLibInitTime: 0,
-    totalTime: 0
-  }
+  time: {}
 }
 
 const tmp = {}
 
-const IMG_REC_INDENT: number = 500  // record loading events after 500ms towards last recording.
-const REGEXP_IMG_TYPE = /(.png|.jpg|.jpeg|.webp|.gif)$/  // image file type regexp.
-
-let earliestBeforeUpdateTime: number = 0
-let earliestBeforeCreateTime: number = 0
-
-let statCollected = false
-function collectStat (): void {
-  if (statCollected) {
-    return
-  }
-  statCollected = true
-  const version = window.weex.config.env.weexVersion
-  const protocol = location.protocol
-  extend(perf.stat, {
-    connectionType: protocol.substring(0, protocol.length - 1),
-    requestType: 'network',
-    pageName: location.href,
-    WXSDKVersion: version,
-    bizType: 'weex',
-    JSLibVersion: version
-  })
-  const performance = window.performance
-  // get templateUrl && JSTemplateSize
-  const entries = performance && performance.getEntries && performance.getEntries()
-  if (entries) {
-    const params = window.lib.httpurl(location.href).params
-    const bundle = params.page || params._wx_tpl
-    if (bundle) {
-      const len = entries.length
-      let i = 0
-      while (i < len) {
-        const entry = entries[i]
-        if (entry.entryType === 'resource'
-          && entry.name.indexOf(bundle.replace(/^[./]+/, '')) > -1) {
-          const res: any = extend({}, entry)
-          extend(perf.stat, {
-            templateUrl: res.name,
-            JSTemplateSize: (res.transferSize / 1024).toFixed(2),
-            networkTime: parseInt(res.duration)
-          })
-          break
-        }
-        i++
-      }
-    }
-  }
-}
-
-export function collectStatPerf (name: string, val: string | number): void {
-  if (!name) { return }
-  perf.stat[name] = val
-}
-
 function getNow (): number {
   const performance = window.performance
   return performance && performance.now ? performance.now() : new Date().getTime()
 }
 
-function getEntries (): Array<any> {
-  const performance = window.performance
-  return performance && performance.getEntries
-    ? performance.getEntries()
-      .filter(function (entry) {
-        return REGEXP_IMG_TYPE.test(entry.name)
-      })
-    : [{ responseEnd: getNow() - IMG_REC_INDENT }]
-}
-
-function _d (func: Function, wait: number) {
-  let timerId
-  let now
-  function later (now) {
-    timerId = null
-    func(now)
-  }
-  return function () {
-    now = getNow()
-    clearTimeout(timerId)
-    timerId = setTimeout(later.bind(null, now), wait)
-  }
-}
-
-export function tagFirstScreen (time?: number): void {
-  if (!time) {
-    time = getNow()
-  }
-  perf.latestRenderFinishes.push(time)
-  const start = Math.max(earliestBeforeCreateTime, earliestBeforeUpdateTime)
-  perf.renderTime.push({
-    start,
-    end: time,
-    duration: time - start
-  })
-
-  const num = perf.renderTime.length
-  perf[`screenTime${num}`] = time
-
-  if (!window._first_screen_detected) {
-    window._first_screen_detected = true
-    collectStat()
-    extend(perf.stat, {
-      screenRenderTime: parseInt(time),
-      componentCount: window._component_count
-    })
-    window.weex.emit('firstscreenfinish', time)
-  }
-
-  if (process.env.NODE_ENV === 'development') {
-    console.log(`screenTime[${num}]: ${time} ms.`)
-    console.log('_weex_perf:', window._weex_perf)
-  }
-
-  window.weex.emit('renderfinish', time)
-}
-
-/**
- * get first screen time.
- */
-const debouncedTagImg = debounce(function () {
-  const entries = getEntries()
-  const len = entries.length
-  if (!len) {
-    /**
-     * no image loaded. This probably happened because of the disabling of images' loading
-     * events. So just tag now as the first screen time.
-     */
-    return tagFirstScreen()
-  }
-  let i = 0
-  let end = 0
-  while (i < len) {
-    const responseEnd = entries[i].responseEnd
-    end = end < responseEnd ? responseEnd : end
-    perf.entries.push({
-      requestStart: entries[i].requestStart,
-      responseEnd
-    })
-    i++
-  }
-  tagFirstScreen(end)
-}, IMG_REC_INDENT)
-
-export function tagImg (): void {
-  debouncedTagImg()
-}
-
-/**
- * recording the earliest 'beforeCreate' time.
- */
-const depressedTagBeforeCreate = depress(function () {
-  const now = getNow()
-  earliestBeforeCreateTime = now
-  perf.earliestBeforeCreates.push(now)
-}, 25)
-
-export function tagBeforeCreate (): void {
-  depressedTagBeforeCreate()
-}
-
-export function tagRootMounted (): void {
-  const now = getNow()
-  perf.latestMounts.push(now)
-  if (!perf.firstAllMountedTime) {
-    perf.firstAllMountedTime = now
-    if (process.env.NODE_ENV === 'development') {
-      console.log(`first all mounted time: ${now} ms.`)
-    }
-  }
-  collectStatPerf('totalTime', parseInt(now))
-}
-
-/**
- * recording the latest 'mounted' time.
- */
-const debouncedTagMounted = _d(function (now) {
-  perf.latestMounts.push(now)
-  perf.createTime.push({
-    start: earliestBeforeCreateTime,
-    end: now,
-    duration: now - earliestBeforeCreateTime
-  })
-
-  if (!perf.firstAllMountedTime) {
-    perf.firstAllMountedTime = now
-    if (process.env.NODE_ENV === 'development') {
-      console.log(`first all mounted time: ${now} ms.`)
-    }
-  }
-}, 25)
-
-export function tagMounted (): void {
-  debouncedTagMounted()
-}
-
-/**
- * recording the earliest 'beforeUpdate' time.
- */
-const depressedTagBeforeUpdate = depress(function () {
-  const now = getNow()
-  earliestBeforeUpdateTime = now
-  perf.earliestBeforeUpdates.push(now)
-}, 25)
-
-export function tagBeforeUpdate (): void {
-  depressedTagBeforeUpdate()
-}
-
-/**
- * recording the latest 'updated' time.
- */
-const debouncedTagUpdated = _d(function (now) {
-  perf.latestUpdates.push(now)
-  perf.updateTime.push({
-    start: earliestBeforeUpdateTime,
-    end: now,
-    duration: now - earliestBeforeUpdateTime
-  })
-}, 25)
-
-export function tagUpdated (): void {
-  debouncedTagUpdated()
-}
-
 export function tagBegin (name: string): void {
   tmp[name] = getNow()
 }

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/a2064a49/html5/test/render/vue/components/list.js
----------------------------------------------------------------------
diff --git a/html5/test/render/vue/components/list.js b/html5/test/render/vue/components/list.js
index 5174035..6cb3b16 100644
--- a/html5/test/render/vue/components/list.js
+++ b/html5/test/render/vue/components/list.js
@@ -18,7 +18,7 @@
  */
 import { init } from '../helper'
 import list from '../../../../render/vue/components/scrollable/list'
-import cell from '../../../../render/vue/components/scrollable/list/cell'
+import cell from '../../../../render/vue/components/scrollable/cell'
 
 init('<list> component', (Vue, helper) => {
   const { utils, compile } = helper

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/a2064a49/html5/test/render/vue/components/switch.js
----------------------------------------------------------------------
diff --git a/html5/test/render/vue/components/switch.js b/html5/test/render/vue/components/switch.js
index 6413b2d..89e3734 100644
--- a/html5/test/render/vue/components/switch.js
+++ b/html5/test/render/vue/components/switch.js
@@ -64,8 +64,7 @@ init('<switch> component', (Vue, helper) => {
   })
 
   it('toggle <switch>', () => {
-    const vm = new Vue(_switch)
-
+    const vm = compile(`<switch ref="switch"></switch>`).$refs.switch
     expect(vm.isChecked).to.not.be.true
     vm.toggle()
     expect(vm.isChecked).to.be.true
@@ -74,7 +73,7 @@ init('<switch> component', (Vue, helper) => {
   })
 
   it('toggle & disabled <switch>', () => {
-    const vm = new Vue(_switch)
+    const vm = compile(`<switch ref="switch"></switch>`).$refs.switch
     vm.isDisabled = true
 
     expect(vm.isChecked).to.not.be.true

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/a2064a49/html5/test/render/vue/examples/list-cell.js
----------------------------------------------------------------------
diff --git a/html5/test/render/vue/examples/list-cell.js b/html5/test/render/vue/examples/list-cell.js
index d7224dd..01ab8d5 100644
--- a/html5/test/render/vue/examples/list-cell.js
+++ b/html5/test/render/vue/examples/list-cell.js
@@ -18,7 +18,7 @@
  */
 import { init } from '../helper'
 import list from '../../../../render/vue/components/scrollable/list'
-import cell from '../../../../render/vue/components/scrollable/list/cell'
+import cell from '../../../../render/vue/components/scrollable/cell'
 import text from '../../../../render/vue/components/text'
 
 init('list & cell example', (Vue, helper) => {

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/a2064a49/html5/test/render/vue/helper/index.js
----------------------------------------------------------------------
diff --git a/html5/test/render/vue/helper/index.js b/html5/test/render/vue/helper/index.js
index a0952f4..883b70c 100644
--- a/html5/test/render/vue/helper/index.js
+++ b/html5/test/render/vue/helper/index.js
@@ -58,7 +58,7 @@ export function init (title, fn) {
        * @param  {object} component.
        */
       register (name, component) {
-        global.weex.registerComponent(name, component)
+        global.weex.install(component)
       },
 
       /**

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/a2064a49/html5/test/render/vue/helper/main.js
----------------------------------------------------------------------
diff --git a/html5/test/render/vue/helper/main.js b/html5/test/render/vue/helper/main.js
index cff3ec8..ea1d10a 100644
--- a/html5/test/render/vue/helper/main.js
+++ b/html5/test/render/vue/helper/main.js
@@ -12,8 +12,7 @@ const helper = {
    * @param  {object} component.
    */
   register (name, component) {
-    weex.registerComponent(name, component)
-    // components[name] = component
+    weex.install(component)
   },
 
   /**

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/a2064a49/html5/test/render/vue/helper/utils.js
----------------------------------------------------------------------
diff --git a/html5/test/render/vue/helper/utils.js b/html5/test/render/vue/helper/utils.js
index 01eb5ec..88820b3 100644
--- a/html5/test/render/vue/helper/utils.js
+++ b/html5/test/render/vue/helper/utils.js
@@ -32,3 +32,7 @@ export function nodeListToArray (obj) {
   }
   return array
 }
+
+export function isPhantom () {
+  return window.navigator.userAgent.indexOf('PhantomJS') !== -1
+}

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/a2064a49/html5/test/render/vue/utils/lazyload.js
----------------------------------------------------------------------
diff --git a/html5/test/render/vue/utils/lazyload.js b/html5/test/render/vue/utils/lazyload.js
index b390468..b4e8251 100644
--- a/html5/test/render/vue/utils/lazyload.js
+++ b/html5/test/render/vue/utils/lazyload.js
@@ -20,25 +20,14 @@ import {
   fireLazyload,
   getThrottleLazyload
 } from '../../../../render/vue/utils/lazyload'
+import { isPhantom } from '../helper/utils'
+
 describe('utils', function () {
   describe('lazyload', function () {
     const validImageTransparent = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'
     const validImageBlack = 'data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs='
-    const invalidImage = 'data:image/jpeg;base64,'
+    const invalidImage = isPhantom() ? 'data:image/gif;base64,' : 'http://invalid.img'
     before(() => {
-      // for test collectStat in utils/perf.js
-      window.performance = {
-        getEntries: () => {
-          return [{
-            entryType: 'resource',
-            name: 'weex-invalid.jpg'
-          }, {
-            entryType: 'resource',
-            name: 'weex-test.jpg'
-          }]
-        }
-      }
-      window.history.pushState(null, null, '?_wx_tpl=./weex-test.jpg')
       this.weexEmit = sinon.stub(window.weex, 'emit')
     })
     after(() => {
@@ -51,36 +40,30 @@ describe('utils', function () {
       node.setAttribute('img-src', invalidImage)
       node.setAttribute('img-placeholder', validImageBlack)
       node.style.height = '10px'
-        //  coverage branch if (item._src_loading)
+      document.body.appendChild(node)
+      //  coverage branch if (item._src_loading)
       node._src_loading = true
-        //  coverage branch if (Array.isArray(el))
+      //  coverage branch if (Array.isArray(el))
       fireLazyload([node])
       node._src_loading = false
-      fireLazyload(node, true)
+      fireLazyload(node)
       setTimeout(() => {
-        expect(node.style.backgroundImage.replace(urlReg, '')).to.be.equal('url(' + validImageBlack + ')')
-        setTimeout(() => {
-          expect(this.weexEmit.withArgs('renderfinish').callCount).to.be.equal(1)
-          expect(this.weexEmit.withArgs('firstscreenfinish').callCount).to.be.equal(0)
-          done()
-          document.body.removeChild(node)
-        }, IMG_REC_INDENT)
+        expect(node.style.backgroundImage.replace(/"/g, '')
+          .replace(urlReg, '')).to.be.equal('url(' + validImageBlack + ')')
+        done()
+        document.body.removeChild(node)
       }, 100)
     })
     describe('getThrottleLazyload', () => {
-      it('should use default value while parmas is undefined', (done) => {
+      it('should use default value while params is undefined', (done) => {
         const IMG_REC_INDENT = 500
         window._first_screen_detected = true
         getThrottleLazyload()()
         setTimeout(() => {
-          setTimeout(() => {
-            expect(this.weexEmit.withArgs('renderfinish').callCount).to.be.equal(1)
-            expect(this.weexEmit.withArgs('firstscreenfinish').callCount).to.be.equal(0)
-            done()
-          }, IMG_REC_INDENT)
+          done()
         }, 16)
       })
-      it('should be work', (done) => {
+      it('should be working', (done) => {
         const node = document.createElement('figure')
         const urlReg = /http(s)?:\/\/(\S+):(\d+)\//
         const wait = 100
@@ -92,13 +75,10 @@ describe('utils', function () {
         window._first_screen_detected = false
         getThrottleLazyload(wait, node)()
         setTimeout(() => {
-          expect(node.style.backgroundImage.replace(urlReg, '')).to.be.equal('url(' + validImageTransparent + ')')
-          setTimeout(() => {
-            expect(this.weexEmit.withArgs('renderfinish').callCount).to.be.equal(2)
-            expect(this.weexEmit.withArgs('firstscreenfinish').callCount).to.be.equal(1)
-            done()
-            document.body.removeChild(node)
-          }, IMG_REC_INDENT)
+          expect(node.style.backgroundImage.replace(/"/g, '')
+            .replace(urlReg, '')).to.be.equal('url(' + validImageTransparent + ')')
+          done()
+          document.body.removeChild(node)
         }, 100)
       })
     })

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/a2064a49/html5/test/render/vue/utils/perf.js
----------------------------------------------------------------------
diff --git a/html5/test/render/vue/utils/perf.js b/html5/test/render/vue/utils/perf.js
index 602da08..2c4857f 100644
--- a/html5/test/render/vue/utils/perf.js
+++ b/html5/test/render/vue/utils/perf.js
@@ -17,106 +17,24 @@
  * under the License.
  */
 import {
-  collectStatPerf,
-  tagFirstScreen,
-  tagImg,
-  tagBeforeCreate,
-  tagRootMounted,
-  tagMounted,
-  tagBeforeUpdate,
-  tagUpdated,
   tagBegin,
   tagEnd,
   perf
 } from '../../../../render/vue/utils/perf'
 describe('utils', function () {
   describe('pref', function () {
-    before(() => {
-      this.clock = sinon.useFakeTimers()
-    })
-    after(() => {
-      this.clock.restore()
-    })
+    // before(() => {
+    //   this.clock = sinon.useFakeTimers()
+    // })
+    // after(() => {
+    //   this.clock.restore()
+    // })
     beforeEach(() => {
       this.weexEmit = sinon.stub(window.weex, 'emit')
     })
     afterEach(() => {
       this.weexEmit.restore()
     })
-    it('collectStatPerf', () => {
-      window.performance = {
-        getEntries: () => {
-          return [{
-            entryType: 'resource',
-            name: 'weex-invalid.jpg'
-          }, {
-            entryType: 'resource',
-            name: 'weex-test.jpg'
-          }]
-        }
-      }
-      window.history.pushState(null, null, '?_wx_tpl=./weex-test.jpg')
-      const time = (new Date()).getTime()
-      collectStatPerf('totalTime', time)
-      expect(collectStatPerf).to.be.a('function')
-      expect(perf.stat['totalTime']).to.be.equal(time)
-      expect(collectStatPerf()).to.be.a('undefined')
-    })
-    it('tagFirstScreen', () => {
-      expect(tagFirstScreen).to.be.a('function')
-      tagFirstScreen()
-      expect(this.weexEmit.withArgs('renderfinish').callCount).to.be.equal(1)
-      expect(this.weexEmit.withArgs('firstscreenfinish').callCount).to.be.equal(0)
-      window._first_screen_detected = false
-      tagFirstScreen()
-      expect(this.weexEmit.withArgs('renderfinish').callCount).to.be.equal(2)
-      expect(this.weexEmit.withArgs('firstscreenfinish').callCount).to.be.equal(1)
-    })
-    it('tagImg', () => {
-      tagImg()
-      this.clock.tick(500)
-      expect(this.weexEmit.withArgs('renderfinish').callCount).to.be.equal(1)
-      expect(tagImg).to.be.a('function')
-    })
-    it('tagBeforeCreate', () => {
-      tagBeforeCreate()
-      this.clock.tick(25)
-      const time = perf.earliestBeforeCreates[perf.earliestBeforeCreates.length - 1]
-      expect(time).to.be.a('number')
-      expect(perf.earliestBeforeCreates).to.have.lengthOf(1)
-      expect(tagBeforeCreate).to.be.a('function')
-    })
-    it('tagRootMounted', () => {
-      tagRootMounted()
-      const time = perf.latestMounts[perf.latestMounts.length - 1]
-      expect(time).to.be.a('number')
-      expect(perf.stat['totalTime']).to.be.equal(parseInt(time))
-      expect(tagRootMounted).to.be.a('function')
-    })
-    it('tagMounted', () => {
-      perf.firstAllMountedTime = 0
-      tagMounted()
-      this.clock.tick(25)
-      expect(tagMounted).to.be.a('function')
-      expect(perf.latestMounts).to.have.lengthOf(2)
-      expect(perf.createTime).to.have.lengthOf(1)
-      expect(perf.createTime[perf.createTime.length - 1]).to.have.all.keys('start', 'end', 'duration')
-      expect(perf.firstAllMountedTime).to.be.above(0)
-    })
-    it('tagBeforeUpdate', () => {
-      tagBeforeUpdate()
-      this.clock.tick(25)
-      expect(tagBeforeUpdate).to.be.a('function')
-      expect(perf.earliestBeforeUpdates).to.have.lengthOf(1)
-    })
-    it('tagUpdated', () => {
-      tagUpdated()
-      this.clock.tick(25)
-      expect(tagUpdated).to.be.a('function')
-      expect(perf.latestUpdates).to.have.lengthOf(1)
-      expect(perf.updateTime).to.have.lengthOf(1)
-      expect(perf.updateTime[perf.updateTime.length - 1]).to.have.all.keys('start', 'end', 'duration')
-    })
     it('tagBegin', () => {
       const name = 'test'
       tagBegin(name)

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/a2064a49/html5/test/render/vue/utils/style.js
----------------------------------------------------------------------
diff --git a/html5/test/render/vue/utils/style.js b/html5/test/render/vue/utils/style.js
index 2110f23..c073987 100644
--- a/html5/test/render/vue/utils/style.js
+++ b/html5/test/render/vue/utils/style.js
@@ -31,6 +31,11 @@ import {
 import {
   init
 } from '../../../../render/vue/env/viewport'
+
+function trimSpace (str) {
+  return str.replace(/\s/g, '')
+}
+
 describe('style', function () {
   // const rect = document.documentElement.getBoundingClientRect()
   // const info = {}
@@ -108,15 +113,21 @@ describe('transform', () => {
     })
     it('should inherit transform properties from element', () => {
       addTransform(node, style, false)
-      expect(node.style.transform).to.be.equal(style.translate + ' ' + nodeStyle.scale + ' ' + style.rotate + ' ')
-        // webkitTransform will remove last whitespace automatically
-      expect(node.style.webkitTransform).to.be.equal(style.translate + ' ' + nodeStyle.scale + ' ' + style.rotate)
+      expect(trimSpace(node.style.transform)).to.be.equal(
+        trimSpace(style.translate + nodeStyle.scale + style.rotate))
+      // webkitTransform will remove last whitespace automatically
+      expect(trimSpace(node.style.webkitTransform)).to.be.equal(
+        trimSpace(style.translate + nodeStyle.scale + style.rotate)
+      )
     })
     it('should replace all transform properties', () => {
       addTransform(node, style, true)
-      expect(node.style.transform).to.be.equal(style.translate + ' ' + style.rotate + ' ')
-        // webkitTransform will remove last whitespace automatically
-      expect(node.style.webkitTransform).to.be.equal(style.translate + ' ' + style.rotate)
+      debugger;
+      expect(trimSpace(node.style.transform)).to.be.equal(
+        trimSpace(style.translate + style.rotate))
+      // webkitTransform will remove last whitespace automatically
+      expect(trimSpace(node.style.webkitTransform)).to.be.equal(
+        trimSpace(style.translate + style.rotate))
     })
   })
   describe('should add translate X to the element', () => {
@@ -128,8 +139,8 @@ describe('transform', () => {
     let node = null
     beforeEach(() => {
       node = document.createElement('div')
-        // node.style.transform = nodeStyle.translate+' '+nodeStyle.scale+' '+ nodeStyle.rotate
-        // node.style.webkitTransform = nodeStyle.translate+' '+nodeStyle.scale+' '+ nodeStyle.rotate
+      // node.style.transform = nodeStyle.translate+' '+nodeStyle.scale+' '+ nodeStyle.rotate
+      // node.style.webkitTransform = nodeStyle.translate+' '+nodeStyle.scale+' '+ nodeStyle.rotate
     })
     it('should element has translate property', () => {
       const toAdd = 2
@@ -137,14 +148,20 @@ describe('transform', () => {
       const translateReplaceFunction = ($0) => {
         return (parseFloat($0) + toAdd) + 'px'
       }
-      const removeSpaceReg = /(\s?)/g
       node.style.transform = nodeStyle.translate + ' ' + nodeStyle.scale + ' ' + nodeStyle.rotate
       node.style.webkitTransform = nodeStyle.translate + ' ' + nodeStyle.scale + ' ' + nodeStyle.rotate
       addTranslateX(node, toAdd)
+      debugger;
       // webkitTransform will reserved whitespace between translate value but transform will not.
-      expect(node.style.transform).to.be.equal(nodeStyle.translate.replace(translateReg, translateReplaceFunction).replace(removeSpaceReg, '') + ' ' + nodeStyle.scale + ' ' + nodeStyle.rotate + ' ')
+      expect(trimSpace(node.style.transform)).to.be.equal(
+        trimSpace(nodeStyle.translate.replace(translateReg, translateReplaceFunction)
+        + nodeStyle.scale
+        + nodeStyle.rotate))
       // webkitTransform will remove last whitespace automatically
-      expect(node.style.webkitTransform).to.be.equal(nodeStyle.translate.replace(translateReg, translateReplaceFunction) + ' ' + nodeStyle.scale + ' ' + nodeStyle.rotate)
+      expect(trimSpace(node.style.webkitTransform)).to.be.equal(
+        trimSpace(nodeStyle.translate.replace(translateReg, translateReplaceFunction)
+        + nodeStyle.scale
+        + nodeStyle.rotate))
     })
     it('should element does not have translate property', () => {
       const toAdd = 2
@@ -157,17 +174,22 @@ describe('transform', () => {
       node.style.webkitTransform = nodeStyle.scale + ' ' + nodeStyle.rotate
       addTranslateX(node, toAdd)
       // transform will reserved whitespace when translate on the last position.
-      expect(node.style.transform).to.be.equal(nodeStyle.scale + ' ' + nodeStyle.rotate + ' ' + defaultTranslate.replace(translateReg, translateReplaceFunction) + ' ')
+      expect(trimSpace(node.style.transform)).to.be.equal(
+        trimSpace(nodeStyle.scale + nodeStyle.rotate + defaultTranslate.replace(translateReg, translateReplaceFunction)))
       // webkitTransform will remove last whitespace automatically
-      expect(node.style.webkitTransform).to.be.equal(nodeStyle.scale + ' ' + nodeStyle.rotate + ' ' + defaultTranslate.replace(translateReg, translateReplaceFunction))
+      expect(trimSpace(node.style.webkitTransform)).to.be.equal(
+        trimSpace(nodeStyle.scale + nodeStyle.rotate + defaultTranslate.replace(translateReg, translateReplaceFunction)))
     })
     it('should elemet remain', () => {
       const toAdd = 0
       node.style.transform = nodeStyle.scale + ' ' + nodeStyle.rotate
       node.style.webkitTransform = nodeStyle.scale + ' ' + nodeStyle.rotate
       addTranslateX(node, toAdd)
-      expect(node.style.transform).to.be.equal(nodeStyle.scale + ' ' + nodeStyle.rotate)
-      expect(node.style.webkitTransform).to.be.equal(nodeStyle.scale + ' ' + nodeStyle.rotate)
+      expect(trimSpace(node.style.transform)).to.be.equal(
+        trimSpace(nodeStyle.scale + nodeStyle.rotate))
+      expect(trimSpace(node.style.webkitTransform)).to.be.equal(
+        trimSpace(nodeStyle.scale + nodeStyle.rotate)
+      )
     })
   })
 })

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/a2064a49/package.json
----------------------------------------------------------------------
diff --git a/package.json b/package.json
index fe8a269..ce7cc0f 100644
--- a/package.json
+++ b/package.json
@@ -44,7 +44,8 @@
     "build:source": "npm run build:native && npm run build:browser && node build/build.js vue",
     "build:browser": "wwp && node build/build.js browser",
     "build:browser:common": "rollup -c build/rollup.browser.common.config.js",
-    "build:vue": "flow check && node build/build.js vue && npm run build:vue:core && npm run build:vue:plugins",
+    "build:vue": "npm run build:vue:full && npm run build:vue:core && npm run build:vue:plugins",
+    "build:vue:full": "flow check && node build/build.js vue",
     "build:vue:core": "node build/build.js vue-core",
     "build:vue:plugins": "node build/build.js vue-plugins",
     "build:vue:examples": "node build/build.js web-examples",

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/a2064a49/packages/weex-vue-render/README.md
----------------------------------------------------------------------
diff --git a/packages/weex-vue-render/README.md b/packages/weex-vue-render/README.md
index 07286be..f9ac2de 100644
--- a/packages/weex-vue-render/README.md
+++ b/packages/weex-vue-render/README.md
@@ -84,7 +84,7 @@ These components have already integrated into render-core. You don't have to imp
 | weex-vue-geolocation | geolocation |
 | weex-vue-global-event | globalEvent |
 | weex-vue-modal | modal |
-| weex-vue-navigator | navigator |
+| weex-vue-nav | navigator |
 | weex-vue-storage | storage |
 | weex-vue-stream | stream |
 | weex-vue-websocket | websocket |
@@ -94,6 +94,14 @@ Some of the above plugins may not be mentioned in weex documents. Just ignore th
 
 You can develop more plugins for your app. Accordingly the same plugin for other two platforms (iOS and Android) should also be built and intergrated in your app if you want it run on all three platforms.
 
+#### scan your code
+
+Use `weex-vue-bundle-util` to scan you code, which will return a promise with a object to tell which components and modules you have used in your project, so that can generate a entry file accordingly to import those plugins.
+
+https://github.com/weexteam/weex-vue-bundle-util
+
+You can see the examples of weex built in this way by running the script `npm run build:vue:examples`, and use the `<script src="./dist/render.vue.js"></script>` as the render in the `vue.html` file.
+
 ## use vue-loader to bundle .vue file
 
 NOTE: you should inject `$processStyle` to preprocess vnode's style in vue-loader's postTransformNode hook.