详解移动端开发页面

Posted by Liangyuqi on November 5, 2017
view times

一、Web App vs. Native App

之前公司移动端项目都是web app,绑定在微信公众号上,又学习了阮一峰老师和hcysun几篇博文,仔细总结一下开发web app的心得

web app 优点

  • 跨平台:所有系统都能运行
  • 免安装:打开浏览器,就能使用
  • 快速部署:升级只需在服务器更新代码
  • 超链接:可以与其他网站互连,可以被搜索引擎检索

web app 缺点

  • 体验差。手机App的操作流畅性,远超网站。
  • 业界不支持。所有公司的移动端开发重点,几乎都是原生app。
  • 用户不在乎。大多数用户都选择使用手机app,而不是网站。

原因:

(1)Web基于DOM,而DOM很慢。浏览器打开网页时,需要解析文档,在内存中生成DOM结构,如果遇到复杂的文档,这个过程是很慢的。可以想象一下,如果网页上有上万个、甚至几十万个形状(不管是图片或CSS),生成DOM需要多久?更不要提与其中某一个形状互动了。

(2)DOM拖慢JavaScript。所有的DOM操作都是同步的,会堵塞浏览器。JavaScript操作DOM时,必须等前一个操作结束,才能执行后一个操作。只要一个操作有卡顿,整个网页就会短暂失去响应。浏览器重绘网页的频率是60FPS(即16毫秒/帧),JavaScript做不到在16毫秒内完成DOM操作,因此产生了跳帧。用户体验上的不流畅、不连贯就源于此。

(3)网页是单线程的。现在的浏览器对于每个网页,只用一个线程处理。所有工作都在这一个线程上完成,包括布局、渲染、JavaScript执行、图像解码等等,怎么可能不慢?

(4)网页没有硬件加速。网页都是由CPU处理的,没用GPU进行图形加速。 上面这些原因,对于PC还不至于造成严重的性能问题,但是手机的硬件资源相对有限,用户互动又相对频繁,结果跟Native app一比,就完全落在了下风。

web app未来的路

(1)多线程浏览器。每个网页应该由多个线程进行处理,主线程只负责布局和渲染,而且应该在16毫秒内完成,JavaScript由worker线程执行,这样就不会发生堵塞了。Mozilla正在开发的Servo就是这样一个项目。

(2)DOM的异步操作。JavaScript对DOM的操作不再是同步的,而是触发后,交给Event Loop机制进行监听。

(3)非DOM方案。浏览器不再将网页处理成DOM结构,而是变为其他结构。React的Virtual DOM方案就是这一类的尝试,还有更激进的方案,比如用数据库取代DOM。

二、移动端开发注意事项

1、设备像素:设备屏幕的物理像素,对于任何设备来讲物理像素的数量是固定的。

2、CSS像素:这是一个抽象的像素概念,它是为web开发者创造的。

比如给一个元素设置100px,它的css像素则会是100px,跨越多少设备像素则和手机屏幕的特性以及用户缩放有关

1.苹果是retina视网膜屏,

设备像素比(DPR) = 设备像素个数 / 设备理想视口宽(device-width)

ppi:像素密度,也就是每英寸像素取值.计算公式

DPR = PPI/160

css像素100px的元素实际上跨越了200px的设备像素

2.用户缩小页面时,css像素100px的元素只会占用50px的设备像素

viewport(视口)

viewport其实可以理解为html的父元素,也叫初始包含块,pc 端viewport的宽度正好等于浏览器窗口的宽度,用户可以手动拖动窗口改变宽的大小。

layout viewport(布局视口)

移动端CSS布局的依据视口,即CSS布局会根据布局视口来计算

ios 980px,android 800px

visual viewport(视觉视口)

可以看成和手机屏幕等大的一个框,在layout viewport不变的情况,我们能看到多少css像素的东西,取决于这个框的缩放程度。默认情况下。大多数移动端浏览器会将visual viewport这个框缩放到与layout viewport相同

