2020年12月02日
  • 小程序加载速度慢 怎么办?

    setData setData 是小程序开发中使用最频繁的接口,也是最容易引发性能问题的接口。在介绍常见的错误用法前,先简单介绍一下 setData 背后的工作原理。 工作原理 小程序的视图层目前使用 WebView 作为渲染载体,而逻辑层是由独立的 JavascriptCore 作为运行环境。在架构上,WebView 和 JavascriptCore 都是独立的模块,并不具备数据直接共享的通道。当前,视图层和逻辑层的数据传输,实际上通过两边提供的 evaluateJavascript 所实现。即用户传输的数据,需要将其转换为字符串形式传递,同时把转换后的数据内容拼接成一份 JS 脚本,再通过执行 JS 脚本的形式传递到两边独立环境。 而 evaluateJavascript 的执行会受很多方面的影响,数据到达视图层并不是实时的。 常见的 setData 操作错误 1. 频繁的去 setData 在我们分析过的一些案例里,部分小程序会非常频繁(毫秒级)的去setData,其导致了两个后果: Android 下用户在滑动时会感觉到卡顿,操作反馈延迟严重,因为 JS 线程一直在编译执行渲染,未能及时将用户操作事件传递到逻辑层,逻辑层亦无法及时将操作处理结果及时传递到视图层; 渲染有出现延时,由于 WebView 的 JS 线程一直处于忙碌状态,逻辑层到页面层的通信耗时上升,视图层收到的数据消息时距离发出时间已经过去了几百毫秒,渲染的结果并不实时; 2. 每次 setData 都传递大量新数据 由setData的底层实现可知,我们的数据传输实际是一次 evaluateJavascript 脚本过程,当数据量过大时会增加脚本的编译执行时间,占用 WebView JS 线程, 3. 后台态页面进行 setData 当页面进入后台态(用户不可见),不应该继续去进行setData,后台态页面的渲染用户是无法感受的,另外后台态页面去setData也会抢占前台页面的执行。 图片资源 目前图片资源的主要性能问题在于大图片和长列表图片上,这两种情况都有可能导致 iOS 客户端内存占用上升,从而触发系统回收小程序页面。 图片对内存的影响 在 iOS 上,小程序的页面是由多个 WKWebView 组成的,在系统内存紧张时,会回收掉一部分 WKWebView。从过去我们分析的案例来看,大图片和长列表图片的使用会引起 WKWebView 的回收。 图片对页面切换的影响 除了内存问题外,大图片也会造成页面切换的卡顿。我们分析过的案例中,有一部分小程序会在页面中引用大图片,在页面后退切换中会出现掉帧卡顿的情况。 当前我们建议开发者尽量减少使用大图片资源。

    支持{{list !== '' ? list['10']['0']['vote']['up'] : '0'}}

    {{list !== '' ? list['10']['0']['vote']['down'] : '0'}}

    分享到微博微信QQ好友
  • Vue面试题总结

    说说你对 SPA 单页面的理解,它的优缺点分别是什么? SPA( single-page application )仅在 Web 页面初始化时加载相应的 HTML、JavaScript 和 CSS。一旦页面加载完成,SPA 不会因为用户的操作而进行页面的重新加载或跳转;取而代之的是利用路由机制实现 HTML 内容的变换,UI 与用户的交互,避免页面的重新加载。 优点: 用户体验好、快,内容的改变不需要重新加载整个页面,避免了不必要的跳转和重复渲染; 基于上面一点,SPA 相对对服务器压力小; 前后端职责分离,架构清晰,前端进行交互逻辑,后端负责数据处理; 缺点: 初次加载耗时多:为实现单页 Web 应用功能及显示效果,需要在加载页面的时候将 JavaScript、CSS 统一加载,部分页面按需加载; 前进后退路由管理:由于单页应用在一个页面中显示所有的内容,所以不能使用浏览器的前进后退功能,所有的页面切换需要自己建立堆栈管理; SEO 难度较大:由于所有的内容都在一个页面中动态替换显示,所以在 SEO 上其有着天然的弱势。 computed 和 watch 的区别和运用的场景 computed: 是计算属性,依赖其它属性值,并且 computed 的值有缓存,只有它依赖的属性值发生改变,下一次获取 computed 的值时才会重新计算 computed 的值; watch:更多的是「观察」的作用,类似于某些数据的监听回调 ,每当监听的数据变化时都会执行回调进行后续操作; 运用场景: 当我们需要进行数值计算,并且依赖于其它数据时,应该使用 computed,因为可以利用 computed 的缓存特性,避免每次获取值时,都要重新计算; 当我们需要在数据变化时执行异步或开销较大的操作时,应该使用 watch,使用 watch 选项允许我们执行异步操作 ( 访问一个 API ),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的。 谈谈对生命周期的理解 beforeCreate阶段:vue实例的挂载元素el和数据对象data都是undefined,还没有初始化。 created阶段:vue实例的数据对象data有了,可以访问里面的数据和方法,未挂载到DOM,el还没有 beforeMount阶段:vue实例的el和data都初始化了,但是挂载之前为虚拟的dom节点 mounted阶段:vue实例挂载到真实DOM上,就可以通过DOM获取DOM节点 beforeUpdate阶段:响应式数据更新时调用,发生在虚拟DOM打补丁之前,适合在更新之前访问现有的DOM,比如手动移除已添加的事件监听器 updated阶段:虚拟DOM重新渲染和打补丁之后调用,组成新的DOM已经更新,避免在这个钩子函数中操作数据,防止死循环 beforeDestroy阶段:实例销毁前调用,实例还可以用,this能获取到实例,常用于销毁定时器,解绑事件 destroyed阶段:实例销毁后调用,调用后所有事件监听器会被移除,所有的子实例都会被销毁 生命周期图示 在哪个生命周期内调用异步请求? 可以在钩子函数 created、beforeMount、mounted 中进行调用,因为在这三个钩子函数中,data 已经创建,可以将服务端端返回的数据进行赋值。 推荐在 created 钩子函数中调用异步请求,因为在 created 钩子函数中调用异步请求有以下优点: 能更快获取到服务端数据,减少页面 loading 时间; ssr 不支持 beforeMount 、mounted 钩子函数,所以放在 created 中有助于一致性; 在什么阶段才能访问操作DOM? 在钩子函数 mounted 被调用前,Vue 已经将编译好的模板挂载到页面上,所以在 mounted 中可以访问操作 DOM 父组件可以监听到子组件的生命周期吗? 可以通过@hook来监听生命周期事件,用法如下: // Parent.vue <Child @hook:mounted="doSomething" ></Child> doSomething() { console.log('父组件监听到 mounted 钩子函数 ...'); }, // Child.vue mounted(){ console.log('子组件触发 mounted 钩子函数 ...'); }, // 以上输出顺序为: // 子组件触发 mounted 钩子函数 ... // 父组件监听到 mounted 钩子函数 ... 谈谈你对 keep-alive 的了解? keep-alive 是 Vue 内置的一个组件,可以使被包含的组件保留状态,避免重新渲染 ,其有以下特性: 一般结合路由和动态组件一起使用,用于缓存组件 提供 include 和 exclude 属性,两者都支持字符串或正则表达式, include 表示只有名称匹配的组件会被缓存,exclude 表示任何名称匹配的组件都不会被缓存 ,其中 exclude 的优先级比 include 高; 对应两个钩子函数 activated 和 deactivated ,当组件被激活时,触发钩子函数 activated,当组件被移除时,触发钩子函数 deactivated。 组件中 data 为什么是一个函数? 因为组件是用来复用的,且 JS 里对象是引用关系,如果组件中 data 是一个对象,那么这样作用域没有隔离,子组件中的 data 属性值会相互影响,如果组件中 data 选项是一个函数,那么每个实例可以维护一份被返回对象的独立的拷贝,组件实例之间的 data 属性值不会互相影响;而 new Vue 的实例,是不会被复用的,因此不存在引用对象的问题。 vue-router 路由模式有几种? vue-router 有 3 种路由模式:hash、history、abstract,对应的源码如下所示: switch (mode) { case 'history': this.history = new HTML5History(this, options.base) break case 'hash': this.history = new HashHistory(this, options.base, this.fallback) break case 'abstract': this.history = new AbstractHistory(this, options.base) break default: if (process.env.NODE_ENV !== 'production') { assert(false, `invalid mode: ${mode}`) } } hash: 使用 URL hash 值来作路由。支持所有浏览器,包括不支持 HTML5 History Api 的浏览器; history : 依赖 HTML5 History API 和服务器配置。具体可以查看 HTML5 History 模式; abstract : 支持所有 JavaScript 运行环境,如 Node.js 服务器端。如果发现没有浏览器的 API,路由会自动强制进入这个模式. vuex有哪几种状态和属性 state中保存着共有数据,数据是响应式的 getter可以对state进行计算操作,主要用来过滤一些数据,可以在多组件之间复用 mutations定义的方法动态修改state中的数据,通过commit提交方法,方法必须是同步的 actions将mutations里面处理数据的方法变成异步的,就是异步操作数据,通store.dispatch来分发actions,把异步的方法写在actions中,通过commit提交mutations,进行修改数据。 modules:模块化vuex vue修饰符 stop:阻止事件的冒泡 prevent:阻止事件的默认行为 once:只触发一次 self:只触发自己的事件行为时,才会执行 Vue实现数据双向绑定的原理:Object.defineProperty() vue实现数据双向绑定主要是:采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应监听回调。当把一个普通 Javascript 对象传给 Vue 实例来作为它的 data 选项时,Vue 将遍历它的属性,用 Object.defineProperty 将它们转为 getter/setter。用户看不到 getter/setter,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。 vue的数据双向绑定 将MVVM作为数据绑定的入口,整合Observer,Compile和Watcher三者,通过Observer来监听自己的model的数据变化,通过Compile来解析编译模板指令(vue中是用来解析 {{}}),最终利用watcher搭起observer和Compile之间的通信桥梁,达到数据变化 —>视图更新;视图交互变化(input)—>数据model变更双向绑定效果。 说说对v-model的了解? 我们在 vue 项目中主要使用 v-model 指令在表单 input、textarea、select 等元素上创建双向数据绑定,我们知道 v-model 本质上不过是语法糖,v-model 在内部为不同的输入元素使用不同的属性并抛出不同的事件: text 和 textarea 元素使用 value 属性和 input 事件; checkbox 和 radio 使用 checked 属性和 change 事件; select 字段将 value 作为 prop 并将 change 作为事件。 以 input 表单元素为例: <input v-model='something'> 相当于 <input v-bind:value="something" v-on:input="something = $event.target.value"> 如果在自定义组件中,v-model 默认会利用名为 value 的 prop 和名为 input 的事件,如下所示: 父组件: <Child v-model="message"></Child> 子组件 <div>{{value}}</div> props:{ value: String }, methods: { test1(){ this.$emit('input', '小红') }, } Vue 项目优化 1.代码层面的优化 v-if 和 v-show 区分使用场景 computed 和 watch 区分使用场景 v-for 遍历必须为 item 添加 key,且避免同时使用 v-if 长列表性能优化 事件的销毁 图片资源懒加载 路由懒加载 第三方插件的按需引入 优化无限列表性能 服务端渲染 SSR or 预渲染 2.Webpack 层面的优化 Webpack 对图片进行压缩 减少 ES6 转为 ES5 的冗余代码 提取公共代码 模板预编译 提取组件的 CSS 优化 SourceMap 构建结果输出分析 Vue 项目的编译优化 3.基础的 Web 技术的优化 开启 gzip 压缩 浏览器缓存 CDN 的使用 使用 Chrome Performance 查找性能瓶颈

    支持{{list !== '' ? list['10']['1']['vote']['up'] : '0'}}

    {{list !== '' ? list['10']['1']['vote']['down'] : '0'}}

    分享到微博微信QQ好友
  • 2020前端技术栈

    一、HTML、CSS基础、JavaScript语法基础。 二、JavaScript语法进阶。包括:作用域和闭包、this和对象原型等。 三、ES6语法。这部分属于JS新增的语法, promise、async 等内容要尤其关注。 四、HTML5和CSS3。要熟悉其中的新特性。 五、canvas。加分项。 六、移动Web开发、Bootstrap等。要注意移动开发中的适配和兼容性问题。 七、前端框架:Vue.js和React。这两个框架至少要会一个。入门时,建议先学Vue.js,上手相对容易。但无论如何,同时掌握 Vue 和 React 才是合格的前端同学。 八、Node.js。属于加分项。 九、自动化工具:构建工具 Webpack、构建工具 gulp、CSS 预处理器 Sass 等。注意,Sass 比 Less 用得多,gulp 比 grunt 用得多。 十、前端综合:HTTP协议、跨域通信、安全问题(CSRF、XSS)、浏览器渲染机制、异步和单线程、页面性能优化、防抖动(Debouncing)和节流阀(Throtting)、lazyload、前端错误监控、虚拟DOM等。 十一、编辑器相关。Sublime Text 是每个学前端的人都要用到的编辑器。另外,前端常见的IDE有两个:WebStorm 和 Visual Studio Code。WebStorm 什么都好,可就是太卡顿;VS Code就相对轻量很多。 十二、TypeScript(简称TS)。ES 是 JS 的标准,TS 是 JS 的超集。TS属于进阶内容,建议把上面的基础掌握之后,再学TS。

    支持{{list !== '' ? list['10']['2']['vote']['up'] : '0'}}

    {{list !== '' ? list['10']['2']['vote']['down'] : '0'}}

    分享到微博微信QQ好友
