Hello.

I am Paul Kinlan.

A Developer Advocate for Chrome and the Open Web at Google.

Grep your git commit log

Paul Kinlan

Finding code that was changed in a commit

Read More

Paul Kinlan

Trying to make the web and developers better.

RSS Github Medium

Performance and Resilience: Stress-Testing Third Parties by CSS Wizardry

Paul Kinlan

Я был в Китае пару недель назад в День разработчиков Google, и я показывал всех своим QRCode scanner, он отлично работал, пока я не вышел в автономный режим. Когда пользователь был в автономном режиме (или частично подключен), камера не запустилась, а это означало, что вы не можете привязать QR-коды. Мне потребовался возраст, чтобы понять, что происходит, и оказалось, что я ошибочно начал работу с камерой в своем «onload» событии, и запрос Google Analytics зависает и не разрешается своевременно. Это это фиксация, которая зафиксировала это.

Because these types of assets block rendering, the browser will not paint anything to the screen until they have been downloaded (and executed/parsed). If the service that provides the file is offline, then that’s a lot of time that the browser has to spend trying to access the file, and during that period the user is left potentially looking at a blank screen. After a certain period has elapsed, the browser will eventually timeout and display the page without the asset(s) in question. How long is that certain period of time?

It’s 1 minute and 20 seconds.

If you have any render-blocking, critical, third party assets hosted on an external domain, you run the risk of showing users a blank page for 1.3 minutes.

Below, you’ll see the DOMContentLoaded and Load events on a site that has a render-blocking script hosted elsewhere. The browser was completely held up for 78 seconds, showing nothing at all until it ended up timing out.

Читать полностью.

Я рекомендую вам прочитать сообщение, потому что есть много замечательного понимания.

Chrome Bug 897727 - MediaRecorder using Canvas.captureStream() fails for large canvas elements on Android

Paul Kinlan

В выходные я играл с видео кодеком эффектов Boomerang, вы можете получить его работу в режиме реального времени (я объясню позже). Я работал над Chrome на рабочем столе, но он никогда не будет работать должным образом в Chrome на Android. См. Код здесь.

Похоже, когда вы используете captureStream () на <canvas>, который имеет относительно большое разрешение (1280x720 в моем случае), MediaRecorder API не сможет кодировать видео, и это не будет ошибкой, и вы не можете обнаружить, что он не может кодировать видео раньше времени.

(1) Capture a large res video (from getUM 1280x720) to a buffer for later processing. (2) Create a MediaRecorder with a stream from a canvas element (via captureStream) sized to 1280x720 (3) For each frame captured putImageData on the canvas (4) For each frame call canvasTrack.requestFrame() at 60fps

context.putImageData(frame, 0, 0); canvasStreamTrack.requestFrame();

Demo: https://boomerang-video-chrome-on-android-bug.glitch.me/ Code: https://glitch.com/edit/#!/boomerang-video-chrome-on-android-bug?path=script.js:21:42

What is the expected result?

For the exact demo, I buffer the frames and then reverse them so you would see the video play forwards and backwards (it works on desktop). In generall I would expect all frames sent to the canvas to be processed by the MediaRecorder API - yet they are not.

What happens instead?

It only captures the stream from the canvas for a partial part of the video and then stops. It’s not predicatable where it will stop.

I suspect there is a limit with the MediaRecorder API and what resolution it can encode depending on the device, and there is no way to know about these limits ahead of time.

As far as I can tell this has never worked on Android. If you use https://boomerang-video-chrome-on-android-bug.glitch.me which has a 640x480 video frame it records just fine. The demo works at higher-resolution just fine on desktop.

Читать полностью.

Если вы хотите поиграть с демоверсией, которая работает на обоих, то нажмите здесь

Why Microsoft and Google love progressive web apps | Computerworld

Paul Kinlan

