XiaoShang Replay

2017-11-27  本文已影响0人  老人贤

  1. 新增加的组件
  1. 新使用的第三方组件
  1. 一些坑

4.思考

5.其他


1. 新增加的组件

表单元素和Vuex

通过vuex同步不同表单元素之间的值,即使表单元素在不同页面之中

// store.js
const state = {
  val: 'Hello World!'
}

const mutations = {
  changeMsg (state, msg) {
    state.val = msg
  }
}

export default new Vuex.Store({
  state,
  mutations
})
// 组件内通过computed属性读取/修改Vuex中的变量
  export default {
    name: 'Input1',
    data () {
      return {}
    },
    computed: {
      message: {
        get () {
          return this.$store.state.val
        },
        set (value) {
          this.$store.commit('changeMsg', value)
        }
      }
    }
  }
input1

)

Input2

修改Input1的值,在不同页面的Input2的值页也被修改了

晓商中搜索的条件筛选组件使用了相同的原理


晓商-条件筛选 晓商-搜索结果页

c-accordion 手风琴菜单

晓商-我的关注

为了避免浏览器的reflow/layout, 菜单的折叠/展开的过渡效果没有使用transiton: max-height(PS: height: auto & transition: height 是不会产生动画效果的),而是通过transform实现。

为什么?

what is reflow

what is reflow

what forces layout/reflow

transition: max-height 真的会导致reflow/layout 吗

  .accordion-item-content {
    max-height: 240px;
    transition: max-height .3s;
  }
每一帧都有layout过程

通过transform 实现

每一帧都没有layout过程

How

vue中transition-group的也使用了FLIP原理

accordion-menu 折叠时的动画原理

2. 新使用的第三方组件

portal-vue

PortalVue is a set of two components that allow you to render a component's template (or a part of it) anywhere in the document - even outside of your the part that is controlled by your Vue App!

DEMO: http://runjs.cn/detail/gmg2uql3

why portal-vue

vue-virtual-scroller

问题:随着列表的向下滚动,会加载更多的数据,同时生产更多的DOM节点。

为了防止页面中的DOM节点无限制地增长,使用了vue-virtual-scroller。该组件会随着滚动条的位置,自动删除离开视窗的DOM节点,插入新的进入视窗的DOM节点。

滚动位置变化了,DOM节点的数目几乎不变

preload-webpack-plugin

问题:使用路由级别的异步加载,页面跳转时,会停顿一下,等页面顶部的下条条消失才会发生跳转。

A Webpack plugin for automatically wiring up asynchronous (and other types) of JavaScript chunks using <link rel='preload'>. This helps with lazy-loading.

what is preload good for?
what is preload good for? -- 中文翻译

Prefetch

<link rel=“prefetch”>但Preload与这两者不同,<link rel=“prefetch”>的作用是告诉浏览器加载下一页面可能会用到的资源,注意,是下一页面,而不是当前页面。因此该方法的加载优先级非常低(自然,相比当前页面所需的资源,未来可能会用到的资源就没那么重要了),也就是说该方式的作用是加速下一个页面的加载速度

资源加载的优先级可以通过DevTool查看

Preload

  • 资源的提前加载
    preload 一个基本的用法是提前加载资源,尽管大多数基于标记语言的资源能被浏览器的预加载器(Preloader)尽早发现,但不是所有的资源都是基于标记语言的,比如一些隐藏在 CSS 和 Javascript 中的资源。当浏览器发现自己需要这些资源时已经为时已晚,所以大多数情况,这些资源的加载都会对页面渲染造成延迟。
    现在,有了 preload,你可以通过一段类似下面的代码对浏览器说,”嗨,浏览器!这个资源你后面会用到,现在就加载它吧。“
    <link rel="preload" href="late_discovered_thing.js" as="script">
  • 对字体的提前加载
    <link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin>
  • 动态加载,但不执行
    难道我们不是已经有了<script async>? <scirpt async>虽好,但却会阻塞 window 的 onload 事件。某些情况下,你可能希望这样,但总有一些情况你不希望阻塞 window 的 onload 。
  • 响应式加载
    通过 Preload,我们可以提前加载资源,利用 media 属性,浏览器只会加载需要的资源。
    <link rel="preload" as="image" href="map.png" media="(max-width: 600px)">
    <link rel="preload" as="script" href="map.js" media="(min-width: 601px)">

# 带你玩转prefetch, preload, dns-prefetch,defer和async

prefetch支持情况
preload支持情况 使用preload-webpack-plugin后的效果

html-critical-webpack-plugin

解决的问题: 加快首屏渲染速度


使用了html-critical-webpack-plugin后,首屏渲染时间发生在657.04ms
没有使用html-critical-webpack-plugin,首屏渲染时间发生在1.32s

原理:利用headless browser,检测出首屏渲染的css,然后将这部分css插入到index.html文件中

缺点:critical css因为在index.html中,增大了index.html文件的体积,同时失去了被缓存的可能

扩展阅读:understanding-critical-css

一些坑

export const wxConfig = () => {
  if (!isWXEnv()) { return; }
  Vue.http.get('/wechat/signature', {
    params: {
      // url: window.encodeURIComponent(window.location.href)
      url: window.encodeURIComponent(window.location.href.split('#')[0])
    }
  }).then(response => {
    const result = response.body;
    // 配置信息
    debugFlag && alert('wxConfig called');
    window._wx.config({
      debug: isDevEnv(),
      appId: result.data.appId,
      timestamp: result.data.timestamp,
      nonceStr: result.data.nonceStr,
      signature: result.data.signature,
      jsApiList: [
        'onMenuShareTimeline',
        'onMenuShareAppMessage',
        'hideMenuItems',
        'showMenuItems',
        'showAllNonBaseMenuItem'
      ]
    });
  }, e => { alert(`WX权限验证配置注入失败--${JSON.stringify(e)}`); });
};

一些思考

code split的粒度

js文件加载情况

不要使用匿名函数 anonymous function(for debugging)

anonymous function
(() => {
      throw new Error('can we get arrow name ?');
})();
named function
const testArrowErrorTrack = () => {
  throw new Error('can we get arrow name ?');
};
上一篇下一篇

猜你喜欢

热点阅读