2020年09月11日
  • 外交部回应TikTok美业务出售问题:美方无异于巧取豪夺

    9月11日,外交部发言人赵立坚主持例行记者会。有记者提问,美国总统特朗普表示,不会延长字节跳动在下星期二前出售TikTok的美国业务的期限。他强调说,出于安全原因,必须关闭TikTok在美国的业务或者出售该业务。请问中方有何回应? 赵立坚表示,关于TikTok的问题我要再次强调,中方反对美方泛化国家安全概念,滥用国家力量,无理打压别国特定企业。美方企图对非美国企业采取经济霸凌和政治操弄的伎俩,是典型的政府胁迫交易和政府强制交易,无异于巧取豪夺。这不仅违反了市场原则和国际规则,也是对美方一贯标榜的市场经济和公平竞争原则的否定。 赵立坚强调,美方应立即纠正错误,停止无理打压包括中国企业在内的别国企业。中方将保留采取必要措施,维护中方企业权益的权利。

    支持{{list !== '' ? list['11']['0']['vote']['up'] : '0'}}

    {{list !== '' ? list['11']['0']['vote']['down'] : '0'}}

    分享到微博微信QQ好友
  • 小黄车自动续费竟仍正常运作

    街头早已见不到ofo小黄车的身影。可就在几天前,周女士的微信账户突然被扣了52元钱,莫名其妙的她查来查去,发现竟然是ofo季卡在自动续费。这款扣得让周女士哭笑不得。 周女士说,其实早在今年的3月份和6月份,她都收到过ofo季卡续费的短信通知。因为当时微信账户里没有余额,所以自动扣款并未成功。而周女士以为,ofo既然已经不运营了,这个短信也就没必要理会了。让她没想到的是,因为最近微信账户里恰好有一笔转账来的钱,9月4日那天ofo季卡自动扣款竟然成功了。当扣款通知发到她手机上时,周女士完全懵了。

    支持{{list !== '' ? list['11']['1']['vote']['up'] : '0'}}

    {{list !== '' ? list['11']['1']['vote']['down'] : '0'}}

    分享到微博微信QQ好友
  • 华为搜索正式转战国内搜索市场

    继3月份在国外内测上线推出HUAWEISearch业务后,近日华为搜索正式转战国内搜索市场。正式在国内上线HUAWEI Research搜索引擎,看来是准备回头争夺移动端搜索市场份额了。

    支持{{list !== '' ? list['11']['2']['vote']['up'] : '0'}}

    {{list !== '' ? list['11']['2']['vote']['down'] : '0'}}

    分享到微博微信QQ好友
2020年09月03日
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索