Хорошая статья о PWA из Mike Elgan. Я не уверен в цели Microsoft с PWA, но я думаю, что наша задача довольно проста: мы хотим, чтобы пользователи мгновенно получали доступ к контенту и функциям и таким образом, как они ожидают, что смогут взаимодействовать с ним на своих устройствах. Интернет должен охватывать всех через каждое подключенное устройство, и пользователь должен иметь доступ к их предпочтительной форме, в качестве приложения, если это так, как они ожидают (мобильный, может быть), или голос на помощнике и т. Д.

Мы все еще длинный путь от безголовой паутины, однако, одна вещь действительно поразила меня в статье:

Another downside is that PWAs are highly isolated. So it’s hard and unlikely for different PWAs to share resources or data directly.

Читать полностью.

Сайты и приложения в Интернете не должны быть изолированы, веб - linkable, indexable, ephemeral, но мы становимся более сильными с каждым созданным нами сайтом. Мы создаем непредвиденные силосы, потому что платформа не позволяет пользователям легко * легко и быстро удалять * свои данные. Я не говорю о RDF или что-то в этом роде, основные операции, такие как копирование и вставка, перетаскивание, совместное использование на сайте и совместное использование с сайта, нарушены в Интернете сегодня, и до этого мы добираемся до IPC между кадрами, работниками и окна.

Building a video editor on the web. Part 0.1 - Screencast

Paul Kinlan

Вы должны иметь возможность создавать и редактировать видео, используя только веб-браузер. Должно быть возможно предоставить пользовательский интерфейс, похожий на Screenflow, который позволяет создавать выходное видео, которое объединяет несколько видео, изображений и аудио в одно видео, которое может быть загружено на такие сервисы, как YouTube. Следуя моему предыдущему сообщению, который кратко описывает требования видеоредактора, в этом посте я просто хотел быстро показать в скринкасте, как я построил рекордер для веб-камеры, а также как создать скринкаст рекордер :)

Read More

894556 - Multiple video tracks in a MediaStream are not reflected on the videoTracks object on the video element

Paul Kinlan

Первая проблема, которую я нашел, пытается создать видеоредактор в Интернете (0).

У меня есть несколько видеопотоков (рабочий стол и веб-камера), и я хотел иметь возможность переключаться между видеопотоками на один элемент видео, чтобы я мог быстро переключаться между веб-камерой и рабочим столом, а не прерывать «MediaRecorder».

Похоже, вы должны сделать это, переключив свойство selected на объектvideoTracks на <video>, но вы не можете, массив треков содержит только 1 элемент (первый видео трек на MediaStream).

What steps will reproduce the problem? (1) Get two MediaStreams with video tracks (2) Add them to a new MediaStream and attach as srcObject on a videoElement (3) Check the videoElement.videoTracks object and see there is only one track

Demo at https://multiple-tracks-bug.glitch.me/

What is the expected result? I would expect videoElement.videoTracks to have two elements.

What happens instead? It only has the first videoTrack that was added to the MediaStream.

Читать полностью.

Repro.

window.onload = () => {
  if('getDisplayMedia' in navigator) warning.style.display = 'none';

  let blobs;
  let blob;
  let rec;
  let stream;
  let webcamStream;
  let desktopStream;

  captureBtn.onclick = async () => {

       
    desktopStream = await navigator.getDisplayMedia({video:true});
    webcamStream = await navigator.mediaDevices.getUserMedia({video: { height: 1080, width: 1920 }, audio: true});
    
    // Always 
    let tracks = [...desktopStream.getTracks(), ... webcamStream.getTracks()]
    console.log('Tracks to add to stream', tracks);
    stream = new MediaStream(tracks);
    
    console.log('Tracks on stream', stream.getTracks());
    
    videoElement.srcObject = stream;
    
    console.log('Tracks on video element that has stream', videoElement.videoTracks)
    
    // I would expect the length to be 2 and not 1
  };

};

Building a video editor on the web. Part 0.

Paul Kinlan

Вы должны иметь возможность создавать и редактировать видео, используя только веб-браузер. Должно быть возможно предоставить пользовательский интерфейс, похожий на Screenflow, который позволяет создавать выходное видео, которое объединяет несколько видео, изображений и аудио в одно видео, которое может быть загружено на такие сервисы, как YouTube. Этот пост - это просто заявление о намерениях. Я собираюсь начать долгий процесс разработки того, что есть и недоступно на платформе, и посмотреть, как далеко мы можем сегодня добраться.