这样就能看到全部的内容,用户自然会放大页面,但是遇到较长的文字段落需要将屏幕左右滑动才能阅读完全。 在没有viewport meta标签之前可以这样优化。

<meta name="viewport" content="width=375" user-scalable=no>

但是只针对375的iphone6,所以引入了新方法。

ideal viewport(理想视口)

理想视口的尺寸因设备和浏览器的不同而不同,每一种机型所对应的屏幕尺寸。

如iphone6:375px(device-width) 安卓:360px

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

1、width=device-width:手动设置layout viewport的宽=设备理想视口宽

2、init-scale:设置页面的初始缩放程度

3、minimum-scale:设置了页面最小缩放程度

4、maximum-scale:设置了页面最大缩放程度

5、user-scalable:是否允许用户对页面进行缩放操作

媒体查询

媒体查询是响应式设计的基础,缺点是范围性不够精确

@media 媒体类型 and (视口特性阀值){
    // 满足条件的css样式代码

}

下面是一段在css中使用媒体查询的示例:

@media all and (min-width: 100px) and (max-width: 200px){
    .demo{
        background: red;
    }
}

上面代码中,媒体类型为all(screen和tv),代表任何设备,并且设备的布局视口宽度大于等于100px且小于等于200px时,让demo类的素背景变红。

开发中解决psd图片的问题

1.psd原稿的尺寸是按照设备像素设计的,如果基于iphone6设计,则设计稿的尺寸就是iPhone6的设备像素的尺寸750px,iPhone6的理想视口尺寸为375px,所以尺寸应该除以2

但是有时候比如尺寸为101px ,除以2计算为50.5px,但是计算机无法显示不到一个像素的值,则会显示为51px,怎么样完美解决呢

<meta name="viewport" content="width=device-width,initial-scale=0.5,maximum-scale=0.5,user-scalable=no" />

但是dpr不是2的设备就不行了,于是要js动态设定缩放比例

var scale = 1 / window.devicePixelRatio;
document.querySelector('meta[name="viewport"]').setAttribute('content','width=device-width,initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');

2.元素跟着设备变化而等比缩放怎么达成呢?

rem是基于html标签的font-size,设计稿宽度除以10,作为根元素字体大小, 之后量出其他元素宽度,转换为rem就可以了。文字字体大小还是设置媒体查询用px。这就是手机淘宝的实现方法

 document.documentElement.style.fontSize = document.documentElement.clientWidth / 10 + 'px';

如果是iphone6 psd 改良为这样更好计算rem,fontsize设为100px,除起来方便

document.documentElement.style.fontSize = document.documentElement.clientWidth / 7.5 + 'px';

文字字体大小是不要换算成rem做单位的,而是使用媒体查询来进行动态设置

@media screen and (max-width: 321px) {
body {
font-size:16px
}
}

@media screen and (min-width: 321px) and (max-width:400px) {
body {
font-size:17px
}
}

@media screen and (min-width: 400px) {
body {
font-size:19px
}
}

解决响应式图片方法汇总

1:准备两张图片,根据媒体查询的devicePixelRatio,retina屏使用高精度图片

在devicePixelRatio<=2时,图片统一使用750设计稿的切图,@2x

在devicePixelRatio>2时,图片统一使用1125设计稿的切图,@3x

2.图片的宽度设置为100%,然后把高度设置为auto

3.将图片当做背景来使用,然后在背景图片中添加一个background-size: contain;属性

4.CSS的媒体查询

5.HTML5中还提供了picture元素,添加source标签用来显示你所要显示的图片

 <picture>
  <source media="(min-width: 650px)" srcset="img1.jpg">
  <source media="(min-width: 465px)" srcset="img2.jpg">
  <img src="img3.jpg" alt="a cute kitten">
</picture>

6.svg 放大或改变尺寸的情况下其图形质量不会有损失