Read More

Barcode detection in a Web Worker using Comlink

Paul Kinlan

Я большой поклонник QRCodes, они очень простой и опрятный способ обмена данными между реальным миром и цифровым миром. В течение нескольких лет у меня был небольшой побочный проект под названием QRSnapper & mdash; ну, у него было несколько имен, но это тот, который я поселил в & mdash; который использует API getUserMedia для получения живых данных с камеры пользователя, чтобы он мог сканировать QR-коды в ближайшем реальном времени.

Целью приложения было поддерживать 60 кадров в секунду в пользовательском интерфейсе и почти мгновенное обнаружение QR-кода, это означало, что мне пришлось ввести код обнаружения в веб-рабочего (довольно стандартный материал). В этом посте я просто хотел быстро поделиться тем, как я использовал комлинк, чтобы значительно упростить логику в Рабочем.

qrclient.js

import * as Comlink from './comlink.js';

const proxy = Comlink.proxy(new Worker('/scripts/qrworker.js')); 

export const decode = async function (context) {
  try {
    let canvas = context.canvas;
    let width = canvas.width;
    let height = canvas.height;
    let imageData = context.getImageData(0, 0, width, height);
    return await proxy.detectUrl(width, height, imageData);
  } catch (err) {
    console.log(err);
  }
};

qrworker.js (веб-работник)

import * as Comlink from './comlink.js';
import {qrcode} from './qrcode.js';

// Use the native API's
let nativeDetector = async (width, height, imageData) => {
  try {
    let barcodeDetector = new BarcodeDetector();
    let barcodes = await barcodeDetector.detect(imageData);
    // return the first barcode.
    if (barcodes.length > 0) {
      return barcodes[0].rawValue;
    }
  } catch(err) {
    detector = workerDetector;
  }
};

// Use the polyfil
let workerDetector = async (width, height, imageData) => {
  try {
    return qrcode.decode(width, height, imageData);
  } catch (err) {
    // the library throws an excpetion when there are no qrcodes.
    return;
  }
}

let detectUrl = async (width, height, imageData) => {
  return detector(width, height, imageData);
};

let detector = ('BarcodeDetector' in self) ? nativeDetector : workerDetector;
// Expose the API to the client pages.
Comlink.expose({detectUrl}, self);

Мне очень нравится Comlink, я думаю, что это игровой чейнджер библиотеки, особенно когда речь заходит о создании идиоматического JavaScript, который работает по потокам. В конце концов, здесь стоит упомянуть, что встроенный API обнаружения штрих-кода можно запустить внутри рабочего, так что вся логика инкапсулирована в сторону от пользовательского интерфейса.

Читать полностью.

Running FFMPEG with WASM in a Web Worker

Paul Kinlan

Я люблю FFMPEG.js, это аккуратный инструмент, который скомпилирован с помощью asm.js`and, и пусть он будет создавать JS-приложения, которые могут быстро редактировать видео. FFMPEG.js также работает с веб-рабочими, чтобы вы могли кодировать видео без блокировки основного потока.

Я также люблю Comlink. Comlink позволяет мне легко взаимодействовать с веб-рабочими, выставляя функции и классы, не имея дело с сложным конечным автоматом postMessage.

Недавно мне удалось объединить этих двух. Я экспериментировал с тем, чтобы экспортировать FFMPEG в Web Assembly (он работает - yay), и я хотел очистить всю работу postMessage в текущем проекте FFMPEG.js. Ниже приведен код, который теперь выглядит - я думаю, что это довольно аккуратно. У нас есть один рабочий, который импортирует ffmpeg.js и comlink, и он просто предоставляет интерфейс ffmpeg, а затем у нас есть веб-страница, которая загружает рабочего, а затем использует комлинк для создания прокси-сервера API ffmpeg.

Ухоженная.

worker.js

importScripts('https://cdn.jsdelivr.net/npm/comlinkjs@3.0.2/umd/comlink.js');
importScripts('../ffmpeg-webm.js'); 
Comlink.expose(ffmpegjs, self);

client.html

let ffmpegjs = await Comlink.proxy(worker);
let result = await ffmpegjs({
   arguments: ['-y','-i', file.name, 'output.webm'],
   MEMFS: [{name: file.name, data: data}],
   stdin: Comlink.proxyValue(() => {}),
   onfilesready: Comlink.proxyValue((e) => {
     let data = e.MEMFS[0].data;
     output.src = URL.createObjectURL(new Blob([data]))
     console.log('ready', e)
   }),
   print: Comlink.proxyValue(function(data) { console.log(data); stdout += data + "\n"; }),
   printErr: Comlink.proxyValue(function(data) { console.log('error', data); stderr += data + "\n"; }),
   postRun: Comlink.proxyValue(function(result) { console.log('DONE', result); }),
   onExit: Comlink.proxyValue(function(code) {
     console.log("Process exited with code " + code);
     console.log(stdout);
   }),
});

Мне очень нравится, как компилируемые модули Comlink, Workers и WASM могут играть вместе. Я получаю идиоматический JavaScript, который напрямую взаимодействует с модулем WASM, и он отключается от основного потока.

Читать полностью.

Translating a blog using Google Cloud Translate and Hugo

Paul Kinlan

Недавно я вернулся из поездки в Индию для участия в мероприятии Google4India (вскоре сообщается) и встретиться с большим количеством компаний и разработчиков. Одной из наиболее интересных изменений стало стремление к большему количеству контента на языке пользователей в стране, и это было особенно очевидно во всех продуктах Google, которые варьировались от упрощения поиска на языке пользователей, поиска контента, а также прочитать его пользователям в текстовой или речевой форме.

Вся поездка заставила меня задуматься. Мой блог построен с Хьюго. Hugo теперь поддерживает контент в письменной форме на нескольких языках. Hugo полностью статичен, поэтому создание нового контента - это вопрос только создания нового файла и создания системы сборки. Поэтому, возможно, я смогу создать что-то, что сделает мой контент более доступным для большего количества людей, запустив мой статический контент с помощью инструмента перевода, потому что человеческий перевод содержимого очень дорог.

За пару часов до моего полета обратно в Великобританию я создал небольшой скрипт, который будет брать мои файлы с разметкой и запускать их через Google Cloud Translate, чтобы создать быстрый перевод страницы, которую я могу быстро разместить. Полное решение представлено ниже. Это относительно базовый процессор, он игнорирует преамбулу Хьюго, он игнорирует «код», и он игнорирует кавычки тяги - мое предположение заключалось в том, что они всегда должны быть оставлены так, как они были написаны.

Примечание. Похоже, наше учебное программное обеспечение для переводов используется, поэтому важно пометить свою страницу, чтобы учебные инструменты не использовали контент Google Translated в качестве входных данных для его алгоритмов.

// Imports the Google Cloud client library
const Translate = require('@google-cloud/translate');
const program = require('commander');
const fs = require('fs');
const path = require('path');

program
  .version('0.1.0')
  .option('-s, --source [path]', 'Add in the source file.')
  .option('-t, --target [lang]', 'Add target language.')
  .parse(process.argv);

// Creates a client
const translate = new Translate({
  projectId: 'html5rocks-hrd'
});

const options = {
  to:  program.target,
};

async function translateLines(text) {
  if(text === ' ') return ' ';
  const output = [];
  let results = await translate.translate(text, options);

  let translations = results[0];
  translations = Array.isArray(translations)
    ? translations
    : [translations];

  translations.forEach((translation, i) => {
    output.push(translation)
  });

  return output.join('\n');
};

// Translates the text into the target language. "text" can be a string for
// translating a single piece of text, or an array of strings for translating
// multiple texts.
(async function (filePath, target) {

  const text = fs.readFileSync(filePath, 'utf8');

  const lines = text.split('\n');
  let translateBlock = [];
  const output = [];

  let inHeader = false;
  let inCode = false;
  let inQuote = false;
  for (const line of lines) {
    // Don't translate preampble
    if (line.startsWith('---') && inHeader) { inHeader = false; output.push(line); continue; }
    if (line.startsWith('---')) { inHeader = true; output.push(line); continue; }
    if (inHeader) { output.push(line); continue; }

    // Don't translate code
    if (line.startsWith('```') && inCode) { inCode = false; output.push(line); continue; }
    if (line.startsWith('```')) { inCode = true; output.push(await translateLines(translateBlock.join(' '))); translateBlock = []; output.push(line); continue; }
    if (inCode) { output.push(line); continue; }

    // Dont translate quotes
    if (inQuote && line.startsWith('>') === false) { inQuote = false; }
    if (line.startsWith('>')) { inQuote = true; output.push(await translateLines(translateBlock.join(' '))); translateBlock = []; output.push(line); }
    if (inQuote) { output.push(line); continue; }

    if (line.charAt(0) === '\n' || line.length === 0) { output.push(await translateLines(translateBlock.join(' '))); output.push(line); translateBlock = []; continue;} 

    translateBlock.push(line);
  }

  if(translateBlock.length > 0) output.push(await translateLines(translateBlock.join(' ')))

  const result = output.join('\n');
  const newFileName = path.parse(filePath);
  fs.writeFileSync(`content/${newFileName.name}.${target}${newFileName.ext}`, result);

})(program.source, program.target);

В целом, я очень доволен процессом. Я понимаю, что машинный перевод не идеален, но я думаю, что я могу увеличить доступ к моему контенту людям, которые могут искать их на своих языках, а не на английском. Я могу увеличить площадь поверхности моего контента и, надеюсь, поможет больше люди.

Понадобится некоторое время, чтобы узнать, действительно ли это помогает людям, поэтому я буду отчитываться, когда у меня будет больше данных … Теперь, чтобы запустить мой скрипт на более моем сайте :)

Apple - Web apps - All Categories

Paul Kinlan

Помните, когда веб-приложения были * рекомендованным способом использования приложений на iPhone?

What are web apps? Learn what they are and how to use them.

Читать полное сообщение.

Примерно в 2013 году Apple начала перенаправлять каталог / webapps / top-level в / iphone /

Дело в том, что каталог действительно хорош, многие приложения в нем все еще работают сегодня. Однако, глядя на AppStore, он решил намного больше проблем, которые были у разработчиков: Лучшее обнаружение и поиск именно потому, что AppStore был непосредственно на устройстве. AppStore также начал вводить это устранение трений со стороны пользователей и разработчиков, особенно в отношении платежей.

Gears API

Paul Kinlan

Я пишу сообщение в блоге о ранних API для мобильных веб-сайтов, и Алекс Рассел напомнил мне о Google Gears

Gears modules include:

  • LocalServer Cache and serve application resources (HTML, JavaScript, images, etc.) locally
  • Database Store data locally in a fully-searchable relational database
  • WorkerPool Make your web applications more responsive by performing resource-intensive operations asynchronously

Читать полное сообщение.

Я думаю, что интересно видеть, что AppCache и WebSQL, Geolocation и WebWorkers вышли из идей в Google Gears, и только последние два из них действительно выжили. WebSQL никогда не поддерживался широко, и его заменил IndexedDB; и AppCache заменен ServiceWorker

RSS Feed to Google Chat Webhook using Cloud Functions for Firebase and Superfeedr

Paul Kinlan

Мы часто используем Google Chat для общения через нашу команду - это похоже на нашу слабость; Мы также создаем много контента, доступного через RSS-каналы, у нас даже есть [команда, которую вы можете просмотреть) (http://devwebfeed.appspot.com). До недавнего времени я узнал, что создать простой простой почтовый бот через WebHooks довольно легко. дал мне идею, я могу создать простой сервис, который опросает RSS-каналы, а затем отправляет их на наш веб-сайт, который может отправлять сообщения прямо в наш командный чат.

В конце концов это было довольно просто, и я включил весь код ниже. Я использовал функции Firebase - я подозреваю, что это так же просто на других сайтах Function-as-a-service - и Superfeedr. Superfeedr - это служба, которая может прослушивать Pubsubhubbub pings (теперь WebSub), а также будет опробовать RSS-каналы, которые не имеют настройки Pubsub. Затем, когда он найдет фид, он проверит настроенный URL (в моем случае мою Облачную функцию в Firebase) с представлением XML или JSON только что найденных данных фида - все, что вам нужно сделать, это проанализировать данные и сделать с ними что-то.

const functions = require('firebase-functions');
const express = require('express');
const cors = require('cors');
const fetch = require('node-fetch');
const app = express();

// Automatically allow cross-origin requests
app.use(cors({ origin: true }));

app.post('/', (req, res) => {
  const { webhook_url } = req.query;
  const { body } = req;
  if (body.items === undefined || body.items.length === 0) {
    res.send('');
    return;
  }

  const item = body.items[0];
  const actor = (item.actor && item.actor.displayName) ? item.actor.displayName : body.title;

  fetch(webhook_url, {
    method: 'POST',
    headers: {
      "Content-Type": "application/json; charset=utf-8",
    },
    body: JSON.stringify({
      "text": `*${actor}* published <${item.permalinkUrl}|${item.title}>. Please consider <https://twitter.com/intent/tweet?url=${encodeURIComponent(body.items[0].permalinkUrl)}&text=${encodeURIComponent(body.items[0].title)}|Sharing it>.`
    })  
  }).then(() => {
    return res.send('ok');
  }).catch(() => {
    return res.send('error')
  });
})
// Expose Express API as a single Cloud Function:
exports.publish = functions.https.onRequest(app);

Читать полный пост.

Я был удивлен и рад тому, как легко было настроить его.

Using HTTPArchive and Chrome UX report to get Lighthouse score for top visited sites in India.

Paul Kinlan

A quick dive in to how to use Lighthouse,HTTPArchive and Chrome UX report to try and understand how users in a country might experience the web.

Read More

Getting Lighthouse scores from HTTPArchive for sites in India.

Paul Kinlan

A quick dive in to how to use Lighthouse to try and understand how users in a country might experience the web.

Read More

'Moving to a Chromebook' by Rumyra's Blog

Paul Kinlan

Рут Джон перешла на Chrome OS (временно):

The first thing, and possibly the thing with the least amount of up to date information out there, was enabling Crostini. This runs Linux in a container on the Chromebook, something you pretty much want straight away after spending 15 minutes on it.

I have the most recent Pixel, the 256GB version. Here’s what you do.

  • Go to settings.
  • Click on the hamburger menu (top left) - right at the bottom it says ‘About Chrome OS’
  • Open this and there’s an option to put your machine into dev mode
  • It’ll restart and you’ll be in dev mode - this is much like running Canary over Chrome and possibly turning on a couple of flags. It may crash, but what the hell you’ll have Linux capabilities ��
  • Now you can go back into Settings and in regular settings there’s a ‘Linux apps’ option. Turn this on. It’ll install Linux. Once this is complete you’ll have a terminal open for you. Perfect

Читать полностью.

У Рут есть отличная запись о переходе на Chrome OS, потому что ее главная машина сломалась.

4 месяца назад я перешел на Chrome OS (до ввода / вывода Google) и перешел на Mac, потому что я сломал свой PixelBook (теперь исправленный).

Для меня сегодня это одна из лучших машин для веб-разработки. Это единственное устройство, на котором я могу проверить «настоящую мобильную связь» - вы можете установить Chrome на Mobile на нем, Firefox Mobile, Samsung Browser, Brave и т. Д. Через платформу ARC. Crostini также является игровым чейнджером для Chrome OS, поскольку он привносит большую часть экосистемы приложений Linux в Chrome OS, и он действительно начинает заполнять огромную область приложений для меня в Chrome OS; У меня есть Firefox, vim, git, VS Code, Node, npm, все мои инструменты сборки, GIMP и Inkscape … Это не значит, что это было прекрасно, Crostini может быть быстрее, это еще не ускорило GPU, и это могло бы быть более интегрированным с Filemanager и т. д., и, наконец, PixelBook действительно нуждается в большем количестве физических портов - я могу подключить к нему два экрана 4k, но я не могу одновременно заряжать.

Я думаю, что обтекание Рут также довольно точно, PixelBook - дорогая машина, но я очень рад видеть, как это приходит на все больше и больше устройств (особенно на гораздо более низких ценах).

Would I pay full price for it? I’m not sure I would pay full price for anything on the market right now. Point me in the direction of a system that will run my graphics software and makes a good dev machine (with minimal setup) and lasts more than 18 months, point me in the direction of a worthy investment and I will pay the money.

Ага.

PWA: Progressive Web All-the-things

Paul Kinlan

Ведомство общественных работ Прогрессивные веб-приложения. Фрэнсис Берриман и Алекс Рассел придумали термин «прогрессивные веб-приложения» в 2015 году с тем, что, по моему мнению, является серьезным сообщением «Прогрессивные веб-приложения: экранирование вкладок без потери нашей души». 3 года спустя, мы прошли долгий путь. Из свободной коллекции технологий - Service Worker, Manifest, Add to Homescreen, Web Push, которые первоначально были реализованы только в одном браузере, бренду, который начал сталкиваться с отраслью с предприятиями и разработчиками, и все основные поставщиков браузеров, реализующих большую часть стека PWA.

Read More

What are the pain points for web designers? - Mustafa Kurtuldu

Paul Kinlan

Мустафа пишет:

Tooling is complicated, we are a tooling focused industry, and they change so much. I have used maybe rough eight different tools, from Photoshop to Sketch. That’s before we add prototyping tools to the mix. This may be something we just have to accept. After all, type standards only really started to settle in the 90s, and typography is a 500-year-old discipline.

Designers are still finding it difficult to prove the importance of the process. I think this is something that we have to take on board: to learn how to educate and not just expect everyone to trust us by default. That takes time — perhaps using scenario-based design or design workshops like a design sprint would help. Getting non-designers to observe users while using a prototype they created is one of the best experiences I have seen in this field.

Cross-browser support is lacking crucial features. Designers need to understand developer tooling, to better scope out what is possible. I think using paired programming or the design process described above can help.

Responsive design is still challenging. I think this is in part due to the tools we use; I would love Chrome Design Tools that would help turn the browser into a creative tool. This space is where I think the next evolutionary step for site and web app creation is at. Mozilla is doing some fantastic work in this space, with their layout and shapes tooling.

All in all the challenges that we face seem to be all the age-old ones. Process, tools, and respect.

Читать полностью.

Я нашел это очень интересное сообщение, которое также является дополнением к сообщению, которое я написал о проблемах для веб-разработчиков. Неудивительно, что совместимость браузеров является проблемой, но проблема по-прежнему вызывает беспокойство в том, что создание IE11 по-прежнему является тем, что удерживает отрасль. Аналогичным образом, Мустафа указывает, что по-прежнему существует проблема с инструментами вокруг адаптивного дизайна, и акцент на единственном отзывчивом решении всегда приводит к следующему (то есть в сообщении Мустафы):

Designing once and using everywhere is still hard to reach ambition.

Это проблема, с которой, я думаю, мы все еще боремся. С одной стороны, мы хотим, чтобы все создавали гибкое решение, которое может обслуживать каждого на каждом форм-факторе устройства, с другой стороны, контекст пользователя важен, и часто пользователь будет только желать выполнить определенные действия в определенное время; мы очень много видим в индустрии розничной торговли и коммерции: люди будут просматривать на мобильных устройствах и заполнять их на рабочем столе, и тогда возникает вопрос: вы больше всего используете эту мультимодальную модель или создаете последовательный опыт на всех устройствах … I подозревают, что ответ «это зависит», но в любом случае это трудная проблема для каждого из групп продуктов инженерам.

Page Lifecycle API - Philip Walton

Paul Kinlan

Филип Уолтон обладает огромным погружением в новый API, над которым работала команда Chrome, чтобы дать вам (разработчику) контроль за тем, как реагировать, когда браузер выгружает ваши вкладки.

Application lifecycle is a key way that modern operating systems manage resources. On Android, iOS, and recent Windows versions, apps can be started and stopped at any time by the OS. This allows these platforms to streamline and reallocate resources where they best benefit the user.

On the web, there has historically been no such lifecycle, and apps can be kept alive indefinitely. With large numbers of web pages running, critical system resources such as memory, CPU, battery, and network can be oversubscribed, leading to a bad end-user experience.

While the web platform has long had events that related to lifecycle states — like load, unload, and visibilitychange — these events only allow developers to respond to user-initiated lifecycle state changes. For the web to work reliably on low-powered devices (and be more resource conscious in general on all platforms) browsers need a way to proactively reclaim and re-allocate system resources.

In fact, browsers today already do take active measures to conserve resources for pages in background tabs, and many browsers (especially Chrome) would like to do a lot more of this — to lessen their overall resource footprint.

The problem is developers currently have no way to prepare for these types of system-initiated interventions or even know that they’re happening. This means browsers need to be conservative or risk breaking web pages.

The Page Lifecycle API attempts to solve this problem by:

  • Introducing and standardizing the concept of lifecycle states on the web.
  • Defining new, system-initiated states that allow browsers to limit the resources that can be consumed by hidden or inactive tabs.
  • Creating new APIs and events that allow web developers to respond to transitions to and from these new system-initiated states.
  • This solution provides the predictability web developers need to build applications resilient to system interventions, and it allows browsers to more aggressively optimize system resources, ultimately benefiting all web users.

The rest of this post will introduce the new Page Lifecycle features shipping in Chrome 68 and explore how they relate to all the existing web platform states and events. It will also give recommendations and best-practices for the types of work developers should (and should not) be doing in each state.

Читать полный пост.

Мой первый комментарий: вы должны прочитать сообщение Philips. Это невероятно.

На мобильном телефоне Chrome может быть довольно агрессивным при фоновой (замораживании или отбрасывании) странице, чтобы сохранить ресурсы, когда пользователь не использует ее (например, когда вы меняете вкладки или переходите из приложения Chrome на Android), когда браузер обращается к вашим как разработчик, которого вы традиционно не знаете о том, когда это происходит, поэтому вы не можете легко сохранить состояние или даже закрыть открытые ресурсы, и так же важно, когда вы используете приложение, чтобы восстановить чистоту состояния. Когда разработчики имеют контроль, они могут делать более осознанный выбор, что также означает, что браузер может быть более агрессивным в сохранении ресурсов в будущем без серьезного влияния на опыт пользователей или разработчиков.

Наконец, приведенная ниже диаграмма объясняет, что все это хорошо подходит.

API Lifecycle API

Add to homescreen changes in Chrome 68 - Pete LePage

Paul Kinlan

Pete LePage пишет о важных изменениях в Add to Homescreen в Chrome

Add to Home Screen changes

If your site meets the add to home screen criteria, Chrome will no longer show the add to home screen banner. Instead, you’re in control over when and how to prompt the user.

To prompt the user, listen for the beforeinstallprompt event, then, save the event and add a button or other UI element to your app to indicate it can be installed.

Читать полный пост.

У меня были смешанные чувства по этому поводу изначально, потому что так много людей не справились с событием beforeinstallprompt, это означало, что внезапно количество установок Web APK упадет довольно значительно, но я думаю, что это действительно правильно.

Цель состоит в том, чтобы уменьшить количество раздражающих подсказок, происходящих в Интернете, и последнее, что нам нужно в отрасли, - это относительно большая подсказка, когда мы думаем, что пользователь может захотеть установить PWA, вместо этого вам теперь нужно подумайте о том, где и когда ** вы ** хотите запросить установку, и вы должны сделать это в ответ на жест пользователя.

Самое главное, что мы (Chrome) внедряем более привычные способы дать пользователю возможность узнать, что опыт может быть установлен, прямо сейчас это небольшая нижняя панель, которая появляется при первой загрузке, и, надеюсь, в будущем мы сможем исследовать более тонкие способы дать пользователю понять, что они могут принять меры.